12

nginx下配置高性能,高安全性的https TLS服务

 3 years ago
source link: https://byronhe.com/post/2015/05/08/https-config-optimize-in-nginx/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

下文以nginx为例,介绍如何部署一个高性能,高安全性的https服务器。

并附送一个优化出来的openssl编译脚本,可以编译出一个高性能,高安全性的openssl库,您可以直接复制粘贴使用。

此处直接给出实践指导,后续再写文章解释tls协议的这些原理细节。

nginx下https配置的优化点,主要有:

  1. session ticket
  2. session id cache
  3. ocsp stapling
  4. http KeepAlive
  5. ECDHE等ciphersuite优化
  6. openssl 编译优化

一, nginx https的配置

先贴一下nginx配置,如下。

是根据mozilla的权威文档 ,和生成工具(选择 nginx,intermediate ) 生成的配置为基础,加入session ticket等配置的结果

server {
    listen 443 ssl;

    # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
    ssl_certificate /path/to/signed_cert_plus_intermediates;
    ssl_certificate_key /path/to/private_key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;

    ssl_session_ticket_key /etc/nginx/conf.d/tls_session_ticket.key;
    ssl_session_tickets on;
    
    keepalive_timeout 75s;

    # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
    ssl_dhparam /path/to/dhparam.pem;

    # intermediate configuration. tweak to your needs.
    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: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_prefer_server_ciphers on;

    # HSTS (ngx_http_headers_module is required) (15768000 seconds = 6 months)
    add_header Strict-Transport-Security max-age=15768000;

    # OCSP Stapling ---
    # fetch OCSP records from URL in ssl_certificate and cache them
    ssl_stapling on;
    ssl_stapling_verify on;

    ## verify chain of trust of OCSP response using Root CA and Intermediate certs
    ssl_trusted_certificate /path/to/signed_cert_plus_intermediates;

    resolver 114.114.114.114;
 
    ....
}

二, 其中的几个配置项

1. /path/to/signed_cert_plus_intermediates

是你的证书链,就是ca签署之后发给你的文件,是一串这样的内容

-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
...
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
2. /path/to/private_key

是你的私钥,一定要保密,最好chown+chmod限制只有http server可以读取!内容大致是:

-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
3. /path/to/dhparam.pem

是dhe密钥协商的参数,生成方法:

     openssl  dhparam -out dhparam.pem 2048
4. /etc/nginx/conf.d/tls_session_ticket.key

是用来加解密session ticket的密码文件,这个文件的安全等级应该和私钥一样,最好chmod+chown限制只有http server能读取。 生成方法:

     openssl rand 48 > tls_session_ticket.key

最好定期(比如2天一次)轮换,配置文件里把新的key文件放在最前面,旧的在下面,如下

    ssl_session_ticket_key current.key;
    ssl_session_ticket_key previous.key;
5. ssl_trusted_certificate /path/to/signed_cert_plus_intermediates

ssl_trusted_certificate,是用来验证ocsp响应的各个ca证书+中级证书,和信任的ca根证书列表。当用来验证ocsp响应的时候,应该配置为你的ca根证书+和中级ca证书的列表,此处可以简单和ssl_certificate使用同一个证书列表文件。
其中当需要使用tls的客户端认证的时候(大多数https server都用不到客户端认证),需要指定信任的ca根证书列表文件, 这个文件在centos里面是/etc/ssl/certs/ca-bundle.trust.crt 这个文件。

配置完成之后,使用ssllabs的这个在线检查工具https://www.ssllabs.com/ssltest/analyze.html 做检查,里面提出的警告,都需要改正。

三, openssl编译优化

主流的https server,都是依赖openssl来提供tls协议,openssl本身代码复杂,概念繁多,最近对这方面做了研究,下面是一个深入分析过后的最优化编译配置,可以编译出一个高性能,高安全性的openssl版本,您可以直接复制粘贴使用。

openssl请使用最新的1.0.2a版本,这个版本有intel针对ecdh p256曲线的优化,编译脚本见本文末尾。

编译好之后,需要让nginx使用我们编译的这个openssl库,在centos下,可以用LD_LIBRARY_PATH的办法:

sudo vim /usr/lib/systemd/system/nginx.service

在其中添加一行Environment,如下:

[Service]
...
Environment=LD_LIBRARY_PATH=/usr/local/bin/openssl-1.0.2a_64_build/lib/
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
...

其中的路径,请自行修改。

还需要创建软连接,解决so库版本号的问题,如下

ln -s libcrypto.so.1.0.0 libcrypto.so.10
ln -s libssl.so.1.0.0 libssl.so.10

脚本中包含了一个cloudflare的patch,增加chacha20_poly1305 cipher,使用了这个patch之后,可以使用cloudflare的ciphers配置

https://github.com/byronhe/modern-crypto-toolbox/blob/master/build_openssl.sh


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK