标签归档:tls

Nginx正确配置SSL OCSP Stapling服务

当我们通过HTTPS访问网站的时候,客户端(浏览器或其他设备)会首先通过证书颁发机构的证书吊销列表(CRL)或者数字证书在线状态协议(OCSP)记录验证网站服务器的证书是否有效。前一种验证方式是最低效的,CA会不断向CRL文件添加证书吊销记录,CRL文件就会变得越来越大,客户端在验证前就需要耗费越来越长的时间来下载CRL文件。

相比CRL验证方式,OCSP就更加高效,OCSP每次只查询并获取一条记录。但同时也存在副作用,因为OCSP服务器通常是由CA提供的一台中心化第三方的OCSP验证服务器,在一定程度上也会存在查询延迟和黑客攻击的危险。一旦有黑客或者组织对CA的OCSP发动DDos攻击,客户端便无法从OCSP服务器获取查询结果并完成证书验证, 客户端就可能会提示网站不受信任。

今天我们讨论的Nginx OCSP Stapling机制就非常先进, 该机制会在客户端和服务器发生TLS握手的过程中发送缓存在网站服务器上的OCSP权威记录到客户端进行证书验证。这样一来,客户端就无需每次都向CA的OCSP进行查询了,同时也降低了由于CA OCSP服务器被DDos造成证书无法验证的事件发生的可能性。

值得注意的是: Nginx会在客户端的 HELLO 握手信息中返回OCSP记录,并且只有当客户端对Nginx发出OCSP信息请求的情况下,Nginx才会发送缓存的OCSP 权威记录到客户端。

大多数的服务器都会缓存48小时内的OCSP权威记录,同时在到期前,服务器也会向CA的OCSP服务器更新最新的OCSP权威记录进行缓存。

什么是OCSP Stapling?

OCSP Stapling的官方定义在IETF RFC 6066中。Stapling这个单词就很好的诠释了OCSP响应记录是如何通过WEB服务器而传达到客户端的。WEB服务器从CA的OCSP服务器查询并缓存权威记录。当一个SSL\TLS的握手链接建立完成后, WEB服务器就会把伴随着OCSP权威记录缓存的响应信息返回给客户端。如果客户端要使用OCSP Stapling服务查询证书状态,必须在SSL\TLS的首次握手信息中包含status_request扩展字段。

使用OCSP Stapling的几个优势:

  1. 当客户端再SSL\TLS握手过程中需要请求OCSP信息并验证数字证书的时候,WEB服务器会直接发送缓存好的OCSP权威记录给客户端。
  2. 客户端无需建立额外的HTTP链接到CA的OCSP服务器进行证书验证。
  3. 降低了CA的OCSP服务器遭受到攻击的可能性。

如需了解更多关于OCSP和OCSP Stapling机制的信息,您可以查看这里① 这里②

服务器环境要求

Nginx版本必须大于或等于1.3.7。Ubuntu LTS releases (12.04)和部分CenOS内置的Nginx均无法支持OCSP Stapling。如果你的服务器上还没有满足要求的Nginx引擎,建议你参考Nginx官方文档进行安装。

为了保证Nginx能成功获取到OCSP验证结果,你必须在服务器上测试是否可以访问到CA的OCSP服务器,如果无法正常访问OCSP服务器,建议检查一下WEB服务器的DNS服务器和防火墙规则。

通过下面这条命令查询某个域名(比如v2ssl.com)所用证书的所有OCSP服务器地址:

 

查询Google.com的OCSP服务器,运行结果如下:

配置Nginx

向您的网站配置文件的HTTPS server (listen 443端口的块)块中添加下列代码开启OCSP Stapling支持:

为了Nginx能够成功校验从OCSP服务器返回的验证结果,配置在ssl_certificate的证书应该被操作系统信任才行。对于Nginx服务器,如果你的证书文件中没有包含证书链文件,你就需要配置Nginx的ssl_trusted_certificate字段来引入证书链文件。

比如我的网站的数字证书是在V2SSL申请的PositiveSSL,签发者是COMODORSADomainValidationCA ,我就将V2SSL下载到的证书压缩包中的证书链COMODO-positivessl-CA.pem配置到Nginx如下:

从上面的配置代码我们可以看到,我们指定了两个DNS解析服务器,分别是8.8.8.8和8.8.4.4。这里配置DNS解析服务器是为了防止DNS被劫持造成Nginx无法访问到正确OCSP服务器。

同时需要注意,在Nginx1.1.7之前的版本仅支持指定一个DNS服务器地址。从Nginx1.3.1和1.2.2版本开始可以支持IPv6的DNS地址,Nginx在解析域名的时候会同时查询v4和v6地址。如果你不需要解析域名的IPv6地址,你可以配置Nginx: ipv6=off。从Nginx1.5.8版本开始内置支持IPv6域名解析。

默认情况下,Nginx使用一个TTL值来配置缓存的查询结果的有效期,你也可以修改valid字段的配置值来重新配置缓存的更新频率。同时,只有在Nginx1.1.9版本之后才支持利用这个配置字段来指定缓存有效期。

配置好后,需要重新启动你的Nginx来让配置生效:

启动成功后我们一起来测试。

测试OCSP响应

打开一个服务器命令行,并使用OpenSSL工具进行测试如:

返回结果包含类似如下值则表示OCSP Stapling正常工作:

如果返回如下字段,则表示配置失败或OCSP Stapling没有工作:

你也可以通过SSL Labs 来检测服务器的OCSP Stapling工作状态。

非常遗憾的是,我测试发现目前国内大部分的CDN均不支持OCSP stapling。

参考资源

1.《nginx documentation for resolver

2.《nginx documentation for ssl_stapling

3.译自:《OCSP Stapling on nginx