aboutsummaryrefslogtreecommitdiffstats
path: root/posts/https.md
blob: a2db107cfef7068f181187ff0d976509382bbddf (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
---
title: HTTPS
published: 2015-07-21
modified: 2015-07-21
---

**Update** (2015-07-21): fix the link to the Apache configuration file.
    
This document will not explain why to use HTTPS for your site, but assume you
are already convinced :-)
  
### Certificate Authority
    
So if you want to do HTTPS everyone focuses only on the certificate and the 
costs, but the costs seem to be going down or reach zero in some cases, 
although that can be treacherous in some cases, like StartSSL. Personally 
I've used [https://namecheap.com](https://namecheap.com), because at 
the time they were one of the cheaper ones that supported SHA-256 for signing 
the certificates. I do not recommend to use 
[StartSSL](https://startssl.com) because they have a ridiculous 
policy regarding revoking certificates. You have to pay to revoke. This is SO 
bad, and considering you may require revocation at some point because someone 
compromised your server... not a great prospect. You can also use [CAcert](http://cacert.org) (not recommended), or wait for [Let's Encrypt](https://letsencrypt.org/).
    

### Generating the signing request
    
Many tutorials only tell you to do the wrong thing. Either they are old, or 
obsolete or do crazy things. It is important to generate the private key on a 
physical device, e.g. your laptop, as virtual machines potentially have bad 
random due to the lack of entropy.
    
Below is the procedure I used for [IndieCert](https://indiecert.net). 
To generate the private key:
   
```
$ openssl genrsa -out indiecert.net.key 2048
```
    
Create a file `indiecert.net.cnf` containing the following:
    
```
[req]
prompt = no
distinguished_name = distinguished_name

[distinguished_name]
CN = www.indiecert.net

[v3_req]
subjectAltName = DNS:www.indiecert.net, DNS:indiecert.net
```
 
Now generate the CSR:
    
```
$ openssl req -sha256 -new -reqexts v3_req -config indiecert.net.cnf -key indiecert.net.key -out indiecert.net.csr
```
    
Because OpenSSL (and the config) is so tricky to get right, also here the output 
of the CSR in "human readable" form:

```
$ openssl req -in indiecert.net.csr -noout -text
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: CN=www.indiecert.net
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: <strong>(2048 bit)</strong>
                Modulus:
                    00:b8:fa:6b:12:e8:50:c8:22:db:ea:2e:1a:99:dc:
                    8d:45:ff:89:ac:c8:1d:6d:02:25:ff:17:fa:4b:67:
                    00:28:39:16:82:12:e1:82:52:ae:06:1b:2a:6f:2f:
                    af:bd:a5:41:46:91:86:81:67:02:50:fc:f8:44:a7:
                    67:66:e2:69:48:08:e1:25:8a:2d:c0:b1:8e:b7:05:
                    f3:7f:ab:68:0e:46:41:5a:f3:e2:dd:c8:60:70:c4:
                    9a:4b:e7:34:1b:8c:07:5d:da:72:42:1a:ee:8e:4b:
                    ce:ec:da:6e:3e:b7:b2:b9:d2:41:78:09:ad:4d:3a:
                    8a:ab:51:ec:32:9d:7b:ba:c5:3d:81:c4:11:78:8c:
                    e4:04:ef:67:24:88:f2:28:33:c8:71:1c:e2:c6:f2:
                    38:2e:57:6c:94:6f:f8:a9:fd:4d:4a:67:29:d9:2e:
                    3c:7e:11:1a:cf:39:d2:e2:89:11:38:6a:09:10:36:
                    8c:93:04:28:79:f7:a7:f4:5c:8f:f3:2e:2c:0a:a5:
                    90:74:cb:63:4a:c8:d9:d2:1d:ab:4b:6a:1e:eb:f1:
                    8e:85:f4:5b:90:1c:51:d5:df:b1:82:6c:b2:a6:d0:
                    7e:01:0b:44:ec:96:3e:2d:0f:6e:87:21:2d:70:26:
                    b6:3a:f5:81:e4:a8:2d:b4:ca:8a:d3:29:ad:0f:c3:
                    9d:49
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name: 
                DNS:www.indiecert.net, DNS:indiecert.net
    Signature Algorithm: <strong>sha256WithRSAEncryption</strong>
         52:f7:9d:14:b4:43:de:52:0b:6f:aa:ff:7a:32:cf:ca:5e:6c:
         09:94:32:02:77:8c:ed:03:07:6e:e6:d4:a8:12:74:21:fb:bc:
         a8:e5:ac:c4:af:6a:df:86:c0:05:07:3c:9e:53:de:ab:bb:37:
         55:2a:f3:f8:1d:fe:6e:92:21:44:bb:3e:c4:a9:fe:a4:4d:f4:
         68:1d:6b:fe:59:ea:95:d6:4f:2b:9f:cc:f9:0d:a2:7e:e0:96:
         8d:32:8b:1c:39:d4:b6:b2:6e:70:98:b2:c1:da:df:5f:72:e2:
         50:0a:54:08:05:f7:82:23:8f:89:4f:94:c4:0c:a1:7b:33:cc:
         ed:0f:5d:87:ed:98:64:e7:b2:ef:1f:12:08:6c:8a:6e:dc:d2:
         85:f9:77:ec:77:ce:53:63:a7:21:37:21:53:51:cb:7e:a8:d3:
         a5:e6:43:e2:96:de:10:83:e4:8a:8a:05:1d:5f:65:31:8d:d1:
         8c:8d:2f:9e:04:1c:9e:d5:c9:88:40:eb:7d:7d:34:8d:43:37:
         71:d9:fd:45:34:4a:b2:c2:80:0f:85:2d:ed:5c:0d:5d:ef:ae:
         3b:94:ea:3a:ea:3b:ad:f3:90:46:6e:a6:4a:d6:c7:57:36:3a:
         c2:71:ef:f7:d8:8d:cc:16:c1:2f:6f:ca:3f:bb:e0:2d:73:bc:
         04:59:89:07
```
    
It is important to make sure you have at least an 2048 bits public key, and
that SHA-256 was used for the signature. This will in most cases trigger the 
CA to also use SHA-256 if they still support SHA-1 as well.

Most CAs will override the CN and the Subject Alternative Name in most cases,
but it doesn't hurt to get it right yourself :-)

## CA procedure
    
The CA will now take this CSR and sign it and send you a signed certificate and
also in most cases a certificate chain:

```
$ openssl x509 -inform PEM -in www_indiecert_net.crt  -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            f1:ce:c2:0e:e7:b4:2f:d8:c4:a5:78:c5:e9:f5:4b:07
    Signature Algorithm: <strong>sha256WithRSAEncryption</strong>
        Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Domain Validation Secure Server CA
        Validity
            Not Before: Feb 18 00:00:00 2015 GMT
            Not After : Feb 18 23:59:59 2016 GMT
        Subject: <strong>OU=Domain Control Validated, OU=PositiveSSL, CN=www.indiecert.net</strong>
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:e1:4c:bd:f2:03:cb:cd:d9:33:b4:56:c4:a3:52:
                    2d:47:4e:1a:df:5a:8b:9e:75:01:51:29:9a:37:83:
                    63:d5:44:b4:6d:fa:b2:c1:a4:97:76:44:b1:f3:e6:
                    96:8f:40:40:85:fe:04:f6:04:65:ae:8d:e1:79:60:
                    32:eb:21:6f:8b:9c:85:2d:d9:38:aa:ea:7c:50:d0:
                    fd:25:29:a3:16:ef:c5:d1:ae:bc:0f:7d:82:41:8e:
                    cb:df:d2:da:41:4d:fd:2e:4c:4c:7f:32:aa:7a:10:
                    aa:73:99:21:f3:e1:a1:14:7b:5a:ca:f9:69:87:b1:
                    35:6f:86:56:6a:54:57:1d:8b:fd:1f:7a:56:d3:44:
                    67:54:99:8d:8c:70:2c:ba:4c:00:ff:6b:a4:0b:bf:
                    0e:c9:dc:b9:ea:bb:0c:9e:a5:02:b2:c9:34:4e:e2:
                    34:be:7f:e5:a5:e5:ed:d0:97:7f:6c:c0:aa:a9:b8:
                    24:76:78:12:49:e5:a5:f8:08:71:3f:55:d4:21:04:
                    7c:c0:5c:31:20:87:29:5e:a1:bd:b1:7d:63:e9:3f:
                    0e:f2:a8:fb:1f:d8:e8:51:0f:89:84:dc:5d:da:7a:
                    69:a5:cd:48:ba:39:63:d8:ae:39:29:cd:a7:8f:94:
                    06:9a:7f:da:c7:b6:f4:71:a1:58:03:ef:10:b4:22:
                    a1:7f
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Authority Key Identifier: 
                keyid:90:AF:6A:3A:94:5A:0B:D8:90:EA:12:56:73:DF:43:B4:3A:28:DA:E7

            X509v3 Subject Key Identifier: 
                FD:00:76:8D:04:A1:3E:B1:41:2B:49:8A:D1:CD:93:89:32:3C:38:B5
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Certificate Policies: 
                Policy: 1.3.6.1.4.1.6449.1.2.2.7
                  CPS: https://secure.comodo.com/CPS
                Policy: 2.23.140.1.2.1

            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://crl.comodoca.com/COMODORSADomainValidationSecureServerCA.crl

            Authority Information Access: 
                CA Issuers - URI:http://crt.comodoca.com/COMODORSADomainValidationSecureServerCA.crt
                OCSP - URI:http://ocsp.comodoca.com

            X509v3 Subject Alternative Name: 
                <strong>DNS:www.indiecert.net, DNS:indiecert.net</strong>
    Signature Algorithm: <strong>sha256WithRSAEncryption</strong>
         69:c1:22:36:c1:2b:5d:43:34:c0:d7:a6:06:03:53:02:f4:85:
         ee:29:72:c2:82:37:56:af:ba:f8:1e:c9:2c:bf:da:fb:38:47:
         43:8d:c1:d3:94:48:b3:49:41:1c:f5:89:7c:97:23:88:0a:b3:
         cb:47:28:13:a2:a7:d2:d2:3c:40:5b:1b:8b:98:ae:70:4c:ea:
         67:77:e1:b8:d4:de:c7:0e:fd:09:ff:56:72:a8:30:eb:0d:0a:
         87:fe:2c:3f:9d:2e:7a:e3:de:47:22:79:dd:2a:58:da:38:78:
         14:2b:70:95:ee:8b:ce:9c:78:b0:ce:a7:cb:27:dd:98:36:f8:
         b4:f8:4c:44:35:b9:9d:d4:8c:cc:5b:c6:48:6e:25:12:e3:ce:
         9e:40:c7:c4:b9:d1:23:6b:93:83:e2:4e:29:7e:10:1a:31:72:
         d0:a0:24:97:3d:ea:b1:89:27:0b:49:0c:33:c7:ff:f2:e9:cb:
         4b:fe:a7:0a:10:c3:11:65:dc:f0:4a:07:32:63:d4:73:d5:30:
         77:9d:f4:fc:d3:51:04:11:51:af:8d:f6:37:d1:de:61:3c:74:
         5d:6a:64:f0:c6:99:45:21:1e:44:1c:01:61:99:3e:c1:a7:e4:
         a0:d1:39:f0:56:33:e6:7b:db:6d:22:73:c4:7f:d0:22:2e:54:
         93:0e:59:e4
```

### Installation
    
Now you can use the certificate, the key and the certificate chain and 
configure them in your web server. If you run your own server you SHOULD use
Mozilla's [configuration generator](https://mozilla.github.io/server-side-tls/ssl-config-generator/) to make sure you configure your server in a secure way. 
    
If you use some virtual hosting provider, like e.g. [Uberspace.de](https://uberspace.de) you can probably upload your key, certificate and chain using SSH and instruct them to configure the certificate for you.

### Validation
    
This is where most people stop. They will never validate their configuration
and make sure SSLv3 is disabled, the chain is configured properly or the 
weak ciphers are disabled. 
        
Go to [SSL Server Test](https://www.ssllabs.com/ssltest/) provided
by Qualys. Enter your domain name and check the results. If you do not
get a rating A or A+ you are doing something wrong and should evaluate the 
results of the test. As an example, you can view the IndieCert [report](https://www.ssllabs.com/ssltest/analyze.html?d=indiecert.net&hideResults=on).
    
If you prefer a free software solution you can also look at [SSL Decoder](https://tls.so/). But it is advisable to also check using the Qualys tool mentioned above.

### Next Steps
    
Now that the basics are done, you should not stop here, but consider a few 
other things:
    
- [HTTP Strict Transport Security](https://developer.mozilla.org/en-US/docs/Web/Security/HTTP_strict_transport_security)
- [OCSP Stapling](https://wiki.mozilla.org/Security/Server_Side_TLS#OCSP_Stapling)
- [Add to HSTS preload list](https://hstspreload.appspot.com/)
- [Public Key Pinning](https://developer.mozilla.org/en-US/docs/Web/Security/Public_Key_Pinning)

### What did I do so far?

For IndieCert I followed most of these steps, but didn't get around to 
implementing Public Key Pinning yet. You can check the Apache configuration I 
use [here](https://github.com/fkooman/indiecert/blob/master/docker/indiecert.example-httpd.conf).