Tuesday, June 9, 2015

TRANSPARENT DYNAMIC REVERSE PROXY WITH NGINX

Hello Guys welcome back again on my blog again.
Recently I have change my company and in the new office i got this new unique task of creating a new dynamic transparent dynamic proxy the group of developers working with me.
      so here what I have done to full fill the requirement with nginx.


Here is the sit­u­a­tion. You have a sin­gle pin­hole into your pri­vate net­work. You have a sin­gle ip at your gate­way. You want to serve mul­ti­ple web­sites on your lan that may be run­ning on mul­ti­ple phys­i­cal servers. Rather than open­ing up mul­ti­ple ports and pin­holling to all the dif­fer­ent spots you want to serve, or get­ting more exter­nal ips and doing 1to1 NAT you can use a reverse proxy to be your sin­gle entrance point. The reverse proxy will fetch the con­tent from the back­end server and serve it up.
nginx is a HTTP server and mail proxy server. One of its fea­tures basic HTTPfea­tures is accel­er­ated reverse proxying.
nginx should be avail­able through your pack­age man­ager so just apti­tude (or what­ever your pack­age man­ager is yum, emerge, pac­man) install it.
The con­fig file paths shown are Debian spe­cific but the con­fig itself should work on any distro.
Edit /etc/nginx/sites-available/default and make it look like this
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
     listen  :80;
     server_name  _;
     access_log  /var/log/nginx/proxy.access.log;
     location / {
     resolver        127.0.0.1;
     proxy_pass      http://$host$uri;
     proxy_redirect off;
     proxy_set_header        Host    $host;
     proxy_set_header        X-Real-IP $remote_addr;
     proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
     }
     error_page   500 502 503 504  /50x.html;
     location = /50x.html {
          root   /var/www/nginx-default;
     }
}
So this con­fig causes nginx to lis­ten on all interfaces/ips. server_name _; matches on any­thing so essen­tially this is a catchall now. You can tail proxy.access.log in order to see the requests are they come in and are served.
The loca­tion sec­tion is where the actual prox­y­ing hap­pens. Since this is a dynamic con­fig­u­ra­tion you need to set a resolver where the requested names can be looked up (and over­rid­den for the local lan address). dns­masq reads is dns con­fig­u­ra­tion right out of /etc/hosts. It’s easy to install and con­fig­ure so I rec­comend using it. We will install and con­fig­ure it shortly but for now just leave resolver as 127.0.0.1. proxy_pass does the request­ing of the page we are prox­y­ing. Since this is a trans­par­ent dynamic proxy we just have it request the same thing that was requested of the proxy. proxy_redirect should be set to off since we are just pass­ing on the same request. We need to set a few head­ers for log­files on the back­end servers as well as mak­ing sure that Host is set to the request­ing host in case your using name based vir­tual hosts on your back­end servers. I have left the error page in the default con­fig (at least on debian its default). This pro­vides a nice error mes­sage in case your proxy is work­ing but one of the back­end servers is not. It just serves the index.html that is located in /var/www/nginx-default. Feel free to change that path to some­thing else, mod­ify the index.html or omit the error_page and error page loca­tion sec­tion all together as they aren’t needed for this to work.
Now we need to get that local resolver (dns­masq) installed so we can take our reverse proxy for a spin. Go ahead and apti­tude (or what­ever) install dnsmasq.
At least on debian dns­masq comes out want­ing to serve dhcp. You prob­a­bly do not want this behav­ior. There is also the ques­tion of need­ing access to these same ser­vices by the same name on your LAN. If you need this you might need to do some slight adjust­ing of your dns. I might rec­comend point­ing your main dns to this dns­mask proxy or point­ing all of your clients at this dns­masq install since it will look up other requested names other than those in /etc/hosts. For this exam­ple I will assume you will be want­ing to access these same web ser­vices inter­nally with the same names and bypass the proxy. So I will assume you have either changed your pri­mary dns cacher/resolver (think soho router or what­not) to the address of the proxy server (since its run­ning dns­masq as well), or set all of your clients to point directly at the proxy server for dns. We need to edit the dns­masq con­fig to dis­able dhcp.
Edit /etc/dnsmasq.conf and add no-dhcp-interface=ethx. Do that for every inter­face on your sys­tem so that your not acci­den­tally serv­ing out dhcp to any­one. If somone has a more generic way to dis­able dhcp in dns­masq with­out spec­i­fy­ing each inter­face I would love to know but from read­ing the man this was the only way I could find. So you may have some­thing like the fol­low­ing in you /etc/dnsmasq.conf.
?
1
2
no-dhcp-interface=eth0
no-dhcp-interface=eth1
After mak­ing the change you should be ready to add entries to the proxy servers /etc/hosts for dns­masq to use and then test your reverse proxy.
Lets say you have www.test.com served off of a machine with the ip 192.168.1.2 and you have tickets.office.test.com served off of 192.168.1.3. Lets also assume that your world route­able ip is 123.123.123.123. You will need to make sure that your author­i­ta­tive dns (the real one that servs for test.com has A records for both www.test.com and tickets.office.test.com point­ing to 123.123.123.123. Now on the machine run­ning dns­masq (in this exam­ple also your proxy server) add the fol­low­ing entries to /etc/hosts.
?
1
2
192.168.1.2 www.test.com
192.168.1.3 tickets.office.test.com
Go ahead and restart dns­masq (from mak­ing changes to the con­fig, sub­se­quent changes to /etc/hosts should not require dns­masq restart to pick up changes) and nginx.
Now tail your proxy.access.log file and start mak­ing requests to www.test.com and tickets.office.test.com from both the inside of your lan as well as out­side against your world ip. It should all mag­i­cally serve up the same content.
This type of con­fig can be use­ful in many sit­u­a­tions. You have a small office and bud­get that reflects that not being able to afford mul­ti­ple ips but need­ing to pro­vide web ser­vices behind the fire­wall. You work in a large cor­po­ra­tion where some­one else man­ages the fire­wall and you would like to bring up more web ser­vices with­out wait­ing for the other per­son to make the nec­es­sary changes to the firewall.
One of the other ben­e­fits this pro­vides is being rel­a­tively self doc­u­ment­ing  with regard to what web ser­vices you host behind the fire­wall. (you should be able to see all of them in /etc/hosts since you have to over­ride the dns)

and in the next blog i will tell you how you can achive the same for https i mean dynamic proxy with ssl  ....