Nginx, Jessie, StartSSL, and the quest for A+

I don’t have time at the moment to fix it.


I like to keep things as secure as I can, and I also have my own webserver running at home.
I’m too cheap to actually pay for my SSL-certificate, so therefore I use StartSSL which offers one for free.
The signup-process is well documented elsewhere, note that they do require a phone number, but I have yet to be called or otherwise contacted by them.

So, without further intro:
:~# mkdir -p /etc/nginx/ssl/csr && cd /etc/nginx/ssl/csr

:~# openssl genrsa -out private.key 4096

Remember that common name, CN, needs to be hostname of website you will use it for.
:~# openssl req -new -key private.key -out request.csr

Go to, select the control panel, select authenticate, verify certificate if needed.
If you have verified your domain, go straight to “Certificates Wizard”, otherwise choose “Validations Wizard”, select “Domain Name Validation” and follow the wizard. When done, go back here and select “Certificates Wizard”.

Choose “Web Server SSL/TLS Certificate”, click Continue.

Under “Generate Private Key”, choose Skip, we are going to use the certificate we already created.

:/etc/nginx/ssl/csr# editor request.csr

Mark all the text, from the line containing BEGIN CERTIFICATE REQUEST to the line containing END CERTIFICATE REQUEST.
Paste the output into the field on Startssl-page, and press Continue.

Under “Certificate Request Received”, press Continue.

Under “Add Domains”, select the top domain you want to use with your ssl-certificate.
Note that you can only select domains validated the last 30 days, and that you select the top-domain even if you are going to use a sub-domain, press continue.
On the next screen you input the desired subdomain, you have to enter something.
You can for example input www here, the top-domain will be in the Alternate name anyway, so they will both validate. Press Continue.

Under “Ready Processing Certificate”, verify your settings and press Continue.

If you get an “Additional Check Required!”, it’s just a matter of waiting for an email.

When you get an email, go to your control panel on StartSSL, select “Tool Box” and press “Retrieve Certificate”.
Select the correct Certificate, and double check the expiry date, then press Continue.
Copy everything in the box.

:/etc/nginx/ssl/csr# editor signed.crt

Paste the contents from the box, and save the file.

:/etc/nginx/ssl/csr# wget
:/etc/nginx/ssl/csr# wget
:/etc/nginx/ssl/csr# cat >> ca-sha2.pem
:/etc/nginx/ssl/csr# cat signed.crt ca-sha2.pem > hostname.crt
:/etc/nginx/ssl/csr# cp hostname.crt ../
:/etc/nginx/ssl/csr# cp private.key ../
:/etc/nginx/ssl/csr# cd ..
:/etc/nginx/ssl/csr# chmod -R 400 csr/
:/etc/nginx/ssl/csr# chmod 400 private.key
:/etc/nginx/ssl# openssl dhparam -out dhparams.pem 4096

Now this takes care of your certificate, and protects against logjam-attack.
But configuration is still needed, so here that is:

:/etc/nginx/ssl# editor /etc/nginx/sites-available/default

Make sure the following is configured:
listen 443 ssl spdy;  # Spdy is not mandatory, but it speeds up clients who support it.
server_name hostname;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/hostname.crt;
resolver valid=300s; #OpenDNS DNS-IP’s, substitute with the servers local DNS-servers, or simply comment it out to let the server handle it itself. (It’s the server that does the requests, not the client.)
resolver_timeout 10s;
ssl_dhparam /etc/nginx/ssl/dhparams.pem;
ssl_certificate /etc/nginx/ssl/hostname.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 24h;
ssl_buffer_size 1400;
ssl_session_tickets off;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers ‘AES256+EECDH:AES256+EDH:!aNULL’; #This will sacrifice some old clients, I don’t mind.
add_header Strict-Transport-Security max-age=15768000;
add_header X-Content-Type-Options nosniff;

Save the file, test config with:
:/etc/nginx/ssl# nginx -t
And if all is well, restart with:
:/etc/nginx/ssl# service nginx restart (I’m guessing a reload would also do though…)

Now go here and test:

As of 2015-07-08 this gave me A+.