software/ssl

SSL Notes

You can generate stong random strings with, eg: openssl rand -base64 24

Warning: as context, you generally need to go through an identity verification procedure before being issued SSL certificates other than the most trivial single-virtual-host kind. This process can take weeks, so start early!

Warning: the whole crypto thing is obviously pedantic and way more of a pain in the ass than needs to be.

Note: read this entire file before starting. In particular see the listing of host names towards the bottom, which should be kept up to date.

HOWTO: Get a new certificate and have it signed by StartSSL

Following the union of directions (dated Nov 16, 2009) at both: https://library.linode.com/security/ssl-certificates/subject-alternate-names https://library.linode.com/security/ssl-certificates/commercial

Run this (mostly) on the remote machine.

NB: it may or may not be necessary to do much of this because StartSSL will re-generate most fields? Ugh.

NB: if you are replacing an existing cert you need to revoke the old one first. This costs $25. “deal with it”.

Create, eg, /etc/ssl/localcerts/server_20140429.cnf, copying from /usr/lib/ssl/openssl.cnf. In that file, set the following at the top:

SAN="email:webmaster@example.com"

and after the ‘[ v3_ca ]’ line add:

subjectAltName=${ENV::SAN}

On the command line (edit these for the specific cert):

export SAN="DNS:example.com, DNS:www.example.com, DNS:mail.example.com, DNS:static.example.com, DNS:git.example.com, DNS:docs.example.com"
openssl req -new -newkey rsa:4096 -sha256 -days 729 -nodes -config /etc/ssl/localcerts/server_20140429.cnf -keyout /etc/ssl/localcerts/server_20140429.key -out /etc/ssl/localcerts/server_20140429.csr

fill in options exactly like on your startcom profile:

Country: US
State: Massachusetts
Locality: Cambridge
Organization Name: <your name>
Organization Unit: <blank>
Common Name: <FQDN, eg server.example.com>
Email: webmaster@example.com
Challenge password: <random string that you write down>
Company name: <blank>

When done, remove most permissions on all the resulting files:

chmod 400 *

Ok, now snarf down the resulting .csr to your local machine (it’s short, just ‘cat’ it).

On the StartSSL website, figure out how to use the toolbox and validations and all that jazz (come back in an hour), then once all that is configured start a certificate generation process. You get, eg, “example.com” automatically, even though this isn’t indicated anywhere. The user inteface sucks, “deal with it”. Save the resulting .crt to, eg, /etc/ssl/localcerts/server_20140429.crt. chmod it 400, root:root.

We need to create a “combined” certificate. Fetch the startssl intermediate and CA certs (WARNING: over https!), and combine a la:

wget https://startssl.com/certs/sub.class2.server.ca.pem
wget https://www.startssl.com/certs/ca.pem
mv ca.pem startssl_ca.pem
cat server_20140429.crt >> server_20140429.combined.crt
cat sub.class2.server.ca.pem >> server_20140429.combined.crt
cat startssl_ca.pem >> server_20140429.combined.crt

Now copy the .key to /etc/ssl/private, give it group “ssl-cert”, and give it chmod 440. Put the .combined.crt and .crt (for, eg, postfix) in /etc/ssl/certs and chmod it 444 (no group change).

Now edit nginx, prosody, postfix, dovecot, etc config and reboot and check logs and test everything to use the new keys. Whew!

Before you celebrate, add a calendar entry for N days before the expiration of the certificates you just created, so you have plenty of time to replace them before they expire.

example infrastructure needs

server: example.com www.example.com mail.example.com static.example.com git.example.com docs.example.com

References

https://library.linode.com/security/ssl-certificates https://www.ssllabs.com/ssltest/ https://www.ssllabs.com/projects/best-practices/

StartCom Alternatives

gandi.net: used by debian.org https://www.gandi.net/ssl/grid http://wiki.gandi.net/en/ssl/regenerate

CAcert installation instructions

https://wiki.cacert.org/FAQ/ImportRootCert#Debian https://wiki.cacert.org/FAQ/BrowserClients#Linux

nginx Config

ssl_protocols  TLSv1 TLSv1.1 TLSv1.2; # don’t use SSLv3 ref: POODLE  
ssl_prefer_server_ciphers on;
ssl_ciphers EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH+aRSA+RC4:EECDH:EDH+aRSA:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;

Then also:

openssl dhparam -out /etc/ssl/dhparam.pem 2048
chmod 600 dhparam.pem

And add:

ssl_dhparam /etc/ssl/dhparam.pem;

For old servers consider:

ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;

Check for CVE-2014-0224:

http://nginx.com/blog/nginx-05-june-2014-openssl-security-advisory/