HTTP, the Hypertext Transfer Protocol, is the foundation of communication on the Internet. But it is not secure, the communication happens in an unencrypted format. However, HTTPS uses SSL or TLS cryptographic protocol to encrypt the data flow. In this post we will see Nginx HTTP to HTTPS redirection, with Comodo Positive SSL certificate, and performance optimization using TLS. We will not use SSL because it is vulnerable to POODLE attack.

We will need an nginx server up and running with ssl and spdy modules enabled. This again is not something huge. just run run apt-get install nginx-full as root user and you are done. Or you make you may have a look at this LINK , if you are inquisitive about how to install it from source. Also Note that the article talks about Positive SSL Domain Control Validated certificate, because that is the one that I am using. And needless to say I am using it because it is cheap and provides good encrypted connection for a small website like this. If you are into e-commerce related site consider purchasing and extended validated certificate.

1) Generate the Server Private key and a CSR with 2048 bit encryption:

cd /etc/ssl openssl req -nodes -newkey rsa:2048 -sha256 -keyout example.com.key -out example.com.csr

In the above example, I have used a dummy domain name “example.com” . Please use your actual domain name and the mail id, wherever needed. Now, Contact any SSL Certificate Provder of your choice and pick a Comodo Positive SSL. After payment and submission of .csr file that was created earlier, you will receive your certificate as a zipped attachment in your mail. This zipped attachment will typically contain four files. Extract it, copy the files to ‘/etc/ssl’ location on the server using scp command (from a linux/unix client) or using winscp from a windows client. The files are:

1) example_com_com.crt;

2) COMODORSADomainValidationSecureServerCA.crt;

3) COMODORSAAddTrustCA.crt;

4) AddTrustExternalCARoot.crt.

2) Create the certificate bundle file using the above files:

cd /etc/ssl cat example_com_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl_bundle.crt

Please note that the order of contatenating (cat) the files as mentioned needs to be maintated, otherwise SSL error message will be generated.

The bundle file created, with all the four files above is fine and we are good to go, but ssl checking tools like https://www.ssllabs.com/ssltest/ tend to report “certificate chain issues” when the self signed Root CA Certificate is included the certificate bundle (In our case the Root CA Certificate is AddTrustExternalCARoot.crt ) . So to avoid that create the certificate bundle file excluding the Root Self Signed CA Certificate.

cd /etc/ssl cat example_com_com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt > ssl_bundle.crt

At this point of time, we have our server key file ‘example.com.key‘ and the certificate bundle file ‘ssl_bundle.crt‘, in ‘/etc/ssl‘. Now we are good go ahead and enable HTTPS on our server and also redirect all HTTP requests to HTTPS. But before we do that let us have a look into optimization of HTTPS.

3) Dealing with SSL/TLS connection overhead and optimizing HTTPS performance:

Session Cache

ssl_session_cache caches session parameters that create the SSL/TLS connection. This cache, shared among all worker_connections, will drastically improve later requests since the connection setup information is already known. As a reference, a 1MB shared cache can hold approximately 4,000 sessions. As the timeout length is increased you will need a larger cache to store the sessions. The default timeout value for ssl_session_timeout is 5 minutes so to improve performance it can be increased to a several hours.

ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m;

OCSP Stapling

Another way to improve HTTPS performance is with OCSP stapling, which decreases the time of the SSL/TLS handshake. Traditionally, when a user connects to your application or website via HTTPS their browser will validate the SSL certificate against a Certificate Revocation List (CRL) or will use an Online Certificate Status Protocol (OCSP) record from a Certificate Authority (CA). These requests add latency and the CA’s can be unreliable. With NGINX you can cache the OCSP response to your server and eliminates costly overhead.

ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/ssl/ssl_bundle.crt; resolver 8.8.8.8 8.8.4.4 valid=60s;

Session Tickets and ID’s

Session tickets store information about specific SSL/TLS sessions. When a client resumes interaction with an application the session ticket is used to resume the session without re negotiation. As an alternative to session tickets, session id’s can be used. Session id’s map to a specific session stored in the ssl_session_cache via a MD5 hash. Both mechanisms can be used to shortcut the SSL handshake.

ssl_session_tickets on;

SSL protocols:

As discussed above, we will not be using SSL as it is vulnerable, instead we move to TLS.

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

Cipher Suites

Specifying optimized Cipher Suites, the algorithms that encrypt the network communications, using the ssl_prefer_ciphersdirective, increases the performance. The reality is that the default settings are good enough for most cases. This setup, and best practice, works equally well for old, current, and, hopefully, future ciphers. Selection of specific ciphers for security and performance should only be used to fulfill specific requirements.

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

SPDY

SPDY is an experimental protocol that attempts to reduce latency and round-trip times. The protocol creates a tunnel between the web browser an application server. Through HTTP multiplexing, SPDY allows for concurrent streams to take place over a single TCP connection. This reduces the need for additional connections and SSL negotiations. The protocol also compresses request and response HTTP headers resulting in fewer bytes transmitted. It’s important to note that you will not receive the benefits of SPDY if you are sharding domains.

listen 443 ssl spdy; spdy_headers_comp 1;

Generate DH parameters:

Phew..!!!! This LINK provies a great deal of information on it.

Create the DH parameters file with 2048 bit long safe prime:

openssl dhparam 2048 -out /etc/ssl/dhparam.pem

And add it to your Nginx config:

ssl_dhparam /etc/ssl/dhparam.pem;

Note that Java 6 doesn’t support DHParams with primes longer than 1024 bit.

Strict Transport Security:

This feature comes in handy when HTTP to HTTPS redirection is enabled, The Strict Transport Security (STS or HSTS) should be done to avoid having to do those redirects everytime. STS is a nifty little feature enabled in modern browsers. All the server does is to set the response header Strict-Transport-Security with a max-age value. If the browser sees this header, it will not try to contact the server over regular HTTP again for the given time period. It will actually interpret all requests to this hostname as HTTPS, no matter what.

add_header Strict-Transport-Security "max-age=31536000";

3) We are done finally:

So here’s how our nginx server difinition block will look like after enabling HTTPS, optimizing it for performance and enabling HTTP to HTTPS redirection:

server { listen 443 ssl spdy; server_name www.example.com example.com; ssl_certificate /etc/ssl/ssl_bundle.crt; ssl_certificate_key /etc/ssl/example.com.key; ssl_session_cache shared:SSL:20m; ssl_session_timeout 10m; ssl_prefer_server_ciphers on; ssl_ciphers HIGH:!aNULL:!MD5; ssl_dhparam /etc/ssl/dhparam.pem; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_tickets on; ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/ssl/ssl_bundle.crt; resolver 8.8.8.8 8.8.4.4 valid=60s; add_header Strict-Transport-Security "max-age=31536000"; # Other server related configuration goes below this: # […] } server { listen 80; server_name www.example.com example.com; return 301 https://www.example.com$request_uri; }

4) So how will the ratings at https://www.ssllabs.com/ssltest/ look like after all this.. Some like this image below: