阿里云限量代金券 | 此广告位出租25元/月 |
本文向你介绍如何在 nginx 服务器上设置健壮的 SSL 安全机制。我们通过禁用 SSL 压缩来降低 CRIME 攻击威胁;禁用协议上存在安全缺陷的 SSLv3 及更低版本,并设置更健壮的加密套件(cipher suite)来尽可能启用前向安全性(Forward Secrecy);此外,我们还启用了 HSTS 和 HPKP。这样我们就拥有了一个健壮而可经受考验的 SSL 配置,并可以在 Qually Labs 的 SSL 测试中得到 A 级评分。
如果不求甚解的话,可以从 https://cipherli.st 上找到 nginx 、Apache 和 Lighttpd 的安全设置,复制粘帖即可。
本教程可以通过发布于 2014/1/21 的 SSL 实验室测试的严格要求(我之前就通过了测试,如果你按照本文操作就可以得到一个 A+ 评分)。
我们需要编辑 nginx 的配置,在 Ubuntu/Debian 上是/etc/nginx/sited-enabled/yoursite.com,在 RHEL/CentOS 上是/etc/nginx/conf.d/nginx.conf。
本文中,我们需要编辑443端口(SSL)的server配置中的部分。在文末你可以看到完整的配置例子。
在编辑之前切记备份一下配置文件!
加密套件(cipher suite)
前向安全性(Forward Secrecy)用于在长期密钥被破解时确保会话密钥的完整性。PFS(完备的前向安全性)是指强制在每个/每次会话中推导新的密钥。
这就是说,泄露的私钥并不能用来解密(之前)记录下来的 SSL 通讯。
提供PFS(完备的前向安全性)功能的是那些使用了一种 Diffie-Hellman 密钥交换的短暂形式的加密套件。它们的缺点是系统开销较大,不过可以使用椭圆曲线的变体来改进。
以下两个加密套件是我推荐的,之后Mozilla 基金会也推荐了。
推荐的加密套件:
ssl_ciphers 'AES128+EECDH:AES128+EDH';
向后兼容的推荐的加密套件(IE6/WinXP):
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
如果你的 OpenSSL 版本比较旧,不可用的加密算法会自动丢弃。应该一直使用上述的完整套件,让 OpenSSL 选择一个它所支持的。
加密套件的顺序是非常重要的,因为其决定了优先选择哪个算法。上述优先推荐的算法中提供了PFS(完备的前向安全性)。
较旧版本的 OpenSSL 也许不能支持这个算法的完整列表,AES-GCM 和一些 ECDHE 算法是相当新的,在 Ubuntu 和 RHEL 中所带的绝大多数 OpenSSL 版本中不支持。
更多设置
确保你也添加了如下行:
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
在一个 SSLv3 或 TLSv1 握手过程中选择一个加密算法时,一般使用客户端的首选算法。如果设置了上述配置,则会替代地使用服务器端的首选算法。
前向安全性和 Diffie Hellman Ephemeral (DHE)参数
前向安全性(Forward Secrecy)的概念很简单:客户端和服务器协商一个永不重用的密钥,并在会话结束时销毁它。服务器上的 RSA 私钥用于客户端和服务器之间的 Diffie-Hellman 密钥交换签名。从 Diffie-Hellman 握手中获取的预主密钥会用于之后的编码。因为预主密钥是特定于客户端和服务器之间建立的某个连接,并且只用在一个限定的时间内,所以称作短暂模式(Ephemeral)。
使用了前向安全性,如果一个攻击者取得了一个服务器的私钥,他是不能解码之前的通讯信息的。这个私钥仅用于 Diffie Hellman 握手签名,并不会泄露预主密钥。Diffie Hellman 算法会确保预主密钥绝不会离开客户端和服务器,而且不能被中间人攻击所拦截。
所有版本的 nginx(如1.4.4)都依赖于 OpenSSL 给 Diffie-Hellman (DH)的输入参数。不幸的是,这意味着 Diffie-Hellman Ephemeral(DHE)将使用 OpenSSL 的默认设置,包括一个用于密钥交换的1024位密钥。因为我们正在使用2048位证书,DHE 客户端就会使用一个要比非 DHE 客户端更弱的密钥交换。
我们需要生成一个更强壮的 DHE 参数:
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096
然后告诉 nginx 将其用作 DHE 密钥交换:
ssl_dhparam /etc/ssl/certs/dhparam.pem;
HTTP 严格传输安全(HSTS)
如有可能,你应该启用 HTTP 严格传输安全(HSTS),它会引导浏览器和你的站点之间的通讯仅通过 HTTPS。
阅读我关于 HSTS 的文章,了解如何配置它
HTTP 公钥固定扩展(HPKP)
你也应该启用 HTTP 公钥固定扩展(HPKP)。
公钥固定的意思是一个证书链必须包括一个白名单中的公钥。它确保仅有白名单中的 CA 才能够为某个域名签署证书,而不是你的浏览器中存储的任何 CA。
我已经写了一篇关于 HPKP 的背景理论及在 Apache、Lighttpd 和 NGINX 中配置例子的文章。
配置范例
server {
listen [::]:443 default_server;
ssl on;
ssl_certificate_key /etc/ssl/cert/raymii_org.pem;
ssl_certificate /etc/ssl/cert/ca-bundle.pem;
ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_session_cache shared:SSL:10m;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
add_header Strict-Transport-Security max-age=63072000;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
root /var/www/;
index index.html index.htm;
server_name raymii.org;
}
结尾
如果你使用了上述配置,你需要重启 nginx:
# 首先检查配置文件是否正确
/etc/init.d/nginx configtest
# 然后重启
/etc/init.d/nginx restart
现在使用 SSL Labs 测试来看看你是否能得到一个漂亮的“A”。当然了,你也得到了一个安全的、强壮的、经得起考验的 SSL 配置!
参考链接:http://www.open-open.com/lib/view/open1430794673710.html
推荐您阅读更多有关于“”的文章
Powered By Z-Blogphp
分享:
支付宝
微信