从Let’s Encrypt获取免费证书 讲述了如何从Let’s Encrypt获取免费证书,配置nginx来支持用https方式访问站点。昨晚想到https安全性的问题,查阅资料后更新了配置,提高了本站的安全性。

使用使用Let’s Encrypt的免费证书中的nginx配置,在 ssl labs 上只能获得B级的评分,主要问题是存在弱密钥DH降级攻击风险,问题详情可参考 weakdh 网站。解决方案如下:

  1. 生成不低于2048位的dh对(推荐4096位):openssl dhparam -out dhparams.pem 4096
  2. 更改nginx配置,在ssl配置段的加密算法和dh参数配置如下:
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

ssl_dhparam {path to dhparams.pem}
  1. 重启nginx服务器: systemctl reload nginx

使用上述配置,再次到 ssl labs 上测试(如已有结果需清空缓存),可以看到得分为A,截图如下:

ssl labs评分
ssl labs评分

目光转到 cipher list以及 molliza网站,其推荐的配置是完全禁用DH密钥交换。molliza wiki上的配置分为三类:前卫兼容(Modern compatibility),默认的中度兼容(Intermediate compatibility)以及旧式向后兼容。前卫兼容策略比较激进,需要现代化的浏览器才可正常访问:微软的浏览器需要IE 11或者Edge浏览器,IE 11以下的浏览器就不能正常访问。推荐使用默认的中度兼容策略,微软系的浏览器满足IE 7+即可,兼顾了兼容性和安全性。

配置好后,可在更严格策略的 ssl decoder 网站上测试https安全性。该网站中,DES-CBC3-SHA算法也被标记为不安全,建议移除。另外建议开启 HSTS 以及 OCSP Stapling 特性。

总结上述,安全的ssl段的配置如下:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';                  
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;
    ssl_dhparam /etc/nginx/conf.d/dhparams.pem;
    ssl_session_tickets off;
    ssl_stapling on; # Requires nginx >= 1.3.7
    ssl_stapling_verify on; # Requires nginx => 1.3.7
    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    add_header X-Frame-Options DENY;        # 如果页面需要被以frame方式加载,建议关闭
    add_header X-Content-Type-Options nosniff;

重启nginx后,在 ssl decoder以及 ssl labs 上检测服务端安全性,都是安全的绿色了。

参考

  1. ssllabs.com/ssltest/
  2. https://ssldecoder.org
  3. https://weakdh.org
  4. https://cipherli.st/
  5. https://wiki.mozilla.org/Security/Server_Side_TLS
  6. https://imququ.com/post/sth-about-switch-to-https.html#toc-2