nginx配置https证书指南
[TOC]
遇到的问题
- 在配置https证书之后,执行
nginx -t
报错 nginx: [emerg] unknown directive "ssl_certificate" in /usr/local/nginx/conf/nginx.conf
server {
listen 443 ssl;
#.其他省略...
ssl_certificate /data/nginx/ssl/xxx.example.com.pem;
ssl_certificate_key /data/nginx/ssl/xxx.example.com.key;
}
发生原因
- 默认nginx是没有安装ssl模块的,需要在编译安装nginx时(即
./configure
)加入--with-http_ssl_module
选项。
确认过程
- 执行
nginx -V
确认编译nginx的时候是否加入--with-http_ssl_module
参数:
[root@localhost]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.22.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.1.1g 21 Apr 2020
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx
注:这里输出的
configure arguments
清单中果然未包含--with-http_ssl_module
参数
处理步骤
- 第1步,Nginx使用OpenSSL进行SSL处理,TLSv1.1与TLSv1.2要求OpenSSL版本 >= 1.0.1,而TLSv1.3则要求 >= 1.1.1,若OpenSSL低于1.1.1则不支持TLS1.3。可执行
nginx -V
或openssl version
查看openssl版本,若两者返回的版本不一致,则以nginx -V
为准,示例为 1.1.1
[root@localhost ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.22.0
built with OpenSSL 1.1.1g 21 Apr 2020
[root@localhost ~]# openssl version
OpenSSL 1.0.2k-fips 26 Jan 2017
- 第2步,停掉nginx进程之后,备份nginx安装目录(默认安装在
/usr/local/nginx
)
/usr/local/nginx/sbin/nginx -s stop
mv /usr/local/nginx /usr/local/nginx_bak
- 第3步,重新编译nginx,下面提供一个相对完善的编译参数,可以覆盖大部分的业务场景,仅供参考。
cd nginx-1.22.0
./configure \
--prefix=/usr/local/nginx \
--user=nginx --group=nginx \
--with-pcre --with-pcre-jit --with-http_realip_module --with-http_sub_module --with-http_stub_status_module \
--with-http_v2_module --with-http_ssl_module --with-openssl=/usr/local/openssl --with-openssl-opt=enable-tls1_3 \
--with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module \
--with-stream --with-http_gzip_static_module --with-http_flv_module --with-http_mp4_module
make && make install
注:下面是针对特定场景推荐的编译参数解释:
参数名称 | 适用场景 | 备注 |
---|---|---|
--user=nginx --group=nginx | 限定nginx服务的用户和组 | - |
--with-stream | 用于stream端口转发 | - |
--with-http_ssl_module | 需要配置ssl证书 | - |
- 第4步,安装成功之后,再次执行
nginx -V
确认已启用了--with-http_ssl_module
参数,最后再参考后面的配置nginx.conf最佳实践。
配置nginx.conf最佳实践
- 以下是4核16G服务器、OpenSSL版本 >= 1.1.1(即支持TLSv1.3)、支持40000并发的最佳实践。常规的参数配置不再赘述,只需要注意下面几个参数:
#.其他省略...
worker_processes auto;
worker_rlimit_nofile 40000;
events {
use epoll;
worker_connections 40000;
multi_accept on;
}
keepalive_timeout 60;
- 针对ssl部分的最佳配置,参考如下:
server {
listen 443 ssl;
server_name xxx.example.com;
root /data/nginx/www/xxx.example.com;
index index.html index.htm;
ssl_certificate /data/nginx/ssl/xxx.example.com.pem;
ssl_certificate_key /data/nginx/ssl/xxx.example.com.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
}
- 针对ssl部分的相关参数,解释如下:
参数名称 | 默认值 | 推荐值 | 备注 |
---|---|---|---|
ssl_certificate | - | - | 公钥证书,它会被发送到连接服务器的每个客户端 |
ssl_certificate_key | - | - | 私钥证书,用来解密的 |
ssl_session_cache | - | shared:SSL:10m |
SSL会话缓存大小,该缓存被所有的 worker 进程共享 |
ssl_session_timeout | 5m |
- | 客户端可以重用会话缓存中ssl参数的过期时间 |
ssl_protocols | TLSv1 TLSv1.1 TLSv1.2 |
TLSv1.2 TLSv1.3 |
指定支持的加密协议,如果只写1.2表示仅支持1.2 |
ssl_ciphers | HIGH:!aNULL:!MD5 |
- | 指定加密套件,用冒号分隔,前有感叹号的表示禁用 |
ssl_prefer_server_ciphers | off |
on |
设置协商加密算法,优先使用服务端(而非客户端浏览器)定义的加密套件 |
需要注意如下几点:
- nginx 从 1.15.0 开始,可使用
listen 443 ssl;
代替listen 443;
和ssl on;
- nginx 从 1.9.1 开始,默认的 SSL 协议为
TLSv1, TLSv1.1, and TLSv1.2
(if supported by the OpenSSL library) - nginx 从 1.0.5 开始,默认的 SSL 加密算法为
HIGH:!aNULL:!MD5
- 设置较长的keepalive_timeout可以减少请求ssl会话协商的开销,但同时得考虑线程的并发数
- 关于
ssl_session_cache
,1MB SSL 会话缓存可容纳约 4000 个会话,推荐 10MB(可支持 4w 个会话) - 关于
ssl_ciphers
,不同的浏览器所支持的加密套件可能会不同。这里指定的是OpenSSL库能够识别的写法,执行openssl ciphers -v
可以列出当前openssl所支持的加密套件清单