Here are some (useful) notes about SSL and security with Nginx. This is just a collection of tips, nothing more…
For certificates for this and also other hosts, I signed up for StartSSL. In contrast to other providers, they offer a free SSL certificate for one domain plus subdomain. Before that, I had certs from CaCert which is also nice, but the root certificate is missing in all major browsers.
I won’t describe the actual process of how to get a certificate from StartSSL because the may change it over time. This is just about how Nginx works with SSL.
So now you have a certificate from $provider. For Nginx you have to create a chain with your private key, your certificate and the StartSSL cert, in that order. Because of this special format, I store all certificates Nginx is using in /etc/nginx/ssl
.
If you’ve done that, configuring Nginx to use it is fairly simple:
HTTPS is ready to go, but which ciphers are actually used? Nginx has the following default rules (Taken from http://wiki.nginx.org/HttpSslModule#ssl_ciphers):
List available ciphers:
Cipher list format explained: http://openssl.org/docs/apps/ciphers.html
If you’d like to see which cipher is negotiated between you and your host, openssl has a very nice way to do that. Just run
or, when you need to specify a hostname for SNI for example, run
Okay, so now we know which cipher is usually negotiated. But how are the “others” doing?
As one could see, different (default) cyphers are used for different reasons. It is always a tradeoff between performance and security.
The cypher kEDH
for example is known as a rather expensive one and many people disable it for this very reason. In some cases this would actually make sense, when you have to deal with lots of new connections and the host is at its limits.
Sessions (since SSLv2) allow to create connections with encryption keys based on the same key data. Once the (complete) negotiation was successful, further connections within the same session can use this data to calculate the encryption keys.
Nginx supports this:
HSTS (draft) is something like a permanent redirect to HTTPS: Once a user visits a website via HTTPS and receives a HSTS header, it declares itself that this site is only accessible over a secure connection. The next time, the user wants to access the site via HTTP, the browser automatically switchs to HTTP (unless the HSTS preference hasn’t expired). It only works with HTTPS, it is not allowed to send this header over HTTP.
Nginx configuration:
This header specifies how a site can be used in a frame. This is also a draft and should help against Clickjacking.