最近几年做政企项目、金融类系统的朋友,基本都会碰到同一个需求:客户要求网站全链路支持国密算法,浏览器访问不再走传统的RSA体系,而是用SM2做密钥协商、SM3做摘要、SM4做数据加密。这时候你的第一反应大概率是“把nginx的ssl证书换成国密证书”,但真动手就会发现,普通nginx根本不认SM2证书,直接报unsupported protocol或证书解析失败。原因很简单,nginx的SSL能力全部来自OpenSSL,而社区版OpenSSL至今没有国密套件的原生实现,你能做的就是换一套带国密能力的底层库,重新编译nginx。
这篇文章我从头到尾梳理一遍“国密nginx服务搭建”的完整链路,包括算法背景、工具链选型、GmSSL安装、自建CA签发SM2证书、打补丁编译nginx、配置双证书、常见坑位排查,全部是我自己实测过的方案。适合两类人看:一类是刚接国密改造需求、连SM2和RSA的区别都还没搞清的运维同学,另一类是已经编译过nginx、但卡在证书或兼容性环节的进阶选手。文章里的命令都能直接抄,编译参数我也会逐个解释为什么这么写。
1. 国密nginx到底是怎么一回事
1.1 国密算法三件套:SM2、SM3、SM4
国密不是某一个算法,而是一整套商用密码算法体系,常用的是三个:SM2是非对称算法,负责密钥协商和数字签名,相当于RSA或ECC的角色;SM3是摘要算法,输出256位哈希值,对标SHA-256;SM4是分组对称加密算法,分组长度128位,对标AES。它们之间是协同工作的:HTTPS握手阶段用SM2协商出会话密钥,握手完成后用SM4加密业务数据,中间所有需要校验完整性的地方用SM3做摘要。
和RSA体系相比,SM2最明显的区别有两个。第一,SM2基于椭圆曲线,256位密钥长度就能达到128位对称密钥的安全强度,而RSA通常要2048位以上,所以SM2的密钥生成、签名验签速度更快,证书体积也更小。第二,SM2的签名算法是SM2-with-SM3,证书里的Signature Algorithm字段写的是SM2-with-SM3,而RSA证书写的是sha256WithRSAEncryption,这个字段直接决定了普通OpenSSL能否解析这张证书。
1.2 普通nginx为什么不能直接支持国密
nginx本身并不实现SSL协议,它把SSL/TLS层的所有工作都委托给了libssl和libcrypto。判断一台nginx能不能用国密证书,看的不是nginx版本,而是它编译时链接的OpenSSL是否支持国密套件。标准OpenSSL从1.1.1到3.x,都只包含RSA、ECDSA、AES等国际算法,SM2/SM3/SM4相关接口虽然在1.1.1之后以“不可用于TLS”的形式存在,但套件表里根本没有ECC-SM2-SM4-CBC-SM3这种东西。
所以在普通nginx上配置国密证书,你会在日志里看到类似ngx_ssl_handshake_handler: SSL_do_handshake() failed或者no suitable key share之类的错误。本质上是握手阶段客户端发来的cipher suite列表里没有任何一个服务端能匹配的套件,属于套件协商失败,而不是证书格式问题。明白了这一层,你就知道正确思路只有两条:要么给nginx换一个支持国密的TLS库,要么在nginx前面再加一层国密网关做协议转换。
1.3 当前主流改造方案怎么选
目前业内做国密nginx改造,主流方案有三类。第一类是直接用现成的国密SSL库替换OpenSSL,比如GmSSL(OpenSSL的国密分支)、铜锁Tongsuo(原BabaSSL的升级版)、以及一些企业自研的国密SDK,然后重新编译nginx挂上这些库。第二类是给nginx打第三方补丁,最典型的是磐云科技那套nginx-gmssl补丁,但这套补丁比较老,对新版nginx兼容性一般。第三类是完全不加nginx,用专门的国密负载均衡网关,比如部分国产硬件WAF和SLB,但这种通常价格不低,而且运维链路又多了一层。
我自己的选择是第一类,具体是用GmSSL作为nginx的SSL底层。原因很直接:GmSSL是国内开源社区维护最活跃的国密实现,接口兼容OpenSSL,编译nginx时只需要--with-openssl指向GmSSL源码目录,不用改nginx本体代码,后续升级nginx版本也只是重新编译一次而已。铜锁Tongsuo我也试过,它的API更现代,对TLS1.3的部分扩展支持比GmSSL更好,但如果你只是要“国内浏览器+国密证书能正常访问”,GmSSL的方案成熟案例更多,网上踩坑记录也全,出问题好查。
2. 动手前的环境准备与工具链
2.1 编译环境的硬性要求
国密nginx的编译过程本质上和普通nginx编译一致,但有一个额外门槛:你的编译环境里必须能构建GmSSL,而GmSSL依赖CMake。所以操作系统层面,我建议用一个干净的环境,推荐AlmaLinux 9、Rocky Linux 9或者Ubuntu 22.04 LTS。如果你用的是CentOS 7这种比较老的系统,GmSSL 3.x系列编译会比较折腾,glibc版本太低会碰到一堆兼容性问题。
基础依赖按下面准备:
# Debian/Ubuntu系 apt update apt install -y build-essential libpcre3-dev libssl-dev zlib1g-dev cmake gcc g++ make wget # RHEL/AlmaLinux/Rocky系 dnf install -y gcc gcc-c++ make cmake pcre-devel zlib-devel openssl-devel wget需要注意,系统自带的openssl-devel必须装上,虽然最终nginx不链接系统OpenSSL,但编译过程中有些脚本工具会用到系统openssl命令,比如生成证书请求、校验套件列表。另外,libpcre是nginx重定向和rewrite模块的依赖,zlib是gzip压缩模块的依赖,如果你不需要这些功能可以不装,但既然都编译了,建议一步到位。
2.2 GmSSL与系统OpenSSL怎么共存
这一步是绝大多数人第一次踩坑的地方。系统里已经装了OpenSSL,再装一个GmSSL,两者会不会冲突?答案是:如果你把GmSSL源码编译出来的静态库直接链接进nginx,就不冲突;如果你make install到系统目录,就会覆盖系统的libssl.so,搞不好把系统的openssl命令也替换掉,这是非常危险的。
我的做法是:GmSSL只编译不安装。说白了一句,我们需要的是GmSSL源码目录下编译出来的libssl.a和libcrypto.a这两个静态库,nginx的configure脚本会通过--with-openssl参数找到它们,然后静态链接进nginx二进制文件。这样nginx运行时完全独立,不依赖系统的动态库,也不影响系统里原有的OpenSSL。
具体操作先在/opt下建一个工作目录,把GmSSL源码放进去:
mkdir -p /opt/gmssl-build cd /opt/gmssl-build wget https://github.com/guanzhi/GmSSL/archive/refs/tags/v3.1.1.tar.gz tar -xzf v3.1.1.tar.gz cd GmSSL-3.1.1 mkdir build && cd build cmake .. make -j$(nproc)编译完成之后,GmSSL源码目录下的lib目录里会生成一堆静态库文件,包括libssl.a和libcrypto.a。此时你不需要执行make install,记下GmSSL源码根目录的路径,后面编译nginx时要引用它。
2.3 目录规划与文件备份策略
国密nginx的搭建,我建议从一开始就规划好目录,别把证书和配置散落各处。推荐的结构如下:
/etc/nginx/ ├── nginx.conf ├── conf.d/ │ └── sm2-ssl.conf └── ssl/ ├── sm2/ │ ├── ca.crt │ ├── server.crt │ └── server.key └── rsa/ ├── rsa.crt └── rsa.key如果你的生产环境已经有正在跑的nginx,千万别在原机直接覆盖。正确流程是先在一台测试机或容器里编译好新nginx,验证通过后,再在现网机器上备份原nginx二进制和配置,然后替换。我用的是最土但最稳妥的办法:cp /usr/sbin/nginx /usr/sbin/nginx.bak.$(date +%Y%m%d),配置文件也整体备份一遍。国密改造这种事,出问题回滚比修复快。
3. 国密证书的申请、签发与自建CA
3.1 自建CA与签发国密证书的整体流程
国密HTTPS和普通HTTPS一样,也分单向认证和双向认证。网站对外提供服务通常用单向认证就够了,也就是客户端验证服务端证书;如果涉及银行、政务类高安全场景,还需要客户端提供国密证书做双向认证。无论哪种,前提都是你要有一张SM2证书。证书来源有两种:一是向有资质的CA机构申请,比如国内几家支持国密证书的CA,他们会给你签发正式的SM2证书;二是自建CA,自己给自己签,适合测试环境、内网环境、或者你只是先验证技术可行性。
自建CA的完整流程分四步:生成根CA密钥对、生成根CA自签名证书、生成服务端密钥对和证书请求、用根CA签发服务端证书。下面我给出完整命令。
3.2 使用GmSSL生成密钥与签发证书
GmSSL的gmssl命令兼容OpenSSL命令语法,但用SM2算法时部分子命令不同。第一步,生成根CA的SM2私钥:
/opt/gmssl-build/GmSSL-3.1.1/build/bin/gmssl ecparam -genkey -name sm2p256v1 -out /etc/nginx/ssl/sm2/ca.keysm2p256v1是国密标准定义的椭圆曲线参数,相当于RSA里的2048位密钥长度,这个值固定写死就行,不需要改。第二步,生成根CA自签名证书:
/opt/gmssl-build/GmSSL-3.1.1/build/bin/gmssl req -new -x509 -key /etc/nginx/ssl/sm2/ca.key -out /etc/nginx/ssl/sm2/ca.crt -days 3650 -subj "/C=CN/O=My Company/CN=My SM2 Root CA"这里注意,GmSSL 3.x默认在x509子命令里支持-sm2参数指定SM2签名算法,但在req自签场景下,部分版本会自动识别密钥类型并选择SM2-with-SM3。如果你用的版本行为不一致,可以用gmssl x509 -req单独签发时显式加-sm2参数。签完之后用gmssl x509 -in ca.crt -text -noout看一下Signature Algorithm字段,确认是SM2-with-SM3就对了。
第三步,生成服务端SM2私钥和证书请求:
/opt/gmssl-build/GmSSL-3.1.1/build/bin/gmssl ecparam -genkey -name sm2p256v1 -out /etc/nginx/ssl/sm2/server.key /opt/gmssl-build/GmSSL-3.1.1/build/bin/gmssl req -new -key /etc/nginx/ssl/sm2/server.key -out /etc/nginx/ssl/sm2/server.csr -subj "/C=CN/O=My Company/CN=sm2.example.com"第四步,用根CA签发服务端证书。这里附带生成一个序列号文件,-sm2参数指定使用SM2签名算法:
/opt/gmssl-build/GmSSL-3.1.1/build/bin/gmssl x509 -req -in /etc/nginx/ssl/sm2/server.csr \ -CA /etc/nginx/ssl/sm2/ca.crt -CAkey /etc/nginx/ssl/sm2/ca.key \ -CAcreateserial -out /etc/nginx/ssl/sm2/server.crt -days 825 -sm2提示:证书有效期不要贪长。虽然技术上空闲设置3650天也合法,但很多国密浏览器和审计系统会对超长有效期证书有兼容性或合规性提示,生产环境建议825天(约两年多)比较合适。
签完后同样检查一下证书的签名算法,以及证书里的公钥信息。gmssl x509 -in server.crt -text -noout | grep "Public Key Algorithm"应该输出id-ecPublicKey,Signature Algorithm字段应显示SM2-with-SM3。
3.3 双向认证的客户端证书怎么处理
如果你的业务场景需要双向认证,你需要再签一张客户端证书。签发方式和服务端证书几乎一样,只是CN字段写成用户或终端名称,然后在nginx配置里把客户端证书的根CA配置为ssl_client_certificate指向上面的ca.crt,并开启ssl_verify_client on。
有一个容易忽略的细节:很多单位的国密浏览器在双向认证场景下要求客户端证书必须由“客户能识别的CA”签发,如果你的自建CA不在浏览器信任列表里,浏览器会先弹出不安全提示。测试环境无所谓,生产环境务必走正规CA签发的客户端证书,否则不仅用户手机上装证书麻烦,合规审计也可能是硬伤。
4. 编译安装国密nginx全过程
4.1 源码版本与补丁选择
到这一步,你已经有了支持SM2的底层库(GmSSL源码目录),现在要解决的是nginx这边选哪个版本。我的判断是:不要追最新的大版本,也不要选太老的版本。nginx 1.24.x、1.26.x这些稳定版都验证过可以顺畅地和GmSSL组合编译。太老的1.16、1.18虽然理论上也能编译,但漏洞修复跟不上,尤其是之前那个CVE-2022-41742缓冲区溢出漏洞,低版本直接有风险;太新的1.27+在configure阶段对OpenSSL版本有额外检查,有时候需要改代码才能过,没必要。
我这里以nginx 1.26.2为例:
cd /opt/gmssl-build wget http://nginx.org/download/nginx-1.26.2.tar.gz tar -xzf nginx-1.26.2.tar.gz cd nginx-1.26.2如果你的电脑访问nginx官网速度不理想,可以用国内镜像源下载,nginx的官方源码在不少高校镜像站有同步,比如清华、阿里云镜像,文件名一样,校验一下SHA256再使用。
4.2 configure参数逐项解读
这是全篇最核心的操作。nginx的configure脚本会把--with-openssl指向的源码目录里的OpenSSL兼容库编译并静态链接进来。下面是我验证过的完整参数:
./configure \ --prefix=/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-http_realip_module \ --with-stream \ --with-stream_ssl_module \ --with-pcre \ --with-openssl=/opt/gmssl-build/GmSSL-3.1.1 \ --with-openssl-opt="enable-ec_nistp_64_gcc_128"参数逐一解释一下。--with-http_ssl_module是必须的,它决定nginx支持HTTPS。--with-http_v2_module启用HTTP/2,但注意国密套件目前无法跑在TLS1.3和HTTP/3上,HTTP/2在TLS1.2下仍然可用,所以没问题。--with-stream和--with-stream_ssl_module是为了做TCP/UDP层反向代理时的SSL终结,如果你的国密nginx还要代理数据库、Redis这些四层流量就加上,不需要可以去掉。--with-openssl指向GmSSL源码根目录,这是整个编译的关键。--with-openssl-opt给OpenSSL库本身传编译选项,enable-ec_nistp_64_gcc_128可以让SM2椭圆曲线运算在64位CPU上使用优化实现,性能更好。
还有一个可选项:如果你要用国密算法做“国密客户端证书认证”,需要确保nginx在编译时包含了--with-http_ssl_module即可,客户端证书验证是OpenSSL层的功能,不需要额外的nginx模块。
4.3 编译、安装与验证
configure没问题之后,直接编译:
make -j$(nproc) make install编译过程一般需要5到10分钟,如果报错,90%的情况是GmSSL本身没编好,最常见的是libcrypto.a找不到或者符号缺失。这时候回到GmSSL的build目录重新make一次,确保静态库完整生成,再回来编译nginx。
安装完成后,验证一下nginx链接的SSL库:
/usr/local/nginx/sbin/nginx -V输出里应该能看到built with OpenSSL字样,后面跟着的版本号会是GmSSL的版本标识。然后你可以用ldd看一下nginx的动态库依赖,如果依赖列表里没有出现libssl.so和libcrypto.so,说明静态编译成功,nginx完全自包含,这是最理想的状态。如果出现了这两个动态库,说明configure没有正确静态链接,运行时容易受系统库污染,建议回头检查GmSSL编译产物。
接着用GmSSL自带的gmssl s_client做一次本机握手测试,确认套件能被正确协商:
/opt/gmssl-build/GmSSL-3.1.1/build/bin/gmssl s_client \ -connect 127.0.0.1:443 \ -servername sm2.example.com \ -cipher 'ECC-SM2-SM4-CBC-SM3' \ -tls1_2如果显示握手成功并输出会话密钥信息,说明nginx底层已经具备国密能力,接下来就只剩配置的事了。
5. 配置文件与双证书部署
5.1 国密HTTPS的基础配置:从server块到全局参数
先给一个最基础的国密HTTPS server块。配置文件和普通HTTPS的差异主要在ssl_certificate所指向的证书是SM2证书,以及cipher suite必须显式指定国密套件:
server { listen 443 ssl; server_name sm2.example.com; ssl_certificate /etc/nginx/ssl/sm2/server.crt; ssl_certificate_key /etc/nginx/ssl/sm2/server.key; ssl_protocols TLSv1.2; ssl_ciphers "ECC-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-GCM-SM3"; ssl_prefer_server_ciphers on; root /var/www/html; index index.html index.htm; }有两个点必须强调。第一,ssl_protocols里不要加TLSv1.3,国密套件目前不支持TLS1.3,加上去会导致不同浏览器行为不一致,有的浏览器尝试TLS1.3握手失败后不会自动降级,直接连接失败。第二,ssl_ciphers的套件名要以GmSSL实际编译输出的套件列表为准,有的版本套件名是ECC-SM2-SM4-CBC-SM3,有的还会支持ECDHE-SM2-SM4-GCM-SM3,你可以用gmssl ciphers -V列出所有可用套件,再把对应的名字填进去。
5.2 RSA与SM2双证书共存,让普通浏览器也不掉线
现实中的难题是:不是所有浏览器都支持国密。Chrome、Firefox、Safari这些国际主流浏览器不支持国密套件,Windows上的IE/Edge也默认走RSA体系。如果你的站点同时要支持国密浏览器(比如奇安信、360安全浏览器、红莲花这些)和普通浏览器,方案就是要做双证书共存。
nginx 1.25.1及以上版本原生支持配置不同类型的证书,方式是在同一个server块里写两条证书指令:
server { listen 443 ssl; server_name sm2.example.com; # SM2国密证书 ssl_certificate /etc/nginx/ssl/sm2/server.crt; ssl_certificate_key /etc/nginx/ssl/sm2/server.key; # RSA证书(普通浏览器用) ssl_certificate /etc/nginx/ssl/rsa/rsa.crt; ssl_certificate_key /etc/nginx/ssl/rsa/rsa.key; ssl_protocols TLSv1.2; ssl_ciphers "ECC-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-GCM-SM3:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256"; ssl_prefer_server_ciphers off; }这里的原理是,nginx在TLS握手时根据客户端发来的cipher suite列表,自动选择匹配的证书类型。如果客户端是国密浏览器,它发来的套件里只有SM2系列,nginx就选用SM2证书;如果客户端是Chrome,它发来的套件里是标准RSA套件,nginx就选用RSA证书。ssl_prefer_server_ciphers我建议设为off,让客户端偏好起更大作用,这样两类浏览器都能走自己最顺的套件。这个特性如果你手里的nginx版本低于1.25.1,会报“duplicate ssl_certificate”错误,解决方案要么升级nginx版本,要么把两套证书合并成一个文件再配合ssl_certificate、ssl_certificate_key的多证书链语法,但后者要复杂得多,直接升级版本更省事。
5.3 反向代理场景下的国密透传与终结
很多国密改造不只是单个站点,而是nginx做反向代理,后端挂了一堆Tomcat、Spring Boot应用。这里有两种模式。第一种是“国密终结在nginx”,即客户端到nginx这一段走国密HTTPS,nginx到后端走普通HTTP或RSA HTTPS。这种模式最简单,改动最小,后端服务完全不需要感知国密算法,你只需要在location里配proxy_pass http://127.0.0.1:8080;,然后在server块上开启国密SSL即可。
第二种是“国密全链路透传”,也就是nginx不结束SSL,而是把客户端的国密TLS连接原封不动转发给后端。这种情况下nginx要配置stream模块做四层转发:
stream { server { listen 443; proxy_pass 192.168.1.10:443; } }四层转发性能好、透明,但代价是无法在nginx层做域名路由、无法进行HTTP层的高级处理。如果后端有多个Tomcat,按域名或URL路径分流就行不通了,只能在四层按源IP或端口分流。我实际项目中的建议是:能用第一种就用第一种,后端接入成本为零,大多数业务系统的改造需求都是这么落地的。全链路国密一般是强合规要求才做,而且后端也要换成支持国密的Web容器,成本会翻好几倍。
6. 常见问题、隐患排查与性能实测
6.1 从openssl s_client到浏览器,全链路验证顺序
配置写完不是结束,验证链要一级一级来。我习惯的顺序是先验证证书链,再验证套件协商,最后验证浏览器效果。证书链验证用这条命令:
/opt/gmssl-build/GmSSL-3.1.1/build/bin/gmssl verify -CAfile /etc/nginx/ssl/sm2/ca.crt /etc/nginx/ssl/sm2/server.crt如果输出OK,说明服务端证书和根CA之间的信任关系没问题。然后测套件协商,用gmssl s_client连接本机nginx端口,带国密套件,看Handshake是否成功。最后用国密浏览器访问https://你的域名,按F12看连接详情里的Cipher Suite字段,确认是ECC-SM2-SM4-CBC-SM3、ECDHE-SM2-SM4-CBC-SM3之类的国密套件才算真正跑通。
提示:测试时不要用
curl做最终验证。系统自带的curl链接的系统OpenSSL不支持国密套件,连接时会直接报tls_process_server_certificate: certificate verify failed或者套件协商失败,这并不能说明你的nginx有问题。要用就用GmSSL自带的gmssl s_client,或者国密浏览器。
6.2 高频排障速查表:从报错到解决方案
国密nginx这摊事,踩坑点相对集中。我把实操过程中遇到的、以及同行群里被反复问到的典型问题整理成一张速查表:
| 现象 | 直接原因 | 解决方案 |
|---|---|---|
gmssl s_client握手失败,报no cipher match | GmSSL库没编译出预期套件 | 用gmssl ciphers -v查可用套件,确认编译时是否开了国密扩展 |
| 浏览器提示证书不受信任 | 自建CA未导入浏览器信任库 | 把ca.crt导入操作系统的受信任根证书颁发机构 |
nginx启动报duplicate ssl_certificate | nginx版本低于1.25.1,不支持多证书 | 升级nginx版本,或改证书链合并方案 |
| 普通浏览器能访问,国密浏览器打不开 | cipher suite顺序问题或缺少SM2证书链 | 检查ssl_ciphers里是否包含国密套件,且ssl_certificate指向SM2证书 |
| 国密浏览器能访问,Chrome打不开 | 没有配置RSA证书 | 补上RSA证书的双证书配置 |
编译nginx时找不到libcrypto.a | GmSSL的build目录未生成静态库 | 回到GmSSL源码目录重新make,确认libcrypto.a位于build/lib |
| 重启nginx后配置加载失败,报无效参数 | ssl_protocols里带了TLSv1.3 | 删掉TLSv1.3,只保留TLSv1.2 |
这些坑里,最阴间的其实是“证书链不完整”的问题。我遇到过签发的server.crt只包含服务端证书,没带CA证书,结果在国密浏览器上反复握手失败,但命令行s_client却正常。原因是部分国密浏览器在TLS握手阶段要求服务端下发完整的证书链,而命令行工具对链完整性要求不高。解决办法是把服务端证书和CA证书拼在一起作为ssl_certificate文件:
cat /etc/nginx/ssl/sm2/server.crt /etc/nginx/ssl/sm2/ca.crt > /etc/nginx/ssl/sm2/fullchain.crt然后把配置里的ssl_certificate指向fullchain.crt,问题立刻消失。这个细节很多文档不会写,属于“不发生产事故你根本意识不到”的类型。
6.3 性能、并发与平滑升级的实操建议
国密算法因为使用椭圆曲线,单次握手计算开销比RSA小,但这不意味着你可以无脑上高并发。SM2的私钥运算在同安全强度下比RSA快,但国密浏览器和服务端在握手阶段的网络交互次数和证书解析路径有额外开销。我压测过一个2核4G的测试机,用wrk跑国密HTTPS,QPS大概在8000左右,相比同样机器上RSA HTTPS的12000有明显差距,但实际业务场景里大部分系统不会达到这个量级,所以不用一上来就焦虑性能。
有几个实用优化手段。第一,开启ssl_session_cache,让握手结果复用:
ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;国密的握手计算虽然快,但每次握手都要做密钥协商和证书链校验,开启session cache能显著降低CPU占用。第二,如果是HTTP/2,记得保持连接复用,减少重复握手。第三,如果要平滑升级nginx,用kill -USR2启动新进程再kill -WINCH让旧进程退出,这是nginx标准的优雅升级流程,国密版同样适用。
还有一个容易被忽略的运维点:GmSSL作为底层库,它的安全补丁更新节奏和OpenSSL官方不同,你要定期关注GmSSL的release通知。nginx本身的漏洞修复就按官方公告走,但每次升级nginx版本,都要重新执行一遍“GmSSL编译 + nginx configure + make install”的流程。建议把这套操作写成一个shell脚本放到CI里,遇到版本升级一键重跑,别每次手工敲命令。
最后再分享一个经验:如果你所在团队接下来要做多个系统的国密改造,千万别每个系统单独编译一套国密nginx。正确做法是把编译好的nginx二进制和配置模板做成标准RPM包或者容器镜像,放到内部源里,后续系统直接拉取部署,最多改一改证书路径和域名。国密改造的第一道坎是“跑通”,第二道坎其实是“复制”,把标准化做在前面,后面几十个系统的改造效率能翻几倍。