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: Organization Unit: Common Name: Email: webmaster@example.com Challenge password: Company name: 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/