summaryrefslogtreecommitdiffstats
path: root/software/ssl.page
blob: 04129a4638875f77debb9e07b99864db09e0ec92 (plain)
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

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;