nginx上升级TLS1.3 http2

openSSL

TLS1.3 final需要openSSL版本1.1.1正式版

下载解压openSSL源码供nginx编译使用

1
2
3
curl -O https://www.openssl.org/source/openssl-1.1.1b.tar.gz
tar zxvf openssl-1.1.1b.tar.gz
mv openssl-1.1.1b.tar.gz openssl

编译nginx

本站nginx版本 1.16.0

1
2
3
4
curl -O http://nginx.org/download/nginx-1.16.0.tar.gz
tar zxvf nginx-1.16.0.tar.gz
./configure --prefix=/usr/local/nginx --with-openssl=../openssl --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_v2_module
make

由于我之前nginx已经编译过了 就不执行make install

替换原来的nginx就行

1
2
3
4
5
# pwd: /usr/local/nginx/nginx-1.16.0
cp objs/nginx /usr/local/nginx/sbin/nginx.latest
cd /usr/local/nginx/sbin
mv nginx nginx.old
mv nginx.latest nginx

替换完之后运行 ./nginx -V 看到

1
2
3
4
5
nginx version: nginx/1.16.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.1.1b 26 Feb 2019
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-openssl=../openssl --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_v2_module

说明nginx整好了

如果之前没安装过nginx 直接在源码目录下make installnginx -V结果一致就行

之后就是nginx -s reload重启

新安装的话是nginx -c conf/nginx.conf

重启之前务必 nginx -t !

nginx配置

http2

这个最简单listen后面加http2就行了

1
2
3
4
server {
listen 443 ssl http2;
...
}

TLS

这里有个巨坑 先上正常配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 443 ssl http2;

# 域名
server_name xxxxx;

# 证书
ssl_certificate xxxxxx;
ssl_certificate_key xxxx;

ssl_session_timeout 5m;

# TLS版本
ssl_protocols TLSv1.2 TLSv1.3;
# 加密套件
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;

...
}

看上去应该是没什么问题,很正常的配置。

先去chrome控制台-Security标签里看

tech_8_1

…嗯?为啥还是TLSv1.2?我chrome版本都73了啊

再去ssllabs分析一波…嗯???为啥还支持TLSv1.0 TLSv1.1?为啥不支持TLSv1.3?

tech_8_2

google了半天有人说 nginx里如果配置了default_server,那么在default_server里也需要指定TLS版本

我为了禁止直接用ip访问设了这么一段

1
2
3
4
5
6
server {
listen 443 default_server;
ssl_certificate xxxxx
ssl_certificate_key xxxxxx;
return 403;
}

所以需要在这里加上ssl_protocols TLSv1.2 TLSv1.3

然后重启nginx测试结果

tech_8_3

tech_8_4

好了。

其他配置

稍微记一下..

gzip

1
2
3
4
5
6
7
8
9
gzip  on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/json application/xml+rss;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";

除了第一行从上到下:

  • 1k以上才压缩
  • 向系统申请多大的缓存
  • 最低支持的http版本
  • 压缩等级
  • 支持的mime
  • 是否在header里加一条“Vary: Accept-Encoding”(告诉缓存服务器遇到同一个 URL 对应着不同版本文档的情况时,如何缓存和筛选合适的版本)
  • 请求来自代理服务器时候 根据请求头中的“Via”字段来执行压缩(其实不太明白)
  • 问就是IE6..

禁止直接ip访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 禁止http
server {
listen 80 default_server;
server_name _;
return 403;
}

# 禁止https 一定要指定证书和TLS版本
server {
listen 443 default_server;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_certificate xxxxxxx;
ssl_certificate_key xxxxxxx;
return 403;
}

HSTS(HTTP严格传输安全)

它告诉浏览器只能通过HTTPS访问当前资源,而不是HTTP。

1
add_header Strict-Transport-Security "max-age=31536000";