Monday, December 26, 2016

Niginix Two way SSL

Configuring Nginx two way SSL is not that much difficult. But if you want to add additional configuration for additional security then it is tricky.
So purpose of this article is:
1. Compile Nginx
2. Configure two way SSL
3. Do the additional setting for
    1. Allow traffic only from specific IP, If IP is not matching throws error 403
    2. Allow traffic only if client certificate serial ID matches the one whitelisted on Nginx

Installing NGINX Dependencies

Prior to compiling NGINX from the sources, it is necessary to install its dependencies:
PCRE library – required by NGINX Core and Rewrite modules and provides support for regular expressions:
tar -zxf pcre-8.39.tar.gz
cd pcre-8.39
./configure
make
sudo make install


zlib library – required by NGINX Gzip module for headers compression

wget http://zlib.net/zlib-1.2.8.tar.gz
tar -zxf zlib-1.2.8.tar.gz
cd zlib-1.2.8
./configure
make
sudo make install

the OpenSSL library – required by NGINX SSL modules to support the HTTPS protocol:

wget http://www.openssl.org/source/openssl-1.0.2f.tar.gz
tar -zxf openssl-1.0.2f.tar.gz
cd openssl-1.0.2f
./configure darwin64-x86_64-cc --prefix=/usr
make
sudo make install

Download Nginx Source:

Download required version from http://www.nginx.org/en/download.html
wget http://nginx.org/download/nginx-1.10.2.tar.gz
tar zxf nginx-1.11.7.tar.gz
cd nginx-1.11.7

./configure --prefix=/opt/SP/apps/nginx-1.10.2-/ --with-pcre=/tmp/pcre-8.39/ --with-http_ssl_module --with-openssl=/opt/SP/apps/nginx-1.10.2/openssl-1.0.2h/ --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module --with-debug --with-http_stub_status_module --http-log-path=/var/SP/log/nginx-/access.log --error-log-path=/var/SP/log/nginx-/error.log --pid-path=/var/SP/run/nginx-/nginx.pid --add-module=/opt/SP/apps/nginx-1.10.2-/external_modules/headers-more-nginx-module-0.30/

make
sudo Make install
So we have Nginx ready to run.
Two way SSL:
    server {
        listen       8443 ssl;
        server_name  localhost;
        ssl on;
        ssl_certificate         /opt/SP/apps/nginx/conf/cert/server_ssl_certificate.pem;
        ssl_certificate_key     /opt/SP/apps/nginx/conf/cert/server_certificate_key.key;
#       ssl_client_certificate  /var/tmp/yogicert/testcertforapixclinetroot/rootca.pem;
        ssl_verify_client optional_no_ca;
        ssl_verify_depth 1;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

set $allow false;
if ($http_x_forwarded_for ~ " ?85\.205\.164\.99?")
{
        set $allow true;
}

#2 New Plex IPS whitelisting
if ($http_x_forwarded_for ~ " ?47\.73\.63\.55?")
{
        set $allow true;
}
if ($http_x_forwarded_for ~ " ?47\.73\.63\.56?")
{
        set $allow true;
}

if ($allow = false)
{
        return 403;
}

        location / {
        set $skey $ssl_client_serial;
           if ( $skey !~* "01000000000123gfgf86E21EBE" )
                {
                        return 403;
                }
           #if ( $ssl_client_serial != "010000000001589B13CE86E21EBE" : "0cdf344ba95a6b2902715f213f8fe9fd") {return 403;}
           proxy_pass         http://127.0.0.1:8080/;
           proxy_set_header        Host            $host;
           proxy_set_header        X-Real-IP       $remote_addr;
           proxy_connect_timeout      15;
           proxy_send_timeout         17;
           proxy_read_timeout         20;
           client_body_buffer_size 10K;
        }

In above config code snippet we are providing server certificate and key. For two way SSL we are enabling ssl_verify_client. If you do not have client CA certificate then we can use option “optional_no_ca”. For IP matching we are matching with variable $http_x_forwarded_for and for certificate serial ID we are looking for $ssl_client_serial.

Please note than you have to enable option ssl_client_verify to get certificate details to Nginx.