Generating and installing an SSL certificate on the nginx web server

Installing an SSL certificate on Nginx: generating a CSR (OpenSSL), obtaining the certificate, and configuring the HTTPS (301) redirect.

nginx ssl

In the previous article: Free SSL certificates I described where you can get a free, browser-trusted SSL certificate. This time we'll deal with the practical part, i.e. generating and installing an SSL certificate for our site. Since I'm a fan of the nginx server, the configuration description will concern this particular web server. When creating the certificate we'll use the openssl package, although you can always use an online generator instead.
The second requirement is that nginx be compiled with support for the ssl module. In the console we run: nginx -V; if we get: --with-http_ssl_module then "we're good to go", otherwise we need to recompile nginx. The compilation process can be found in the article about configuring rtorrent + rutorrent = GUI/WebUI.

Creating the certificate:

  • we perform all actions from the root account
  • Let's create a directory for the certificate, e.g. mkdir -p /etc/nginx/ssl/our_domain_name
  • We generate an RSA key without a password (allows restarting the web server without providing a password):
  • openssl genrsa -out mydomain.key 2048
  • If we don't mind entering a password each time (min. 4 letters):
  • openssl genrsa -des3 -out mydomain.key 2048
  • Generating the certificate request:
  • openssl req -new -key mydomain.key -out mydomain.csr
  • While generating the certificate request (CSR) we'll be asked to provide some information without using Polish diacritical characters (ą, ł, ó, Ł, Ó...) or special characters ( ? . , > ~ ! # @ $ % ^ * / \ ( ) ) :
    
    	
  • Country Name - provide the two-letter country code
  • State or Province Name - full name of the province/state, e.g. Malopolskie
  • Locality Name - full name of the city
  • Organization Name - full name of our company / organization, e.g. Company Name Inc.
  • Organizational Unit Name - department of the company / organization
  • Common Name - full domain name (FQDN) of the encrypted site, e.g. mail.our_domain.com
  • Email - for contact regarding the certificate (optional field)
  • A challenge password []: - leave blank
  • An optional company name []: - not required
  • After creating the csr file, we log into the StartSSL website and then click Certificates Wizard, choosing Web Server SSL/TLS Certificate
  • Then we choose Skip, and reach Submit Certificate Request. We paste in the content of our csr file
  • If everything went as expected, we'll see the message: Certificate Request Received
  • We choose our domain from the list
  • Next we'll be asked to provide the subdomain we want to secure (e.g. www.our_domain.com)
  • We save the generated certificate under the name mydomain.crt
  • We download the following file to the server: wget https://www.startssl.com/certs/class1/sha2/pem/sub.class1.server.sha2.ca.pem
  • We append the content of this file to our certificate: cat mydomain.crt sub.class1.server.sha2.ca.pem >> mydomain.pem
  • It's good to set the correct permissions on our files:
    chmod 600 /etc/nginx/ssl/our_domain_name/mydomain.key
    	
    chmod 600 /etc/nginx/ssl/our_domain_name/mydomain.pem

Configuration: nginx + SSL
At this point, all that's left is to enable SSL on the nginx server. Since we generated the SSL certificate for a subdomain, we'll configure a v-host. For simplicity, let's assume our domain is: mail.domain.com . The configuration itself is identical for all distributions, though it may differ e.g. in paths. The configuration below was carried out on Debian. The configuration will be constructed so that the user doesn't have to specifically type into the browser: https://mail.domain.com - just mail.domain.com is enough .

  • We create the configuration file for our virtual host: touch /etc/nginx/sites-available/mail
  • server {
                listen  80;
                server_name  mail.domain.com;
    			
                ## old, less optimal solution: wiki.nginx.org/IfIsEvil
                # if ($host = 'mail.domain.com' ) {
                #     rewrite ^/(.*)$ https://mail.domain.com/$1 permanent;
                # }
    			
                # current solution
                return       301 https://mail.domain.com$request_uri;
    			
                access_log  /var/log/nginx/mail.domain.com.access.log;
                error_log  /var/log/nginx/mail.domain.com.error.log;
            }
    
    server	{
                listen 443;
                ssl on;
                server_name mail.domain.com; 
    ssl_certificate /etc/nginx/ssl/mail.domain.com/mydomain.pem; ssl_certificate_key /etc/nginx/ssl/mail.domain.com/mydomain.key;
    access_log /var/log/nginx/mail.domain.com.access_log; error_log /var/log/nginx/mail.domain.com.error_log; . . # rest of the configuration file }
  • We create a symbolic link: ln -s /etc/nginx/sites-available/mail /etc/nginx/sites-enabled/mail
  • Then restart nginx: /etc/init.d/nginx restart
  • Finally, let's check if the browser accepts our certificate (view: Google Chrome):
  • startssl nginx