kn007的个人博客
♥ You are here: Home > 软件与网络 > VPS > Nginx SSL配置杂谈

Nginx SSL配置杂谈

by | 2 Comments

不同场景,配置不同。大家最好按照自己实际需求来做配置,以下讲讲我觉得重要的一些点。

我现在在Fedora Server 44下,Nginx是自行编译的,打上了Dynamic TLS Record补丁(接下来会解释为什么),以及其他一些模块(如brotli)。

OpenSSL使用了长期版本3.5.7。跟之前最大变化就是没有了等价算法(之前是1.1.1w带补丁版本)。

所以为了实现原来等价算法类似的特性,配置很重要,现在关键配置如下:

ssl_buffer_size 16k;

ssl_dyn_rec_enable on;
ssl_dyn_rec_threshold 10;
ssl_dyn_rec_timeout 2000ms;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:P-256;
ssl_early_data on;
ssl_prefer_server_ciphers on;
ssl_conf_command Options PrioritizeChaCha;
ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305';

如果是瘦客户机、工控机,物联网环境需要CCM模式的话,Ciphersuites和ssl_ciphers改为:

ssl_conf_command Ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-CCM8';

因为我不使用PQC (Post-Quantum Cryptography),没啥必要。如果用的话,ssl_ecdh_curve需要修改:

ssl_ecdh_curve X25519MLKEM768:SecP256r1MLKEM768:X25519:P-256;

如果你想使用kTLS (Kernel TLS)的话,需要修改ssl_conf_command且删掉ssl_dyn_rec_*相关配置:

ssl_conf_command Options PrioritizeChaCha,KTLS;

因为kTLS与Dynamic TLS Record并不兼容,直接一起用并不一定会出现问题,但是实际上可能两者均没有什么效果或随机效果。

另外如果你不用Dynamic TLS Record的话,无论是否使用kTLS,都建议你把ssl_buffer_size改为4KB(除非你是下载站,都是大文件)。

接下来来解释下,首先打上Dynamic TLS Record后,可以设置ssl_buffer_size为16KB的原因是这个补丁会在连接初期,发送约等于一个MTU的TLS记录。这样浏览器收到一个包就能立刻解密并渲染内容,极大地降低了TTFB。当连接稳定后,再平滑过渡到16KB的块以保证大文件的吞吐率(会一步步按阶段增大直至16KB)。ssl_dyn_rec_threshold设置为10是我多次测试后,混合环境下最合适的值。

因为一般来说,博客、CMS等这类的站点,在没有Dynamic TLS Record的情况下都是推荐直接设置ssl_buffer_size为4KB的,这样既能兼顾场景,TTFB也会好一些。但是如果你的站点有音乐站、下载站、直播站、CDN等等的话,4KB的块就过于小气了,开销变大。而Nginx默认设置了ssl_buffer_size为16KB就是为了满足大部分场景,但是在TCP拥塞控制、慢启动机制等原因(不是一两句话说得完),加上网络较慢或变化较大(漫游)的情况下,重传的代价就变大了。有了Dynamic TLS Record就可以兼顾所有,这也是我在用Dynamic TLS Record的原因(测试过,好用)。

kTLS的优势,网上说的很多,我就不重复了。记得使用上需要在内核上启用TLS模块(且Nginx需要结合sendfile)。它在我的老服务器上,虚拟网卡上,并没有感觉到提高,对于我算是噱头了。

其他配置上的话,TLS 1.3主要通过ssl_conf_command Ciphersuites来控制,ssl_ciphers是控制TLS 1.2的行为,通过PrioritizeChaCha以及ssl_prefer_server_ciphers,可以优先到双方最优的算法,注意顺序,特别是chacha20不能提到前面去的,那样的话,PrioritizeChaCha就没意义。

对于brotli,我也有几句说的,不知有没有像我一样,一开始就是拉满brotli_comp_level到11。大家可能知道gzip一开始也有类似拉满的误区,后面知道其实设置于小于等于6是最好,5是最佳甜点值,而其实brotli设置为4就比gzip等级5压缩率高(大概是gzip压缩后的85%甚至更低)且cpu消耗几乎一致或略低。如果你CPU好,你可以保持brotli_comp_level为默认值6,CF也是使用6,但是对比等级4收益下降非常多。

其他没介绍的配置,不是不重要,而是还是那句话,需要根据情况适合自己。


关于编译Nginx,之前写过《我的Nginx编译之旅》,其实大同小异,就不再表。

如上所说,现在只推荐打上Dynamic TLS Record补丁。在解压后的Nginx源码目录下使用如下命令进行修补:

curl -4s https://raw.githubusercontent.com/kn007/patch/master/nginx_dynamic_tls_records.patch | patch -p1
kn007/patchSomething could be public patches

提供下现在编译的版本:

nginx version: nginx/1.31.2
built by gcc 16.1.1 20260515 (Red Hat 16.1.1-2) (GCC)
built with OpenSSL 3.5.7 9 Jun 2026
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/usr/local/nginx --http-client-body-temp-path=/usr/local/nginx/tmp/client_body --http-proxy-temp-path=/usr/local/nginx/tmp/proxy --http-fastcgi-temp-path=/usr/local/nginx/tmp/fastcgi --without-http_ssi_module --without-http_scgi_module --without-http_uwsgi_module --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_v3_module --with-http_gzip_static_module --with-http_realip_module --with-pcre-jit --with-threads --with-file-aio --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_secure_link_module --with-http_mp4_module --add-module=/data/src/ngx_brotli --add-module=/data/src/headers-more-nginx-module --with-openssl=/data/src/openssl-3.5.7 --with-openssl-opt='enable-ec_nistp_64_gcc_128 enable-ktls no-shared -march=sandybridge -O3 -fPIC -fstack-protector-strong' --with-cc-opt='-march=sandybridge -O3 -fcode-hoisting -DTCP_FASTOPEN=23 -ffast-math -flto=4 -fstack-protector-strong --param=ssp-buffer-size=4 -Wformat -Werror=format-security -fno-strict-aliasing -fPIC -Wp,-D_FORTIFY_SOURCE=2 -Wimplicit-fallthrough=0 -Wno-cast-function-type -Wno-format-extra-args -Wno-deprecated-declarations -Wno-stringop-overflow -falign-functions=32 -fuse-ld=mold' --with-ld-opt='-Wl,-s -Wl,-z,relro -Wl,-z,now -fPIC -ljemalloc -lrt -flto=4 -fuse-ld=mold'

不得不说mold是个好文明,比gold或lld舒服多了。注意编译参数最好不要照抄,适合自己的才是好的,以及其中的sandybridge,需要改成你的CPU指令集架构。

以及最新写的systemd服务:

cat > /etc/systemd/system/nginx.service << 'EOF'
[Unit]
Description=A high performance web server and a reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
StartLimitIntervalSec=20s
StartLimitBurst=3

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid

LimitNOFILE=524288
LimitMEMLOCK=infinity

Environment="MALLOC_CONF=background_thread:true"

ReadWritePaths=-/usr/local/nginx/logs
ReadWritePaths=-/usr/local/nginx/tmp

ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecStop=/bin/kill -s QUIT $MAINPID
ExecReload=/bin/kill -s HUP $MAINPID

TimeoutStopSec=15s
KillMode=mixed
KillSignal=SIGQUIT
Restart=on-failure
RestartSec=2s

SocketBindAllow=tcp:80 tcp:443 udp:443
SocketBindDeny=any
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictRealtime=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX AF_ALG

[Install]
WantedBy=multi-user.target
EOF

符合安全标准(理论上不怕RCE),适用SELinux严格,请按照实际情况自行修改。

转载请注明转自: kn007的个人博客 的《Nginx SSL配置杂谈

donate
有所帮助?

Comments

2 Comments立即评论
  1. 回复

    这年头,除非是对 memory 要求很高,不然我应该都直接用 Caddy,太省事了。

    1. MOD回复

      @haishan: 适合自己的就是好的 :oops:

;-):|:x:twisted::smile::shock::sad::roll::razz::oops::o:mrgreen::lol::idea::grin::evil::cry::cool::arrow::???::?::!: