Saturday, June 30, 2012

Apache 2 Reverse Proxy Howto: Protect and redirect your internal web services with Apache 2 acting as a Reverse Proxy

Apache 2 Reverse Proxy Howto: Use Apache Web server acting as a reverse proxy to protect and redirect your internal Web services




The Goal:


For various situations, you may need to use a reverse proxy to protect or redirect your internal web services, this can done really easily with an Apache server!

For example, you have a home server and don't want to open directly outside connections to your server, you can use an third party to host theses Web services. (as for an example using a virtual host inside your own host)

You may also need this kind of configuration if your home server uses any VPN connection that redirect any outgoing traffic to the tunnel. (typical case and normal situation with any VPN public provide)


Let's resume some benefits:

  • Improves your Web services security with a third party server
  • Secure your Web services on third party server even if running non SSL on real server
  • Easily secure with SSL an embedded or non standard Web Service
  • Consolidates your Web services ports on third party server (example: a logical range on your proxy and any port on your real server)
  • Provides an answer to host Web services when you use a VPN provider that redirects all traffic to the tunnel

What you need:


  • A server hosting your web services (Any OS)
  • A third party: A another physical server or just a virtual host on your server
If you want to host a virtual machine on your server (Virtual-box, Vmware...), i recommend to choose a minimalist Linux distribution and server oriented, such as Debian or Ubuntu server.
You won't need any desktop interface, so just a minimalist and low resource consuming OS, Ubuntu server will be perfect.


Step 1: Configure your network and Third party server that will act as a reverse proxy

  • If you choose a virtual host, ensure to configure the Network interface using bridge mode, it will act as  a totally independent network interface as if it would be a real physical one
  • Configure your local router or firewall to open and redirect TCP ports to your Third party server (and not your real server)
Example of configuration:
  • Let's your server has following Web services : 80 (http), 443(https), 10190 (http)
  • And Your third party server (eg. Reverse proxy) will host: 10000(http), 10001(https), 10002 (htttps)
  • On your Router/Home Firewall/ISP Box, redirect all external traffic TCP ports 10000, 10001, 10002 to your Physical or Virtual Host acting as the Reverse Proxy

Step 2: Install Apache 2 and configure

  • Install Apache 2, openssl and requirements:
Install Apache 2 on Debian and derived systems:
sudo apt-get install apache2 openssl
Activate required Apache modules:
sudo a2enmod proxy proxy_http proxy_connect ssl
Deactivate defaults http and https sites (we don't need it and don't want it):
sudo a2dissite default
Configure Apache to listen to required ports:
edit "/etc/apache2/ports.conf" as follows:
NameVirtualHost *:10000
Listen 10000

NameVirtualHost *:10001
Listen 10001

NameVirtualHost *:10002
Listen 10002


Step 3: Configure your auto signed SSL certificate

Create your auto signed certificate to encrypt and secure Web traffic with SSL (use whatever you want when asked by openssl) :

sudo openssl req -x509 -nodes -days 3650 -newkey rsa:1024 -out /etc/apache2/server.crt -keyout /etc/apache2/server.key

Step 4: Configure an "htpassword" file for simple authentication (at least recommended)

generate an .htpasswd file to protect your site by authentication (adapt your username) :
NB:

  • "-c" option will create a new file
  • "-m" option will use MD5 to secure password, by default htpasswd uses DES which will only consider first 8 characters 
sudo htpasswd -c -m /etc/apache2/.htpasswd username

Step 5: Configure and enable your Reverse proxy instances

Create your first reverse proxy site:
create a new file "/etc/apache2/sites-available/instance1_port10000 (adapt to your needs):
<VirtualHost *:10000>
  ServerName XXXXXXXXXXX
  ProxyRequests Off
  ProxyVia Off
    <Proxy *>
     Order deny,allow
     Allow from all
    </Proxy>
  ProxyPass / http://MY PHYSICAL HOST:PORT
  ProxyPassReverse / http://MY PHYSICAL HOST:PORT
  <Location />
    Order allow,deny
    Allow from all
    AuthName "Access Restricted"
    AuthType Basic
    AuthUserFile "/etc/apache2/.htpasswd"
    Require valid-user
  </Location>
  LogLevel info
  CustomLog /var/log/apache2/access_XXXXXXX.log combined
  ErrorLog /var/log/apache2/error_XXXXXXX.log
  SSLEngine on
  SSLCertificateFile /etc/apache2/server.crt
  SSLCertificateKeyFile /etc/apache2/server.key
</VirtualHost>

Enable the site:
sudo a2ensite instance1_port10000

Restart Apache:
sudo service apache2 restart (or "sudo apachectl restart" if you prefer)
Test your site by accessing https://<reverse_proxy_ip>:<instance_port>

You will be able to access with the same URL from both inside and outside locations without having to open direct connection from outside to your real server :-)

This is off course a real simple example you may easily use for your Home server, reverses proxy are very often used in Enterprise with others security mechanisms.

The purpose here is to provide a simple way to improve home Web services security and consolidate.
















3 comments:

  1. Hello, could you elaborate more precisely the step 5 (simulation of a real config) and give us the following steps for the virtualhost 10001 and 10002? I would like to spread beyond my internet box a mail server and server remote console ajaxterm, from the external to my rapsberry so secure as you've described. thank you in advance! olivier-network@live.fr
    (ps: I ask for these details as because I am having trouble configuring apache2, I always find tutorials with example generic, not applicable)

    ReplyDelete
    Replies
    1. *from my local rapsberry to the net beyond my internet box

      Delete
    2. Hi,

      See my new post:
      http://youresuchageek.blogspot.fr/2013/01/rpi-nginx-shellinabox.html

      Cheers

      Delete

Please feel free to comment ^^