Nginx的SSL配置优化

in Tutorials with 8 comments

本站linpx.com用了下面的配置在SSL Labs测试中可以获得A+的最佳评级。

aaaaa1213.png

一般网站使用的SSL证书都是RSA证书,这种证书基本都是2048位的密钥,但是证书密钥交换密钥必须要比证书密钥更长才能安全,而默认的只有1024位,所以我们需要手动生成一个更强的密钥。所以配置之前,如果没有DH-key就需要做下面的步骤

有screen则跳过,没则安装

yum -y install screen

生成4096位的DH-Key(证书密钥交换密钥)

screen -S DH
openssl dhparam -out dhparam.pem 4096

执行之后需要等很长时间,总之慢慢等,网路出现中断,可以执行下面命令重新连接安装窗口

screen -r DH

熬过漫长的等待时间后,建议生成的dhparam.pem文件最好跟SSL证书放在一起方便管理。

有了证书密钥交换密钥后,我们继续配置,打开网站所对应的Nginx的conf配置文件

假设我的配置文件是在 /usr/local/nginx/conf/vhost 的目录

vim /usr/local/nginx/conf/vhost/www.linpx.com.conf

配置如下,只包含了ssl的部分,未包含其他比较重要的配置,如缓存、跳转、防盗链和强制HTTPS等等

server {

listen 443 ssl http2;

add_header Strict-Transport-Security "max-age=6307200; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_certificate /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.key;
ssl_trusted_certificate /usr/local/nginx/conf/vhost/sslkey/chaine.pem;
ssl_dhparam /usr/local/nginx/conf/vhost/sslkey/dhparam.pem;

ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;

ssl_prefer_server_ciphers on;

ssl_session_cache builtin:1000 shared:SSL:10m;
ssl_session_tickets on;

ssl_stapling on; 
ssl_stapling_verify on;

resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;

···

}

各行解析:

server {

listen 443 ssl http2;
#使用HTTP/2,需要Nginx1.9.7以上版本

add_header Strict-Transport-Security "max-age=6307200; includeSubdomains; preload";
#开启HSTS,并设置有效期为“6307200秒”(6个月),包括子域名(根据情况可删掉),预加载到浏览器缓存(根据情况可删掉)

add_header X-Frame-Options DENY;
#禁止被嵌入框架

add_header X-Content-Type-Options nosniff;
#防止在IE9、Chrome和Safari中的MIME类型混淆攻击

ssl_certificate /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/sslkey/www.linpx.com.key;
#SSL证书文件位置

ssl_trusted_certificate /usr/local/nginx/conf/vhost/sslkey/chaine.pem;
#OCSP Stapling的证书位置

ssl_dhparam /usr/local/nginx/conf/vhost/sslkey/dhparam.pem;
#DH-Key交换密钥文件位置

#SSL优化配置

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#只允许TLS协议

ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
#加密套件,这里用了CloudFlare's Internet facing SSL cipher configuration

ssl_prefer_server_ciphers on;
#由服务器协商最佳的加密算法

ssl_session_cache builtin:1000 shared:SSL:10m;
#Session Cache,将Session缓存到服务器,这可能会占用更多的服务器资源

ssl_session_tickets on;
#开启浏览器的Session Ticket缓存

ssl_session_timeout 10m; 
#SSL session过期时间

ssl_stapling on; 
#OCSP Stapling开启,OCSP是用于在线查询证书吊销情况的服务,使用OCSP Stapling能将证书有效状态的信息缓存到服务器,提高TLS握手速度

ssl_stapling_verify on;
#OCSP Stapling验证开启

resolver 8.8.8.8 8.8.4.4 valid=300s;
#用于查询OCSP服务器的DNS

resolver_timeout 5s;
#查询域名超时时间

···

}

配置完后请记得重启Nginx!

CentOS 6.x:

service nginx restart

CentOS 7.x:

systemctl restart nginx
Responses
  1. nami

    请问你的openssl版本是多少,我的同样nginx配置相同的ciphers,但是却比你的多容许了一个cipher:
    LS_RSA_WITH_3DES_EDE_CBC_SHA (0xa)

    Reply
    1. nami
      @nami

      哦知道了 你网站用的是ECDSA的证书。。这个证书多少钱申请的呀

      Reply
  2. 提交到HSTS提示Warning: Non-standard capitalization of includeSubDomains 怎么破?

    Reply
    1. @小残

      如果是申请HSTS Preload List
      则看一下这篇:www.linpx.com/p/hsts-and-hsts-preload-list-enabled-applications.html
      注意 max-age=31536000 的时间

      其他情况试一下 nginx -t 检查错误

      Reply
      1. @Chakhsu Lau

        已经弄好了原来是max-age必须设置为6307200~

        Reply
  3. add_header Strict-Transport-Security "max-age=6307200; includeSubdomains; preload"; 其中的 max-age 不能低于 18 周(10886400 秒)

    Reply
    1. @carpliyz

      额,这篇文章主要是针对没有打算申请 HSTS Preload List 的,所以就换了个6307200,关于《申请 HSTS Preload List 》的,可以看下面链接文章有详细介绍

      https://www.linpx.com/p/hsts-and-hsts-preload-list-enabled-applications.html

      Reply
      1. @Chakhsu Lau

        了解,还是 大于10886400 为好,否则不生效==

        Reply