Nginx服务器中关于SSL的安全配置详解

2019-10-17 20:17:42丽君

向前保密的概念很简单:客户端和服务器协商一个可靠的密钥,并在会话结束后销毁。服务器中的RSA私钥用来签名客户端和服务器之间交换的Diffie-Hellman密钥。副主密钥从Diffie-Hellman握手中得到,并用于加密。由于副主密钥在客户端和服务器之间的连接中是明确具体的,并用于有限的时间,因此被叫作Ephemeral(短暂的)。

由于有Forward Secrecy,即使攻击者持有服务器的私钥,也不能够解密过去的会话。私钥仅仅用来签名DH(Diffie-Hellman)的握手,它并没有泄漏副主密钥。Diffie-Hellman确保了副主密钥不会离开客户端和服务器,也不会被中间人截获。


1.4.4所有的nginx版本在往Diffiel-Hellman输入参数时依赖OpenSSL。不幸的时,这就意味着Ephemeral Diffiel-Hellman(DHE)会使用OpenSSL的这一缺陷,包括一个1024位的交换密钥。由于我们正在使用一个2048位的证书,DHE客户端比非ephemeral客户端将使用一个更弱的密钥交换。

我们需要产生一个更强的DHE参数:
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

然后告诉nginx在DHE密钥交换的时候使用它:
 
ssl_dhparam /etc/ssl/certs/dhparam.pem;
OCSP 适用

在和服务器连接的时候,客户端通过使用证书撤销列表(CRL)来验证服务器证书的有效性,或者是使用在线证书状态协议(OCSP)记录。但是CRL的问题是:CRL的列表项不断增多,而且需要不断地下载。


OCSP是更轻量级的,因为它一次只获取一条记录。但是副作用是,当连接到服务器的时候,OCSP请求必须发送到第三方响应者,这增加了延迟,以及失败的可能。实际上,OCSP响应者由CA操控,由于它常常不可靠,导致浏览器由于收不到适时的响应而失败。这减少了安全性,因为它允许攻击者对OCSP响应者进行DoS攻击来取消验证。

解决方案是在TLS握手期间,允许服务器发送缓存的OCSP记录,这样来绕过OCSP响应者。这个技术节省了在客户端和OCSP响应者之间的一个来回,称为OCSP闭合(OCSP Stapling)。

服务器只在客户端请求的时候,发送一个缓存的OCSP响应,通过对CLIENT HELLO的status_request TLS拓展来声明支持。

大多数服务器都会缓存OCSP响应到48小时。在常规间隔,服务器会连接到CA的OCSP响应者来获取最新的OCSP记录。OCSP响应者的位置是从签名证书的Authority Information Access 字段来获取。

HTTP Strict Transport Security

如果可能,你应该开启 HTTP Strict Transport Security (HSTS) ,它指示浏览器只通过HTTPS来访问你的站点。

HTTP Public Key Pinning Extension

你同样应该开启 HTTP Public Key Pinning Extension。

Public Key Pinning 意味着证书链必须包含处于白名单之中的公钥。它确保只在白名单中的CA可以对*.example.com进行签名,而不是浏览器中保存的任何一个CA。