How To Use Apache as a Reverse Proxy with mod_proxy on Ubuntu 16.04
Introduction
A reverse proxy is a type of proxy server that takes HTTP(S) requests and transparently distributes them to one or more backend servers. Reverse proxies are useful because many modern web applications process incoming HTTP requests using backend application servers which aren’t meant to be accessed by users directly and often only support rudimentary HTTP features.
You can use a reverse proxy to prevent these underlying application servers from being directly accessed. They can also be used to distribute the load from incoming requests to several different application servers, increasing performance at scale and providing fail-safeness. They can fill in the gaps with features the application servers don’t offer, such as caching, compression, or SSL encryption too.
Step 1 — Enabling Necessary Apache Modules
Apache has many modules bundled with it that are available but not enabled in a fresh installation. First, we’ll need to enable the ones we’ll use in this tutorial.
The modules we need are mod_proxy
itself and several of its add-on modules, which extend its functionality to support different network protocols. Specifically, we will use:
mod_proxy
, the main proxy module Apache module for redirecting connections; it allows Apache to act as a gateway to the underlying application servers.mod_proxy_http
, which adds support for proxying HTTP connections.mod_proxy_balancer
andmod_lbmethod_byrequests
, which add load balancing features for multiple backend servers.
To enable these four modules, execute the following commands in succession.
1 2 3 4 5 6 7 8 9 10 11 12 |
a2enmod proxy a2enmod proxy_http a2enmod proxy_ajp a2enmod rewrite a2enmod deflate a2enmod headers a2enmod proxy_balancer a2enmod proxy_connect a2enmod proxy_html a2enmod lbmethod_byrequests a2enmod mod_xml2enc a2enmod remoteip |
To put these changes into effect, restart Apache.
1 |
sudo systemctl restart apache2 |
Apache is now ready to act as a reverse proxy for HTTP requests. In the next (optional) step, we will create two very basic backend servers.
Step 2 — Create New Virtual Host Files
This method uses Apache2 virtual host configuration files on the primary server (to which the router sends port 80 traffic).
Create a new virtual host file:
1 |
sudo nano /etc/apache2/sites-available/proxy-host.conf |
Add the following lines to suit your needs:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# <VirtualHost *:80> # ServerName google.com ServerAlias www.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.100.2/ ProxyPassReverse / http://192.168.100.2/ # </VirtualHost> <VirtualHost *:80> # ServerName forum.google.com ServerAlias www.forum.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.100.2/ ProxyPassReverse / http://192.168.100.2/ # </VirtualHost> <VirtualHost *:80> # ServerName blog.google.com ServerAlias www.blog.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.100.3/ ProxyPassReverse / http://192.168.100.3/ # </VirtualHost> <VirtualHost *:80> # ServerName test1.google.com ServerAlias www.test1.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.100.4/ ProxyPassReverse / http://192.168.100.4/ # </VirtualHost> # |
Save and close the file.
Enable new virtual host file:
1 |
sudo a2ensite proxy-host.conf |
When you are finished, you need to restart Apache to make these changes take effect:
1 |
sudo systemctl restart apache2 |
Step 3 — Log Client IP AND X-Forwarded-For IP
When placing apache web servers behind a load-balancing proxy like the BigIP or Pound or behind a caching proxy like Squid or a BlueCoat proxy, the client IP address from the browser is replaced with the IP address of the load-balancer/proxy.
Install mod_remoteip
You can configure your Apache server to log the X-Forwarded-For request header. Configure Apache to log the X-Forwarded-For header by completing the following steps:
- Locate the main Apache configuration file httpd.conf. This file is usually located at
/etc/httpd/conf/httpd.conf
- Edit the configuration file and find the section that contains LogFormat.
- Add the following to your combined LogFormat: “
%{X-Forwarded-For}i
” - Consider the following example code in logformat:
123456SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwardedLogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedLogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" forwardedErrorLog ${APACHE_LOG_DIR}/error.logCustomLog ${APACHE_LOG_DIR}/access.log combined env=!forwardedCustomLog ${APACHE_LOG_DIR}/access.log forwarded env=forwarded
- After making these changes, you must restart the apache2 service:
1sudo systemctl restart apache2
Enable SSL Reverse-Proxy Support
If you want to enable SSL support to your Reverse-Proxy connections, then you will need to enable the SSL module first.
To enable this module, run:
1 |
sudo a2enmod ssl |
After you have enabled SSL, you’ll have to restart the Apache service for the change to be recognized.
1 |
sudo service apache2 restart |
Next, you will need to generate self-signed certificate for Reverse-Proxy Server read this for more info
Generate self-signed certificate on redirect server ( in this example 192.168.100.4)
Copy all certificates file from redirect server to Reverse-Proxy Server
add this config to /etc/apache2/sites-available/proxy-host.conf
file
1 2 3 4 5 6 7 8 |
# SSLEngine on Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/fuhrer-test.tk/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/fuhrer-test.tk/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf # SSLProxyEngine On |
now /etc/apache2/sites-available/proxy-host.conf
file look like this
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# <VirtualHost *:80> # ServerName google.com ServerAlias www.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.1.242/ ProxyPassReverse / http://192.168.1.242/ # # RemoteIPHeader X-Forwarded-For </VirtualHost> <VirtualHost *:80> # ServerName forum.google.com ServerAlias www.forum.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.1.242/ ProxyPassReverse / http://192.168.1.242/ # </VirtualHost> <VirtualHost *:80> # ServerName blog.google.com ServerAlias www.blog.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.1.242/ ProxyPassReverse / http://192.168.1.242/ # </VirtualHost> <VirtualHost *:80> # ServerName kernel.google.com ServerAlias www.kernel.google.com # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.1.242/ ProxyPassReverse / http://192.168.1.242/ # </VirtualHost> # Reverse-Proxy HTTP <VirtualHost *:80> # ServerName fuhrer-test.tk ServerAlias www.fuhrer-test.tk # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.1.197/ ProxyPassReverse / http://192.168.1.197/ # </VirtualHost> # Reverse-Proxy HTTPS <VirtualHost *:443> # ServerName fuhrer-test.tk ServerAlias www.fuhrer-test.tk # SSLEngine on Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/fuhrer-test.tk/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/fuhrer-test.tk/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf # SSLProxyEngine On ProxyPreserveHost On ProxyRequests off ProxyPass / https://192.168.1.197/ ProxyPassReverse / https://192.168.1.197/ # </VirtualHost> # Reverse-Proxy HTTP <VirtualHost *:80> # ServerName web1.fuhrer-test.tk ServerAlias www.web1.fuhrer-test.tk # ProxyPreserveHost On ProxyRequests off ProxyPass / http://192.168.1.197/ ProxyPassReverse / http://192.168.1.197/ # </VirtualHost> # Reverse-Proxy HTTPS <VirtualHost *:443> # ServerName web1.fuhrer-test.tk ServerAlias www.web1.fuhrer-test.tk # SSLEngine on Include /etc/letsencrypt/options-ssl-apache.conf SSLCertificateFile /etc/letsencrypt/live/web1.fuhrer-test.tk/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/web1.fuhrer-test.tk/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf # SSLProxyEngine On ProxyPreserveHost On ProxyRequests off ProxyPass / https://192.168.1.197/ ProxyPassReverse / https://192.168.1.197/ # </VirtualHost> |
To put these changes into effect, restart Apache.
1 |
sudo systemctl restart apache2 |
If certificates file from redirect server change or update, dont forget to copy it to Reverse-Proxy Server
Source:
…