How to Secure Socket Layer

It's been a few years since I've had to set a SSL cert. Having to revisit the subject makes me appreciate even more what DevOps has to deal with on a day to day basis.

Setting up SSL is relatively straight forward in theory, simply have an authority sign your cert and point your server to those two files right? Easier said then done.
One becomes very spoiled living in Ruby land. Here's a note to myself on setting up and launching basic SSL. Hopefully it will be useful to others.

The stack

  • Ubuntu
  • Nginx
  • Namecheap

The process

  1. Ubuntu
    1. Generate CSR (Certificate Signing Request)
  2. Namecheap (or other issuer)
    1. Upload CSR
    2. Verify domain ownership
  3. Nginx
    1. Install Certificate
    2. Restart and hope it works
  4. Send love to your DevOps team for having to deal with this all the time

Generating a CSR

At this step you are creating two files, a private key server.key and Certificate Signing Request server.csr. The private key is exactly what you'd expect to find in any key pair (à la ssh). The CSR is simply a file containing website identification information signed by the private key.

  1. Run the following on your server:
    openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
  2. Answer all applicable questions. Since this is a personal cert, I left most fields blank with a .
  3. mv the generated server.key (private key) somewhere safe. The conventional location I found was /etc/ssl/private/server.key
  4. Secure it's ownership and access mode appropriately.
    sudo chown root:ssl-cert server.key & sudo chmod 640 server.key
  5. Upload the CSR to your signing authority (namecheap in my case)

Upload CSR & Verify domain ownership

This was simple. I visited namecheap's SSL index and filled out the activation form for the previously purchased SSL cert. Since I had already set up email forwarding I chose that option to validate ownership.

Install the CSR on nginx

This step is a bit more complicated. The signing authority I chose emailed the website's certificate and the intermediary certificate as cleartext in the email. Others send a zip file containing the already concatenated cert. Your mileage may vary just be sure you have the cert for your page and the intermediary cert from the authority.

  1. Copy-pasta the two encrypted certs from the email to ssl.crt and intermediate.crt
  2. Concatenate the intermediate.crt into the ssl.crt
    cat intermediate.crt >> ssl.crt
  3. mv the cert into place. The conventional location I've found is mv ssl.crt /etc/ssl/certs/
  4. Set the cert's owner and permission. sudo chown root:root ssl.crt & sudo chmod 644 ssl.crt
  5. Update the nginx virtual host file for the site you're securing, and add these important bits:
server {  
  listen 443 ssl;

  ssl_certificate /etc/ssl/certs/ssl.crt;
  ssl_certificate_key /etc/ssl/private/server.key;
...

The ssl_certificate is the concatenated cert, ssl_certificate_key is the private key generated with the CSR.

Note on securing the certs:

The concatenated ssl.crt is sent with connections, basically a public read, so not much concern there. However, the server.key is a private key and should be secured appropriately.

That's it!
Restart the server and bask in the warm glow of encryption.

TODO: Hug your DevOps