提醒:本文最后更新于 1674 天前,文中所描述的信息可能已发生改变,请仔细核实。
OCSP(Online Certificate Status Protocol,在线证书状态协议)可以理解为是一个在线查询接口,客户端(如浏览器)可以通过它实时查询单个证书的合法性(多为确认证书是否被作废)。
使用“OCSP Stapling”主要是为了某些客户端会在TLS握手阶段进一步协商时,实时查询OCSP接口,并在获得结果前阻塞后续流程,这对握手效率影响很大。而OCSP Stapling是指服务端在证书链中包含颁发机构对证书的OCSP查询结果,从而让客户端跳过验证的过程。(工作流程参考上图)
OCSP响应本身经过了数字签名,无法伪造,所以OCSP Stapling既提高了握手效率,又不会影响安全性。对外提供访问的网站是比较推荐开启的。
但因为Nginx在实现OCSP Stapling这部分逻辑时,直接使用了OpenSSL库,使得Nginx使用BoringSSL时便不支持OCSP Stapling。
那么如何解决这个问题呢?
首先需要个Patch,早在2018年,热心网友Carter Li便在我的Patch项目中提供了补丁来解决这个问题。它为Nginx添加了使用ssl_stapling_file
参数给BoringSSL提供OCSP stapling支持。
这个Patch的传送门。为Nginx打上补丁后,使用BoringSSL即可通过指定ssl_stapling_file来支持OCSP stapling。
但这又产生了新的问题,OCSP stapling file需要手动创建,而且是有有效期。你需要不断更新,以确保客户端不会读取到过期的数据。虽然有效期有一周,但也较为麻烦,带来了不必要的工作量。
所以我写了个shell脚本,如下。利用at(一个cron应用)来自动更新OCSP stapling file。
#!/bin/sh
openssl ocsp -no_nonce \
-CAfile /path/to/root.crt \
-VAfile /path/to/root.crt \
-issuer /path/to/issuer.crt \
-cert /path/to/server.crt \
-respout /path/to/ocsp.resp \
-url "$(openssl x509 -in /path/to/bundle.crt -text | grep "OCSP - URI:" | cut -d: -f2,3)" \
> /tmp/ocsp.reply 2>&1
at $(date -d "$(cat /tmp/ocsp.reply | grep 'Next Update: ' | awk -F': ' '{print $2}') + 1 minutes" +"%H:%M %Y-%m-%d") < ~/ocsp.cron.sh
service nginx reload
exit
其中:
1.~/ocsp.cron.sh
为本脚本具体位置。
2./path/to/root.crt
为你所申请证书的Root CA证书。
3./path/to/issuer.crt
为你所申请证书的中间链证书。
4./path/to/server.crt
为你所申请的证书。
5./path/to/bundle.crt
为你所申请含中间链的证书(issuer.crt与server.crt合并可得)。
6./path/to/ocsp.resp
为你给Nginx ssl_stapling_file参数指定的OCSP响应文件。
以上,请按照你的实际存储位置、文件名字、具体情况更改。
脚本主要作用是生成ocsp.resp为Nginx所用,并且在产生文件时,以OCSP回应的过期时间+1分钟创建定时任务重建ocsp.resp并产生新的计划任务后重启Nginx。也就是说至多有一分钟,你的OCSP stapling file是过期的,但这保证了重建成功。
启动服务器后,脚本一次运行后就可以不管了,自动循环创建任务,高效快捷(王婆卖瓜)。可以通过添加脚本到系统自启动,达到无感体验。(AT重启后也能任务保持,不需要添加脚本到自启动,只需要运行一次即可)
定时任务使用到了at,可以通过包管理直接安装。
Nginx的配置中只需要增加一行:
ssl_stapling_file /path/to/ocsp.resp;
即可完成(记得根据实际位置和文件名字,修改路径)。
需要注意的是,指定OCSP stapling file的方式仅支持单证书(无法同时支持RSA/ECC双证书)。
更多关于OCSP的知识,可以看屈哥博客的这篇文章:《从无法开启 OCSP Stapling 说起》。
转载请注明转自:kn007的个人博客的《让Nginx使用BoringSSL时支持OCSP Stapling》
《更新到支持OCSP的BoringSSL》
@一曲长歌辞烟雨: 卧槽。。这也行
@kn007: 问下这个版本是哪个版本啊。。。我试了最新版还是不支持的啊
@Zxilly: 啥,什么意思?
原版使用Boringssl的Nginx(也可以是打上quiche等patch的nginx),然后再打这个patch和使用脚本即可
更新到BoringSSL下支持OCSP
OCSP封套这个东西,如果不手动更新的话,Nginx获取它是异步的,解决方法看来只能用脚本了
@云间守望: 是的。
不是,你怎么也更新至
@云间守望: 因为我看到了这个
https://boringssl.googlesource.com/boringssl/+/103ed08549a74af9f03363c633028faf9a475066%5E%21/
按照这个的说法,BoringSSL应该是已经支持了OCSP啊。。。
然后我这句的意思是,上面那位不是回复说“更新到支持OCSP的BoringSSL”嘛,但是我试了最新的版本还是报个`nginx: [warn] "ssl_stapling" ignored, not supported`
@Zxilly: 你这回复哪里回复谁呢。。。。
文章正文,能认真看下么。。。
“但因为Nginx在实现OCSP Stapling这部分逻辑时,直接使用了OpenSSL库,使得Nginx使用BoringSSL时便不支持OCSP Stapling。”
@kn007: 你这回复点那个按钮的时候会跳一下。。。
@Zxilly: 对,会跳转,但是如果没点错,是不会跑错的。。。
我回头改下逻辑吧
您可以显示一个使用“ LetsEncrypt”执行此操作的示例吗?
如果可能,请使用2“ nginx_vhost”。
非常感谢!
问一下,CloudFlare的QUIC实现是不是和谷歌chromium那个不一样啊,感觉chrome好像不支持的样子
@Zxilly: 不一样,可以支持
@Zxilly: 因为你想的是quic,但其实我们说的是http3
大佬,为什么使用火狐浏览时会出现“MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING”错误?显示“建立安全链接失败,链接到 XX 时发生错误,该 OCSP 响应不包括该证书被验证的状态。”。我在ssllabs网址测试的时候在“OCSP stapling”这一栏里显示“Invalid No response provided”。奇怪的是我另外一个域名同样的配置却不会出现这个错误
@cyetus: letsencrypt?重新颁发一次,可能可以解决
@kn007: 卧槽大佬回复好快。是letsencrypt证书,重新颁发是指颁发证书还是那个ocsp文件?
@cyetus: 证书问题,letsencrypt的ocsp有问题。你可以搜一下。。
@kn007: 感谢大佬,重新颁发一次证书可以访问了。话说出现这种问题只能重新颁发证书吗?我记得我刚开始使用大佬的脚本的时候OCSP还是正常的,然后过了几天我偶然在ssllabs测试一下才发现OCSP出问题了。此外,大佬的nginx patch有打算支持nginx-quic这个分支嘛?
@cyetus: letsencrypt颁发的证书有一定几率出问题,在ocsp上。
nginx-quic还没研究,可能不会,因为目前还不成熟。