Home > Applications & Tools > Configuring Nginx as Reversed Proxy Server for HTTPS

Configuring Nginx as Reversed Proxy Server for HTTPS

January 6th, 2014 Leave a comment Go to comments

Nginx (pronounced as ‘engine x’) is a light-weight HTTP/reverse proxy/mail proxy server written by Igor Sysoe. It is flexible, lightweight compared, and high-performant with Apache. The official nginx site is here. The beginner guide is a very good starting point. The following is based on my hands-on experience with Nginx. If you have similar requirement, you can copy over the scripts and configuration for your environment.

Installing and running Nginx

Lost VMs or Containers? Too Many Consoles? Too Slow GUI? Time to learn how to "Google" and manage your VMware and clouds in a fast and secure HTML5 App.

It’s quite easy to install Nginx on Linux. In Ubuntu, just issue the following commands to install it. To use advanced features like authentication with PAM, the nginx-extra has to be installed; otherwise, you can skip it.

# apt-get install nginx
# apt-get install nginx-extras

To run Nginx, just issue nginx command with admin privilege. With the last ps command, you should see master and 4 worker processes. If not, you need to troubleshoot what goes wrong in the installation.

# nginx
# ps aux | grep nginx

After any configuration change, it should be reloaded (not restarted, which is quite nice). The -s option means signal for the Nginx server.

# nginx -s reload

To quit the server, you can send quit signal to the server. Optionally, you can send shutdown which is not as graceful as quit but faster in speed than quit. So always try to use quit if possible.

# nginx -s quit

Configure reversed proxy

Nginx can be used as a primary Web server, but also as a proxy server for either load balancing or hiding the real server identities at the back. The following proxy the traffic to port 80 to port 8080 of local host. You can proxy it to a remote host as well – just change the URL. A more complicated case is to reverse proxy different resources like /images, /scripts to different URLs served by different servers.

The following configuration from /etc/nginx/nginx.conf forwards HTTP traffic to port 8080 which is default port for Tomcat. You can also add your configuration into the /etc/nginx/conf.d directory for a more modular way to manage the configurations.

	server {
	  listen 80;
	  location / { proxy_pass http://localhost:8080; }

Generate key/certificate for SSL

Nginx has good support of secure communication with https. You need to create key and certificate for SSL, and then change configuration to enable https (next section).

First, let’s create a working diretory for the SSL key/certificates:

# mkdir -p /etc/nginx/ssl
# cd /etc/nginx/ssl

In the ssl directory, let’s run the following commands. You can change the name of the keys and certificates.

# openssl genrsa -des3 -out server.key 2048
# openssl req -new -key server.key -out server.csr
# cp server.key server.key.bak
# openssl rsa -in server.key.bak -out server.key
# openssl x509 -req -in server.csr -signkey server.key -out server.crt

When all done, two (more is fine) files must be in the directory.

# ls /etc/nginx/ssl
server.crt  server.key

Modify configuratiovin to enable SSL

Now it’s time to change the configuration file /etc/nginx/nginx.conf. The following configuration file defines three ports:

# vim /etc/nginx/nginx.conf
    server {
        listen 80;
        location / { proxy_pass http://localhost:8080; }
        location ~ \.(gif|jpg|png) { root /data/images; }
    server {
        listen 8080;
        root /data/up1;
        location / { }
    server {
        ### server port and name ###
        listen          443;
        ssl           on;
        ### SSL log files ###
        access_log      /var/log/nginx/ssl-access.log;
        error_log       /var/log/nginx/ssl-error.log;
        ### SSL cert files ###
        ssl_certificate      ssl/server.crt;
        ssl_certificate_key  ssl/server.key;
        ### Add SSL specific settings here ###
        ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers RC4:HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        keepalive_timeout    60;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;
        ### We want full access to SSL via backend ###
        location / {
            proxy_pass  http://localhost:8080;
            ### force timeouts if one of backend is died ##
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
            ### Set headers ####
            proxy_set_header        Accept-Encoding   "";
            proxy_set_header        Host            $host;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            ### Most PHP, Python, Rails, Java App can use this header ###
            #proxy_set_header X-Forwarded-Proto https;##
            proxy_set_header        X-Forwarded-Proto $scheme;
            add_header              Front-End-Https   on;
			proxy_redirect     off;

Re-direct HTTP to HTTPS

If you want to have a secure Web site, you can redirect all the HTTP request to the HTTPS. The following configuration snippet can redirect any request to port 80 to the port 443 with https protocol.

    server {
        listen 80;
        return 301 https://$host$request_uri;
Categories: Applications & Tools Tags: , ,