HTTPS with Nginx: setting up an SSL certificate in 3 simple steps

This article will explain how to serve content securely over HTTPS via Nginx. This can be done in 3 simple steps detailed below. It's unbelievably easy! I've even added an optional step for optimization, and links for further readings.

The three steps are as follows:
Step 1: preparing your private key and CSR 
Step 2: obtaining an SSL certificate
Step 3: Nginx SSL configuration

This post is valid as of October 2014, tested with Nginx 1.2, Nginx 1.4 and Nginx 1.6 (probably works with every version above 1.2). For older versions, directive names might change just a tiny bit but the rest of the process should otherwise work normally.


You will need to have OpenSSL installed on your server. To find out whether OpenSSL is installed on your server, type "openssl version". It should tell you the version you are running. I recommend version 1.0.1 at least because it supports several features which will come in handy in future tutorials (including which SPDY). If you do not have OpenSSL installed yet, just run "apt-get install openssl" or equivalent to install it.

You also need to have the SSL module installed on Nginx. To find out whether you have it, run "nginx -V" and see if the HTTP SSL module is included in the list. If it isn't, you will need to rebuild Nginx with the proper configure parameter (read more).

Step 1: preparing your private key and CSR

Note: in the following examples, you'll need to replace all references to mydomain.com by your actual domain name.

You need two files to be able to obtain an SSL certificate. First, a private key file. Such a file can be generated by running the following command:
openssl genrsa -out mydomain.com.key 2048

You will notice that this command generates a file called "mydomain.com.key" in the current folder. This is your private key file. Now, we're going to use this key to generate a CSR file (Certificate Signing Request), which will be used in step 2 to obtain the SSL certificate. Run the following command:
openssl req -new -key mydomain.com.key -out mydomain.com.csr

Caution! This command will prompt you to enter some values. Enter actual values for your domain and company information, and be extra careful when filling up the "Common Name" field: you need to enter the domain name for which you will use the certificate! If you are going to use the certificate on "mydomain.com" then you have to enter "mydomain.com" as Common Name. If you fail this step, your certificate will not work properly.

After this is done, you'll find yourself with two files: 
- a .key file = your private key file
- a .csr file = your certificate signing request file

Step 2: obtaining an SSL certificate

There are thousands of providers on the web for SSL certificates. I personally use Godaddy because it's reliable and quite cheap. Plus, you can find coupons online (Google it, you'll probably be able to get at least 30% off like I did). 

GoDaddy will ask you to provide your .CSR file in a text box. Just open your .CSR file with a text editor, then copy/paste the entire content into the textbox on GoDaddy. At this point you'll be able to verify the domain name that you entered in step 1. This is your chance to make things right in case you made a mistake.

After your CSR file is uploaded, you'll be able to download your certificate. GoDaddy offers several file formats for the different web servers. Nginx isn't in the list (as of October 2014) so just pick the "Other" option. You're given a .zip file containing two files: 
- a .crt file with a seemingly random name, which is your website's certificate,
- and GoDaddy's .crt file (gd_bundle_something.crt) which is GoDaddy's certificate

Now you're going to need to concatenate these two files into one (your certificate coming first, then Godaddy's). You could do so by creating a new file in the Notepad on Windows and copy-pasting the content of your site's .crt file, then the contents of Godaddy's .crt file. Otherwise on Linux you could just run the following command:
cat your_website.crt gd_bundle_something.crt > mydomain.com.crt
The order is important! Your site's certificate MUST come before Godaddy's, otherwise you'll get a warning/error page from the web browser when visiting your site.

At this point, you should have two files that we'll need to provide to Nginx:
- mydomain.com.key (private key file, from step 1)
- mydomain.com.crt (certificate file which we just generated)
If you are missing one of these, read the tutorial again because I covered both ;-)

Step 3: Nginx SSL configuration

The configuration is done at the server block level:
server {
listen 443 ssl; # this tells Nginx to listen on port 443 (https) with SSL
ssl_certificate     /path/to/your/mydomain.com.crt;
ssl_certificate_key /path/to/your/mydomain.com.key;

[...] # The rest of your vhost configuration...

Save your configuration, reload Nginx and voilà! People can now securely visit your website via HTTPS.

Optional: optimization and advanced configuration

Nginx lets you tweak the configuration with the following directives:
- ssl_protocols: lets you specify the list of allowed SSL protocols
ssl_ciphers: lets you specify the enabled ciphers (format must follow standards imposed by the OpenSSL library)
And many more...

You can also add a few directives at the http block level that may help with performance:
- ssl_session_cache: a caching mechanism for SSL sessions, allowing to avoid new handshake and session overhead every time a user connects. It is used on par with the next directive...
- ssl_session_timeout: defines how long an SSL session should last.
For details on how to use either directive, read the official documentation.

If you really don't want to bother with it, just use the example below:
http {
    ssl_session_cache   shared:SSL:10m; # 10 megabytes are reserved for the SSL cache
    ssl_session_timeout 10m; # 10 minutes


We've set up an SSL certificate on Nginx to serve secure content over a single domain. But what if you have subdomains or multiple domains with the same content? This is a much more complex subject, I recommend reading this before going any further.

Additionally, if you're moving a domain from HTTP to HTTPS, you will probably want to read this article about how to properly move from HTTP to HTTPS from the point of view of SEO. It might be a significant change in the eyes of a search engine!

1,000,000 page views on this blog!

Just a quick self congratulation post: 6 years after the launch of this blog, I've already received

1,000,000 page views!

The milestone was reached last week while I was away. This has led me to realize that I should probably update this blog a little more. I've got two articles coming up:
- How to set up an SSL certificate on Nginx to serve HTTPS content
- How to enable SPDY on Nginx

Thank you for visiting!

Search This Blog