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/