OCSP是更轻量级的,因为它一次只获取一条记录。但是副作用是,当连接到服务器的时候,OCSP请求必须发送到第三方响应者,这增加了延迟,以及失败的可能。实际上,OCSP响应者由CA操控,由于它常常不可靠,导致浏览器由于收不到适时的响应而失败。这减少了安全性,因为它允许攻击者对OCSP响应者进行DoS攻击来取消验证。
nginx 配置文件
1 | ssl_dhparam /usr/local/nginx/ssl-key/dh_ssl/nginx.pem; |
配置项 说明
- ssl_dhparam
1
2
3所有的nginx版本在往Diffiel-Hellman输入参数时依赖OpenSSL。不幸的时,这就意味着Ephemeral Diffiel-Hellman(DHE)会使用OpenSSL的这一缺陷,包括一个1024位的交换密钥。由于我们正在使用一个2048位的证书,DHE客户端比非ephemeral客户端将使用一个更弱的密钥交换。
我们需要产生一个更强的DHE参数:
1 |
|
ssl_certificate
1
网站证书
ssl_certificate_key
1
证书私钥
ssl_trusted_certificate
1
2
3OCSP是更轻量级的,因为它一次只获取一条记录。但是副作用是,当连接到服务器的时候,OCSP请求必须发送到第三方响应者,这增加了延迟,以及失败的可能。实际上,OCSP响应者由CA操控,由于它常常不可靠,导致浏览器由于收不到适时的响应而失败。这减少了安全性,因为它允许攻击者对OCSP响应者进行DoS攻击来取消验证。
解决方案是在TLS握手期间,允许服务器发送缓存的OCSP记录,这样来绕过OCSP响应者。这个技术节省了在客户端和OCSP响应者之间的一个来回,称为OCSP闭合(OCSP Stapling)。
检查ocsp 是否开启
服务端启用 OCSP Stapling 之后,客户端还需要在建立 TLS 时,在 Client Hello 中启用 status_request 这个 TLS 扩展,告诉服务端自己希望得到 OCSP Response。目前主流浏览器都会带上 status_request,而在 openssl 中需要指定 -status 参数。完整命令如下:1
$ openssl s_client -connect imququ.com:443 -status -tlsextdebug < /dev/null 2>&1 | grep -i "OCSP response"
- 如果你的服务器上部署了多个 HTTPS 站点,可能还需要加上 -servername 参数启用 SNI:
1
$ openssl s_client -connect imququ.com:443 -servername imququ.com -status -tlsextdebug < /dev/null 2>&1 | grep -i "OCSP response"
如果结果是下面这样,说明 OCSP Stapling 已开启:1
2
3
4OCSP response:
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
而这样显然是未开启:1
OCSP response: no response sent
获取证书 OCSP Response
了解如何通过 openssl 验证 OCSP Stapling 状态后,我们再来看看 OCSP Response 的完整内容,去掉前面命令中的 grep 就可以看到。例如这是本站的:
1 | $ openssl s_client -connect imququ.com:443 -status -tlsextdebug < /dev/null 2>&1 |
可以看到 OCSP Response 由两部分组成:OCSP Response Data 和 Certificate。OCSP Response Data 是本站证书的验证信息;而 Certificate 则是用来验证 OCSP Response Data。本例中的 Certificate 的 Common Name 是 RapidSSL SHA256 CA - G4 OCSP Responder,可以看出它专属于 RapidSSL 的 OCSP 服务。后面我们会发现,并不是每一家 CA 的 OCSP Response 都会提供 Certificate 信息。
上面这段 OCSP Response 信息是通过服务端 OCSP Stapling 获取的。下面介绍如何通过 openssl 在本地获取证书 OCSP Response。
首先需要准备好待验证网站证书链上的所有证书。证书链一般由根证书、一个或多个中间证书、站点证书组成。根证书内置在操作系统或浏览器内(Firefox),可以直接导出,或者去各大 CA 官方下载;中间证书、站点证书在建立 TLS 连接时由服务端发送,可以这样获取: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$ openssl s_client -connect imququ.com:443 -showcerts < /dev/null 2>&1
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., OU = (c) 2008 GeoTrust Inc. - For authorized use only, CN = GeoTrust Primary Certification Authority - G3
verify return:1
depth=1 C = US, O = GeoTrust Inc., CN = RapidSSL SHA256 CA - G4
verify return:1
depth=0 CN = www.imququ.com
verify return:1
---
Certificate chain
0 s:/CN=www.imququ.com
i:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G4
-----BEGIN CERTIFICATE-----
MIIFMDCCBBigAwIBAgICWiYwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCVVMx
... ...
fBv5YysJ/pgFe75P9RVALMiPUPHvH2FGI47pxlvzs5+7Gt2p
-----END CERTIFICATE-----
1 s:/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G4
i:/C=US/O=GeoTrust Inc./OU=(c) 2008 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G3
-----BEGIN CERTIFICATE-----
MIIEpjCCA46gAwIBAgIQKByJKWYUQ4BCY1U6MkCuszANBgkqhkiG9w0BAQsFADCB
... ...
nPvdJAq9WZFKQgM4EnEyiHagjny7Mu+IKhvUam9QuVJni6sw+h/94ySa
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=www.imququ.com
issuer=/C=US/O=GeoTrust Inc./CN=RapidSSL SHA256 CA - G4
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3460 bytes and written 434 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES128-GCM-SHA256
Session-ID: B6A0F49F6DAD0BD8AFB63F87D134FFCBC2B1487CD81440C26D165B5738A5C3EC
Session-ID-ctx:
Master-Key: 72871B14BC37B08F51F818285264169C512B865D13839C9B824175115F008801781FBAC64D01FC76376BCAB85E6B8F84
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
TLS session ticket lifetime hint: 86400 (seconds)
TLS session ticket:
0000 - 56 f8 0d dd 0e ea 7d 0b-09 70 0b dd 52 da b7 a8 V.....}..p..R...
... ... ... ...
00a0 - c2 25 af a9 46 69 64 73-69 16 ea 64 94 c7 f4 a4 .%..Fidsi..d....
Start Time: 1457861201
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
DONE
以上内容中 Certificate Chain 这一节,编号为 0 的证书是站点证书;编号为 1 的证书是中间证书。我的证书链一共是三级,服务端只需要发送两个证书,对于四级证书链,服务端就需要发送三个证书了。总之,只有根证书无需发送。
将站点证书保存为 site.pem;中间证书保存为 intermediate.pem(如果有多个中间证书,按照子证书在上的顺序保存);再从系统中导出对应的根证书存为 root.pem。这样,证书链上的所有证书都搞定了。为了确保无误,建议再验证一下每个证书的 Common Name:
1 | $ openssl x509 -in site.pem -noout -subject |
接着,获取站点证书的 OCSP 服务地址:1
2$ openssl x509 -in site.pem -noout -ocsp_uri
http://gz.symcd.com
错误
1 | Error querying OCSP responsder |
需要参数
-header “HOST” “ocsp.int-x3.letsencrypt.org”
验证方式
1 | openssl ocsp -no_nonce -issuer intermediate.pem -cert ../_.yd.cc/STAR.yd.cc.crt -CAfile chain.pem -text -url http://ocsp2.globalsign.com/gsdomainvalg2 -header Host ocsp2.globalsign.com |
HA 证书
HA 证书 = 证书.cer + 证书.key
ginx开启ssl_dhparam
参考文档: https://weakdh.org/sysadmin.html
一般地,Nginx 会使用来自 Openssl 默认的 DHE 参数 (Ephemeral Diffie-Hellman),其加密性能弱。我们可以在终端命令生成一个新的来代替它。1
2shell> mkdir /etc/letsencrypt/dh_ssl && cd /etc/letsencrypt/dh_ssl
shell> openssl dhparam -out xxx.com.pem 2048