自从全球开始推网站必须要支援 SSL (https) 加密之后,我就到 startssl.com 申请了一个免费的 SSL Certificate ,用了一阵子发现,只要用 HTTPS 打开我的个人网站,就有一定的机率会很慢,大约要等待 30 秒左右页面才会下载完成,奇怪的是只要成功打开过一次页面,接下来的页面就不会再卡这么久了,我一直怀疑是 SSL 的关系,但又没办法肯定。
Chrome console tool 是一个很强力的工具,它可以检测整个网页的传输过程,我使用它来测试我的网站连线资讯,先打开 chrome console toole ,然后再用 HTTPS 连到我的个人网站,结果在 Console Tool 中看到 " initial connection SSL" 的等待时间很长,甚至会超过 30 秒,我几乎可以肯定这个 SSL 连线一定有问题。

OCSP
在网路上看了一些相关文章,猜测可能是 OCSP (online certificate status protocol) 这个功能造成我的网站特别的慢。
OCSP 是什么呢? 他存在的目地是为了加快 SSL certificate 验证的效率,OCSP 是指我们 server 端暂存一份从 certificate authority 给我们的凭证的资料,当 user 透过浏览器要跟 Server 做 SSL handshake 时, Server 端可以立马用这个暂存的 Certificate 回传给 User ,告知 user 我们家的凭证状态 ,以便加快 SSL handshake 的速度,如果没有 OCSP ,那么 User 要再发一次 Request 到 CA 端,跟发凭证商要你的 Certificate 状态,因为我的网站没有实作 OCSP ,所以当 client 拿到 OCSP 验证结果时,就会转向 CA 商要求凭证,造成网页变得很慢很慢。
如何检查你的 OCSP 是否有开启
https://www.digicert.com/help/ 这个网站可以帮助我们检查网站是否有支援 OCSP ,例如我输入我的网站 domain: www.puritys.me,结果得到 OCSP Staple: Not Enabled ,代表我的网站不支援 OCSP 。

另外我们也可以用 Command line script 的方式来检查是否有启用 OCSP,如果看到 "OCSP response: no response sent" ,就代表 ocsp 没有成功。
- openssl s_client -connect www.puritys.me:443 -status 2> /dev/null
启用 OCSP on Apache Server
启用 OCSP 的方式很简单,你只要在 httpd.conf 加入以下设定,然后再重启 apache 即可,接著你可以用上面讲的两个方式来测试是否有正确启用 OCSP ,要注意的是 OCSP 是使用 80 port 来做连线,所以你不要像我一样,一开始不知道将 " SSLUseStapling on" 设定在 443 port ,结果找半天一直找不到原因。
- <IfModule ssl_module>
- SSLUseStapling on
- SSLStaplingResponderTimeout 5
- SSLStaplingReturnResponderErrors off
- SSLStaplingCache shmcb:/var/httpd/stapling_cache(128000)
- </IfModule>
成功启用 OCSP 后,你会看到 OCSP Staple 显示 "Good" 不在是 "Not Enabled" 。
OCSP Debug
- OLDIFS=$IFS; IFS=':' certificates=$(openssl s_client -connect www.puritys.me:443 -showcerts -tlsextdebug -tls1 2>&1 </dev/null | sed -n '/-----BEGIN/,/-----END/ {/-----BEGIN/ s/^/:/; p}'); for certificate in ${certificates#:}; do echo $certificate | openssl x509 -noout -ocsp_uri; done; IFS=$OLDIFS
- // http://ocsp.startssl.com
上面这行指令是用来找出你的 OCSP host,你必需确认你的 Server 与 OCSP host 之间的网路连线是通畅的,例如使用 telnet ocsp.startssl.com 80 来试试看 tcp 连线。
- openssl ocsp -issuer key/chain.crt -cert key/site.crt -text -url http://ocsp.startssl.com -CAfile key/root.crt -nonce
上面的指令是用来测试你的 server 是否可以从 CA 商拿到 OCSP 凭证 ,我的 SSL 凭证是跟 startssl 申请的,所以 CA 端 ocsp 网址为 http://ocsp.startssl.com ,是 http 喔不是 https !!
如果你有看到 "OCSP Response Status: successful " ,代表可以从 CA 端拿到正确的 ocsp 。
参考文章
- What is OCSP https://en.wikipedia.org/wiki/OCSP_stapling
- https://www.ssllabs.com/ssltest/analyze.html
- ocsp debug: https://raymii.org/s/articles/OpenSSL_Manually_Verify_a_certificate_against_an_OCSP.html
- openssl cookbook: https://www.feistyduck.com/library/openssl-cookbook/online/ch-testing-with-openssl.html
- SSL 漏洞 : https://www.sslbuyer.com/index.php?option=com_content&view=article&id=177:fix-ssl-vulnerabilities&catid=25&Itemid=2595