Installing SSL on Ubuntu with nginx

This article explains how to get your website secured with a signed certificate on a Ubuntu server running nginx. I got this thing working by following this Slicehost forums article which is for self-signed certificates and which outlines a number of technical workarounds you need to do for nginx.

Because I like to hear the sound of my own typing, I'm going to run through some basics in thoroughly lay-person terms. Ironically this article sometimes is a bit non-technical, so the anticipated audience probably doesn't even use nginx. Oops it's some kinda crazy zeedonk article.

Goal

Right you have a website running fine at http://example.com. You want it to be accessible via https://example.com. You want the little lock to appear in your browser, and you don't want your visitor to be greated with an ugly message about "trusting certificates".

Create a certificate

Login to the server as root. We need to go to where the certificates and keys are. We're going to where the files live that are used in the message encryption and decryption between machines. It's all frightfully complex actually and I don't like being here... but soldier on we must.


root@mybox:~$cd /etc/ssl
root@mybox:/etc/ssl$ ls
certs openssl.cnf private

Create a private key

Now we'll create a private key. We'll do all this in a temporary directory for good measure.


root@mybox:/etc/ssl/private# cd ..
root@mybox:/etc/ssl# mkdir temp
root@mybox:/etc/ssl# cd temp
root@mybox:/etc/ssl/temp# openssl genrsa -des3 -out example.com.key 1024
Generating RSA private key, 1024 bit long modulus
..........++++++
................++++++
e is 65537 (0x10001)
Enter pass phrase for secure.emspace.com.au.key: ##########
Verifying - Enter pass phrase for secure.emspace.com.au.key: ##########

Remember that password it's used in the next step. Now using that key we create a CSR (Certificate Signing Request) this is going to be sent to a third party organization called a "Certificate Authority", like GeoTrust of Thawte.

So this is where we store the information that our visitors will see if they ever stop to examine our certificate. In the code below, don't type the <-- bits, they are instructions to you. Sorry for the crappy coloring, I need to see if I can get this syntax highlighting to work with bash.


root@mybox:/etc/ssl/temp# openssl req -new -key example.com.key -out example.com.csr
Enter pass phrase for secure.emspace.com.au.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:AU
State or Province Name (full name) [Some-State]:Victoria
Locality Name (eg, city) []:Melbourne
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Urbits Pty. Ltd.
Organizational Unit Name (eg, section) []:Em Space
Common Name (eg, YOUR name) []:example.com <-- the domain or subdomain you want to secure.
Email Address []:nospam@ham.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: <-- just hit enter
An optional company name []: <-- just hit enter

If you list the contents of the directory now, you will see a .key file and a .csr file.

De-password the key

With the key we've got, if the server is restarted someone needs to punch in the password into a console to SSL run. There are notes about this in the linked Slicehost article. In my case I want the server to start automatically so I want to remove the password requirement from the key. Technically I think you can skip this bit if you have reason for the extra security.


root@mybox:/etc/ssl/temp# cp example.com.key example.com.key.copy
root@mybox:/etc/ssl/temp# openssl rsa -in example.com.key.copy -out example.com.key
Enter pass phrase for secure.emspace.com.au.key.copy:
writing RSA key

Get your certificate signed

OK. Now to spend some money on getting a company to trust our certificate. You might think you need to front up to some giant glassy tower block with your birth certificate and passport. But for whatever reason no. These companies simply get you to approve the certificate creation via a primary email address associated with the domain, like "webmaster@example.com". Coolio.

Back on the server. Pump out the CSR to the buffer so you can copy it on your clipboard and copy everything including the -----HEADER AND FOOTER BITS------. Surprisingly, in my case the certificate has come out as the Lorum Ipsum text! What are the chances!


root@mybox:/etc/ssl/temp# cat example.com.csr
-----BEGIN CERTIFICATE REQUEST-----
Loremipsumdolorsitamet,consecteturadipisicingelit,seddoeiusmodte
mporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,qu
isnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconse
quat.Duisauteiruredolorinreprehenderitinvoluptatevelitessecillum
doloreeufugiatnullapariatur.Excepteursintoccaecatcupidatatnonpro
ident,suntinculpaquiofficiadeseruntmollitanimidestlaborumLoremip
Loremipsumdolorsitamet,consecteturadipisicingelit,seddoeiusmodte
mporincididuntutlaboreetdoloremagnaaliqua.Utenimadminimveniam,qu
isnostrudexercitationullamcolaborisnisiutaliquipexeacommodoconse
quat.Duisauteiruredolorinreprehenderitinvoluptatevelitessecillum
-----END CERTIFICATE REQUEST-----

Find a certificate authority

I'm off now to some place that will sell me a certificate. This one will do, I got the link from the website of a secure payment gateway company I've used. You can pay a lot more for a certificate that will work with any subdomain, or that has lots of insurance, or that will not complain with IE2. Me I'll grab the cheap one and choose to buy "Quick SLL" from GeoTrust.

I also choose something more than 1 year to avoid feeling like I'm aging quickly when the certificate suddenly expires a year from now.

Pay

Step through a screen or two until you come to the place where we paste the CSR - here is what it looks like to me.

The following screen for me ask for my personal details and also ask me to nominate one of a limited number of defined email adresses. I usually have configured the webmaster address so I choose that one. I then go through to the cart and pay.

Email Confirmation

If I've configured webmaster@example.com correctly I should get an email soon. I see I've got a few emails but the one I'm looking for looks something like this. Look! I'm asking myself to do stuff using some sort of funky interwebs foldback!


The person identified below has requested a QuickSSL Premium certificate for:
https://example.com

Applicant information:
Name: Simon Hobbs
E-mail: simon@example.com
Phone: 61396395436

Simon Hobbs requests that you come to the URL below to review and approve this certificate request:

https://products.geotrust.com/orders/Approval.do?pin=ABCASEASYAS123

If you have any questions, please contact the person identified above, or visit customer support.

All I have to do is follow that link and approve the order and I'll soon be the proud owner of another TLA called a CRT.

Make the CRT file

In my email now I've been sent something that looks akin to the CSR but is a Certifiate (CRT). If I was self-signing my certificate I would have produced one of these little babies, but it wouldn't have the benefit certificate authority like GeoTrust tell browsers that it was automagically kosher.

I copy the CRT in the same way as the CSR and go back to the server. I'm just going to create a file and then use a text editor like vi to paste my CRT into the file.


root@mybox:/etc/ssl/temp# touch example.com.crt
root@mybox:/etc/ssl/temp# vi example.com.crt

Shuffle files

We now put the files in their spots. I could then nuke the temp directory but I'll just get everything working first. I do however do a quick check of the private directory. The permissions should look like this or SSL may simply not work.


root@mybox:/etc/ssl/temp# cp example.com.crt ../certs/
root@mybox:/etc/ssl/temp# cp example.com.key ../private/
root@mybox:/etc/ssl/temp# ls -la ../private/
drwx------ 2 root root 4096 Feb 20 04:24 .
drwxr-xr-x 5 root root 4096 Feb 19 18:54 ..
-rw-r--r-- 1 root root 887 Feb 20 04:24 example.com.key

nginx vhost

I'll create a separate virtual host configuration file for secure and normal sites. It's a bit cleaner. So in /etc/nginx/sites-available I add a new file that looks like this.


server {
listen 443;

ssl on;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;

server_name example.com;

... more stuff
}

Once you've got that sorted, remember to put a soft link to your vhost file in sites-enabled in what appears to be the good Ubuntu way. Then test your config sudo /usr/sbin/nginx -t

Gotchas?

  • You try to install two certificates on the one server, but they run on the same IP. You need a new IP.