1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
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/
|