Apache reverse proxy
could do with filling out more detail
A reverse proxy allows you to front multiple websites from a single public IP address, act as a load balancer and potentially defuse otherwise dangerous cyber attacks. There are different solutions, the instructions here are for an Apache server-based solution. Basic requirements are Apache, mod_ssl and mod_proxy installed and enabled.
Installation
Install apache2
apt-get install apache2
File /etc/apache2/mods-available/proxy.conf should look like this:
<IfModule mod_proxy.c> # If you want to use apache2 as a forward proxy, uncomment the # 'ProxyRequests On' line and the <Proxy *> block below. # WARNING: Be careful to restrict access inside the <Proxy *> block. # Open proxy servers are dangerous both to your network and to the # Internet at large. # # If you only want to use apache2 as a reverse proxy/gateway in # front of some web application server, you DON'T need # 'ProxyRequests On'. ProxyRequests Off <Proxy *> AddDefaultCharset off Order deny,allow Deny from all </Proxy> # Enable/disable the handling of HTTP/1.1 "Via:" headers. # ("Full" adds the server version; "Block" removes all outgoing Via: headers) # Set to one of: Off | On | Full | Block #ProxyVia Off ProxyVia On ProxyPreserveHost On ProxyRequests Off ProxyTimeout 600 </IfModule>
Create file /etc/apache2/mods-available/proxy_http.conf and put this inside:
ProxyVia On ProxyPreserveHost On ProxyRequests Off <Proxy *> Order deny,allow Allow from all </Proxy>
Enable modules proxy and proxy_http
a2enmod proxy a2enmod proxy_http
And restart apache2
service apache2 restart
Failover proxy
Create a user on failover-proxy with a private key and one on proxy with the public key that would sync the data from proxy to failover-proxy.
On failover-proxy create script /opt/bin/proxy_sync:
#!/bin/bash #apache sync /usr/bin/rsync -rl --safe-links --rsync-path="/usr/bin/sudo /usr/bin/rsync" <user>@<proxy-ip>:/etc/apache2/ /etc/apache2/ 2>&1 >> /var/log/proxy_sync.log #for letsencrypt certs /usr/bin/rsync -rl --safe-links --rsync-path="/usr/bin/sudo /usr/bin/rsync" <user>@<proxy-ip>:/etc/letsencrypt/ /etc/letsencrypt/ 2>&1 >> /var/log/proxy_sync.log /usr/sbin/apache2ctl graceful
Create a cron job for the script /etc/cron.d/proxy_sync:
*/15 * * * * <user> /opt/bin/proxy_sync
Keepalived
Keepalived is used to manage a floating IP.
To setup keepalived, install it on both servers:
sudo apt-get install keepalived
Copy the nagios check "check_http" to /usr/local/bin, from the /usr/lib/nagios/plugins of a server that has nagios-plugins installed (please don't install nagios-plugins on the reverse proxy, that package would install many dependencies).
Finally create the following /etc/keepalived/keepalived.conf on the master:
global_defs { notification_email { <email> } notification_email_from <email> smtp_server 127.0.0.1 } vrrp_script chk_apache { script "/usr/local/bin/check_http -H 127.0.0.1 -e 200" interval 3 # check every 2 seconds weight 2 # add 2 points of prio if OK } vrrp_instance floating_ip { interface eth0 state MASTER virtual_router_id 51 priority 101 authentication { auth_type PASS auth_pass SHAREDPASSWORD } virtual_ipaddress { <select-an-ip> } track_script { chk_apache } }
Create exactly the same file on the failover proxy, just change priority from 101 to 100.
Explanations of the apache check
The track_script "chk_apache" uses nagios' script check_http to ask a webpage to the local apache every three seconds - and checks for a 200 "OK" error code. If the test succeeds, it adds 2 points to the priority of the server.
The server with the highest priority gets the IP address. In effect, we would have the master with a priority of 101+2, and the failover with a priority of 100+2.
If the check fails on the master, its priority goes down to 100, and the IP migrates to the failover, which still has a priority of 100+2.
Adding an entry
In Apache we use vhost declarations to define each reverse proxy FQDN. In Ubuntu/Debian systems these are found in /etc/apache2/sites-available, typically one per vhost using a suitably descriptive name. They can also be wrapped into a single file, or of course into the main apache conf file. As they are effectively (includes) of the Apache conf, every change requires an Apache restart to apply:
apache2ctl restart
In the Debian/Ubuntu model you also need to enable a site one it's been defined, which is done with a link to the /etc/apache2/sites-available/ file newly created:
cd /etc/apache2/sites-enabled ln -s ../sites-available/yournewvhost
This approach allows you to quickly and easily take a specific site offline if there's a problem, just by deleting the link in /etc/apache2/sites-enabled and restarting Apache.
Assuming your sites will be https from the proxy outwards, start with a 301 to force https:
<VirtualHost *:80> ServerName my.domain.name ServerAlias my.alias.domain Redirect 301 / https://my.domain.name ProxyPass / http://my.realserver.nameorIP/ ProxyPassReverse / http://my.realserve.nameorIP/ CustomLog /var/log/apache2/my.domain.name.access.log combined ErrorLog /var/log/apache2/my.domain.name.error.log </VirtualHost>
And then add an SSL entry
<VirtualHost *:443> ServerName my.domain.name SSLEngine on SSLCertificateFile /etc/apache2/ssl/mycertificate.crt SSLCertificateKeyFile /etc/apache2/ssl/mykey.key SSLCertificateChainFile /etc/apache2/ssl/myintermediatecertificateifneeded.crt ProxyPass / http://myrealserver.nameorIP/ ProxyPassReverse / http://my.domain.name/ ProxyPassReverse / http://myrealserver.nameorIP/ CustomLog /var/log/apache2/my.domain.name.access.log combined ErrorLog /var/log/apache2/my.domain.name.error.log </VirtualHost>
If you want the SSL proxy to also connect to the target as SSL, change the ProxyPass URLs appropriately and add to the vhost
SSLProxyEngine On</ssl>