Monday, May 27, 2013

HTTPS on Nginx with SSL Certificate

A directory to keep a copy of certificates as a backup:
# cd /root
# mkdir nginx_ssl

Only root have the access:
# chmod 700 nginx_ssl

Create Certificate

Now, you need to understand that one server can hold multiple certificates, but only one per listening IP address. So, if your server is listening on one IP address, you can only have one certificate for the server. Follow me so far? All of your virtual domains can share the same certificate, but clients will get warning prompts when they connect to a secure site where the certificate does not match the domain name. If your server is listening on multiple IP addresses, your virtual hosts have to be IP-based -- not name-based. This is something to consider when creating your certificate. :-)

# cd /root/nginx_ssl
# openssl genrsa -des3 -out server.key 1024

Note: You will now be prompted to enter in a password. Write this down as you will need it later.

We need to make a Certificate Signing Request (CSR):
# openssl req -new -key server.key -out server.csr

Note: Enter your password when it asks for it. Make sure you enter your FQDN for the "Common Name" portion.

Self-signing your Certificate

You could always pay money to Verisign or Thawte for this but it costs $$$. Here is the way to do it:

# openssl x509 -req -days 365 -in /root/nginx_ssl/server.csr -signkey /root/nginx_ssl/server.key -out /root/nginx_ssl/server.crt
# chmod 400 *

Now your cert is good for 365 days. If you want to make it longer, go right ahead and do so :-)

If you would like more information about SSL Certs, go to

Now we need to copy the certs to the right place:
# mkdir /usr/local/etc/nginx/nginx_ssl
# chmod 500 /usr/local/etc/nginx/nginx_ssl
# ls -ld /usr/local/etc/nginx/nginx_ssl
# cp /root/nginx_ssl/server.key /usr/local/etc/nginx/nginx_ssl
# cp /root/nginx_ssl/server.crt /usr/local/etc/nginx/nginx_ssl
# chmod 400 /usr/local/etc/nginx/nginx_ssl/server.key
# chmod 400 /usr/local/etc/nginx/nginx_ssl/server.crt

Note: you don't need to copy the server.csr file.

Add these lines to nginx.conf:
# vi /usr/local/etc/nginx/nginx.conf
ssl                  on;
ssl_certificate      nginx_ssl/server.crt;
ssl_certificate_key  nginx_ssl/server.key;

ssl_session_timeout  5m;

ssl_protocols        SSLv2 SSLv3 TLSv1;
ssl_ciphers          HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers   on;

Add this line to the FastCGI block of nginx.conf file if you want to see print_r($_SERVER['HTTPS']) in PHP:
fastcgi_param HTTPS on;

To this block in nginx.conf:
location ~ \.php$ {
                    fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    #NOTE: You should have "cgi.fix_pathinfo = 0" in php.ini
                    include fastcgi_params;
                    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                    fastcgi_param HTTPS on;
                    fastcgi_intercept_errors on;
                    #fastcgi_pass;  #pass the PHP scripts to FastCGI server listening on
                    fastcgi_pass unix:/tmp/php-fpm.sock;

Add following line if you want Nginx to support wildcard domains / hostname:
fastcgi_param SERVER_NAME $http_host;


No comments: