Monthly Archives: June 2015

Nginx as an automatic reverse proxy

Nginx is a nice piece of software, an elegant webserver keeping things simple (although it has given me some headaches). On this case I'll show you how to setup a reverse proxy for any hostname on your internal/external network. A practical use case for this, could be the following
[PC] <-VPN-> [ VPN TERMINATION POINT ]     <-->[HOST A.INTRANET.LOCAL]
                                                                                                               <-->[HOST B.INTRANET.LOCAL]
                                                                                                               <-->[HOST C.INTRANET.LOCAL]
Lets say we are working remotely and had a VPN connection that is able to access a single linux box (VPN termination point), but we need to navigate to other hosts on the internal network i.e: A.INTRANET.LOCAL The solution to this problem is simple, but we need to make some assumptions:
  • The intranet has an internal DNS server capable of resolving INTRANET.LOCAL subdomains.
  • The websites we want to access are all accessible via hostname.
All we need to do is install nginx. On Ubuntu/Debian is as simple as:
$ sudo apt-get install nginx
Then put the following inside the /etc/nginx/sites-enabled/default file:  
server {
listen   80;
server_name  localhost;
access_log  /tmp/nginx.access.log;
 
location / {
resolver 10.47.4.109;
proxy_pass $scheme://$host;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
}
}
  Lets explain the tricky parts a little bit:
  • resolver 10.0.0.2: This is necessary as nginx does not use the standard dns resolution method (a.k.a resolv.conf) so we need to configure a dns server. On this case 10.0.0.2 is the intranet dns server.
  • proxy_pass $scheme://$host: This is simple, it redirects all incoming requests, to the same hosts it was originally intended to. The special variable $scheme contains the protcol (http, https) and the $host variable the hostname.
  • proxy_set_header Host $host: This sets the Host header on the requests, necessary to process a virtualhost directive on any webserver listening on that hostname. proxy_set_header X-Forwarded-For $remote_addr: This attachs the original remote address to the request.
Note: This configuration, as it is, it will work only for websites listening on port 80, you may have to adjust the listen port to accomdate to other requirements.
WARNING:  One has to be very carefull implementing this solution, as the nginx configuration will act as a proxy for *any* host on the internet. You need to make sure that is not exposed to the outside world and be aware that anyone knowing the ip address inside the intranet will be able to use it, so you are encourage to take securiy measures