Monday, July 7, 2014

Nginx dynamic reverse proxy

About four years ago, i was knew Nginx when try to fight with slowloris attack on my Apache server. Since that day I was fell in love with Nginx and it never cease to amaze me about what it can do. I now i decice to collect about some part of my use case and solution with Nginx to share.

Our team have one line of internet and one public IP which have to handle many kind of web application behind it some of web application very simple and doesn't care about virtual domain, URL rewirte, authentication resource optimization. So it really need a front web-server who fill the gap  and make the manage process more easy and secured. That where Nginx coming and give me a greate favour. Here is what Nginx currently do in my server:

  • Forward request base on domain and url to the right web application behind 
  • Support https, SPDY to make web application faster and more secure.
  • Caching and optimizing the response of web application's static resource.
  • Authentication and authorization base on domain and URL.
  • Rewrite the URL and add more information to request to help the web application understand more about user. 
  • Limited request rate and bandwidth, deny request base on IP and country to protect web application from abuse by bad visitor.
The Case 1:
We have a IP range in our local network which reserve for 4 virtual machine which run our demo product and can be managed directly by developer when they need to show case to our customer. 

Problem is every time they want allow outside access to their demo product i have to add new record to Nginx or router to forward the request to demo server and now i go tired with that task. I want nginx to extract the forward destination by reading the domain information and forward request to that. For example, when user request http://acceptance01.8080.example.net/index.php Nginx will forward lookup local DNS for computer name acceptance01 and forward to that computer on port 8080 with file index.php. If request failed some how Nginx will handle the bad situation by display a nice error message.

Here is some quick and dirty config from my /etc/nginx/sites-available/vm.example.com
server {
    listen   80;
    server_name  *.vm.example.com;

    # Point this to you DNS server which client get DHCP from
    # for example: a virtual machine with host name "abc" request DHCP with your router
    # the DNS name will remember the IP address of "abc" in memory that why we can use
    # hostname with style of abc.vm.example.com
    resolver 192.168.1.1;

    set $realservername "";
    set $realport "80";

    if ($http_host ~ ^([a-z0-9\-]*)\.(vm\.example\.com)$) {
        set $realservername $1;
    }

    if ($http_host ~ ^([a-z0-9\-]*)\.(\d*)\.(vm\.example\.com)$) {
        set $realservername $1;
        set $realport $2;
    }

    location / {
        # Block client if client not from my country
        # if ($geoip_country_code !~ (VN|^$) ) {
        #    return 403;
        # }

        # uncomment this if you want to limit the name list of server name
        # if ($realservername !~ (name1|name2|name3) ) {
        #    return 403;
        # }

        proxy_connect_timeout 10s;
        proxy_read_timeout 20m;
        proxy_send_timeout 20m;
        proxy_pass  http://$realservername:$realport;

        # needed to forward user's IP address to rails
        proxy_set_header  X-Real-IP  $remote_addr;

        # needed for HTTPS
        proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_max_temp_file_size 0;
    }
}

You will also need a wildcard DNS for *.vm.example.com point to your server. I using Cloudflare free service which support wildcard DNS. Check with your DNS provider to make sure it support.

1 comment:

  1. I just like the helpful info you supply in your articles. I will bookmark your blog and check once more right here frequently. I'm reasonably sure I will be told many new stuff right here! Good luck for the next! paypal login my account

    ReplyDelete