昨天偶然发现本站第一次访问时间非常的久,需要 6-7 秒的时间才能完全打开,但是第一次访问之后速度就非常快了,基本上是秒开。使用浏览器的开发者模式看了一下,发现是第一次 SSL 握手时间过长导致的访问缓慢,大约需要 3000-4000 毫秒才能完成握手。去网上搜集了一些资料,原来是 Let's Encrypt 证书的锅——Let's Encrypt OCSP 的服务器在国外,导致查询证书有效性的时间过长。开启 OCSP Stapling 将能很好的解决这个问题。
OCSP (Online Certificate Status Protocol), 也就是 TLS证书状态查询扩展,通常由证书签发机构 (CA)提供,用于在线实时验证证书是否合法有效,这样客户端就可以根据证书中的 OCSP信息,发送查询请求到 CA 的验证地址,来检查此证书是否有效。然而这些默认查询 OCSP的客户端在获得查询结果的响应前势必会一直阻塞后续的事件,在网络情况堪忧的情况下(尤其是 CA的服务器在国外)会造成较长时间的页面空白,使得用户体验相当糟糕。
OCSP Stapling 一般翻译为 OCSP装订,就是将查询 OCSP接口的工作交给服务器来做,服务器除了可以直接查询 OCSP信息,还可以仅进行少数次查询并将响应缓存起来。当有客户端向服务器发起 TLS握手请求时,服务器将证书的 OCSP信息随证书链一同发送给客户端,从而避免了客户端验证会产生的阻塞问题。由于 OCSP响应是无法伪造的,因此这一过程也不会产生额外的安全问题。所以在服务器上部署 OCSP装订,能大大缓解链接数与高并发量,省去多次握手操作,使网站访问速度更快。
由于本站运行在 Apache 下,以下记录为 Apache 开启 OCSP Stapling 的方法。
Step 1:
找到 Apache 的安装目录,打开 conf/extra 路径下的 httpd-ssl.conf,把 103 行和 109 行最前面的 # 号去掉取消注释开启 OCSP Stapling,112 行和 115 行参数可以选择性开启。
Step 2:
在 Apache 主配置文件 httpd.conf 中搜索 <IfModule ssl_module>(若搜不到就自己新建),在 <IfModule ssl_module> 标签内添加以下内容:
SSLUseStapling on SSLStaplingResponderTimeout 5 SSLStaplingReturnResponderErrors off SSLStaplingCache "shmcb:/www/server/apache/logs/ssl_stapling(32768)"
Step 3:
还是在 httpd.conf 中搜索 mod_socache_shmcb.so(一般在第 90 行左右)取消这一行的注释来开启这个模块。
至此我们的配置已经完成,重启 Apache 服务即可。下面我们来验证 OCSP Stapling 是否生效。
Step 4:
首先访问一下自己的网站,确保 OCSP 信息已经缓存到服务器上。前往 https://myssl.com/ssl.html,键入自己的网址,等待检测完成后在 “证书信息” 一栏查看 “OCSP 装订状态” 字段是否为 “正常”。若为 “不支持”,则 OCSP Stapling 并未生效,请检查配置过程是否有疏漏。
除此之外,还可以在终端键入以下命令来验证是否生效(记得把 yourdomin.com 改成自己的域名):
echo QUIT | openssl s_client -connect yourdomin.com:443 -status 2> /dev/null | grep -A 17 'OCSP response:'
若返回的 OCSP Response Status 为 successful,则配置生效;否则会提示 “OCSP response: no response sent” 。
配置成功后再进行加载速度测试,此时 SSL 握手时间从配置前的 3000-4000 毫秒降低至 30-70 毫秒,大大降低了网站首次加载的时间,可见配置 OCSP Stapling 的必要性。