General documentation / cheat sheets for various languages and services

SSL

Generating an SSL key and signed certificate

These instructions will adapt to the input you provide so that you can easily copy and paste the required commands into your terminal.

This process involves writing and reading several files. Create a new directory and cd into it. The rest of these instructions assume that you stay in this directory.

1. Generate a random private key

Run the following command to randomly generate a private key:

openssl genrsa 4096 > {{fields.domain}}.key

You should never show this key to anyone, not even StartSSL. Your web server (e.g., nginx) will use this key to encrypt / decrypt traffic, but otherwise, no one else should see it. If you lose it, you will need to go through this whole process again. Worse, if someone else has access to it, they could potentially read all the traffic going to and from your server, as if your visitors were using plain http://

That command creates a 4096-bit key. You could probably get away with 2048 bits, but 4096 is a safe value.

If you look at the contents of {{fields.domain}}.key, it should begin with the line -----BEGIN RSA PRIVATE KEY----- and end with the line -----END RSA PRIVATE KEY-----, with several (~49) lines of random characters in between.

2. Generate a certificate signing request

This is where your domain name actually gets involved. You can specify all the arguments when calling openssl at the command line, but we'll use a config file.

Create a file called {{fields.domain}}.config with the following text:

[ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] CN={{fields.domain}} O={{fields.organization}} emailAddress={{fields.email}} L={{fields.city}} ST={{fields.state}} C={{fields.country}}

And then run the following command:

openssl req -new -config {{fields.domain}}.config -key {{fields.domain}}.key > {{fields.domain}}.csr

That generates a file called {{fields.domain}}.csr, which we'll use in the next step. {{fields.domain}}.csr should begin with the line -----BEGIN CERTIFICATE REQUEST----- and end with the line -----END CERTIFICATE REQUEST-----, again with a lot of random-looking characters in between.

3. Request the certificate

We'll use StartCom's free certificate-signing service, StartSSL, so you'll need to make an account at https://www.startssl.com/. Then go to the Control Panel, and select the "Validations Wizard" tab. Select the "Type", "Domain Name Validation", and follow the steps there to validate your domain. It will you show you a list of email addresses associated with your domain that it can use to validate that you own that domain, so you'll probably need to be able to read email sent to postmaster@{{fields.domain}} (if none of the other email addresses will forward to you).

Once you receive the validation email, you'll be able to use the "Certificates Wizard" tab on the StartSSL site.

  1. Select the Certificate Target called "Web Server SSL/TLS Certificate"
  2. On the Generate Private Key page, click "Skip »»"
  3. Paste in the contents of the {{fields.domain}}.csr file you created in the previous step.
  4. It should say Certificate Request Received. Click "Continue »»"
  5. On the Add Domains page, {{fields.domain}} is probably the only possible Domain selection, otherwise select {{fields.domain}}
  6. It will ask you what subdomain you want to use with this certificate (in addition to no subdomain). www is a typical choice.

When the signing is complete, it will show you a multiline textbox with the contents of your signed certificate. Save this in a file called {{fields.domain}}.crt

TODO: add remark about the certificate trust chain

4. Install the certificate on your server

You should now have the following two files (the other files aren't actually used in the encryption / decryption process, but useful to keep around):

Precisely how you use these depends on your application.

Suppose you want to use nginx, at least as your SSL termination point (which isn't a bad idea). Copy the key and certificate to your server, into these locations:

To serve static files from /var/www, use the following config file:

server { server_name {{fields.domain}}; listen 443 ssl; ssl_certificate /etc/nginx/certs/{{fields.domain}}.crt; ssl_certificate_key /etc/nginx/certs/{{fields.domain}}.key; location / { root /var/www; } }

The important bit are the ssl_certificate and ssl_certificate_key directives. You would use much the same configuration if you were back-proxying to some other application, just with a different location directive, e.g., location / { proxy_pass http://127.0.0.1:8080; }

Obligatory SSL configuration remark: for tighter security, include the following SSL-specific directives in your nginx configuration file:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA; ssl_prefer_server_ciphers on; ssl_session_timeout 5m; ssl_session_cache shared:SSL:50m; add_header Strict-Transport-Security "max-age=31536000";

Note that the StartSSL certificate has the expiration date set to a year from when StartCom generated it. If you want a longer-lasting certificate, consider the following alternatives:

5. Verification

You can use the following services to verify your configuration