RSS订阅专注X86/ARM架构技术
博客交流QQ群693563350 赞助本站
你现在的位置:网站首页 / 建站 / 正文内容

增强nginx的SSL安全性

17120 建站 | 2017年04月15日

20150505105652_397.png

本文向你介绍如何在 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


上一篇:HTTPS网站存在不安全因素的解决办法

下一篇:zblogphp相关文章功能调用代码

猜你喜欢