原生nginx不支持国密ssl,需使用nginx-tongsuo等国密定制版,配合tongsuo openssl、双证书(sm2+rsa)及国密套件(如ecc-sm4-cbc-sm3),并用国密客户端验证握手。

原生 Nginx 不支持国密(SM2/SM3/SM4)SSL 协议,要实现国密 HTTPS,必须借助支持国密的 OpenSSL 分支(如 OpenSSL-SM)并配合兼容国密的 Nginx 衍生版本(如 nginx-tongsuo 或 nginx-gm),而非简单添加第三方插件。
选择正确的国密兼容 Nginx 构建环境
所谓“第三方插件”在 Nginx 生态中并不存在可热加载的国密 TLS 插件。实际路径是:
- 使用基于国密 OpenSSL(如 Tongsuo)编译的定制版 Nginx,例如 nginx-tongsuo(官方维护,生产就绪)或社区版 nginx-gm
- 避免自行 patch 官方 Nginx 源码——TLS 握手、证书解析、密钥交换等深度耦合底层密码库,改造成本高且易出错
- 确认操作系统环境支持:推荐 CentOS 7+/Ubuntu 20.04+,提前安装 Tongsuo 开发包(
tongsuo-devel)和构建工具链
配置国密双证书与混合加密套件
国密合规要求同时部署 SM2 证书(用于签名/密钥交换)和 RSA 证书(兼容国际客户端),Nginx 需配置双证书及国密优先的 TLS 协议栈:
- 证书文件需包含:
sm2.crt(SM2 公钥证书)、sm2.key(SM2 私钥)、rsa.crt、rsa.key;私钥必须为未加密 PEM 格式 - 在 server 块中启用双证书:
ssl_certificate /path/to/sm2.crt; ssl_certificate_key /path/to/sm2.key; ssl_certificate /path/to/rsa.crt; ssl_certificate_key /path/to/rsa.key;
- 指定国密 TLS 版本与套件(以 nginx-tongsuo 为例):
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECC-SM4-CBC-SM3:ECDHE-SM4-CBC-SM3:RSA-SM4-CBC-SM3; ssl_ecdh_curve sm2p256v1;
注意:ECC-SM4-CBC-SM3 是国密标准套件,仅国密客户端可协商;国际客户端会回退至 RSA-SM4-CBC-SM3 或其他兼容套件(需确保 openssl_conf 启用 legacy provider)。
验证国密握手与客户端兼容性
部署后必须实测国密握手是否生效,不能仅依赖配置语法正确:
- 使用国密浏览器(如红莲花、360安全浏览器国密版)或命令行工具
openssl s_client -connect example.com:443 -tls1_2 -cipher ECC-SM4-CBC-SM3(需链接 Tongsuo 的 openssl) - 检查 Nginx error log 是否出现
SSL_do_handshake() failed或no suitable key share,常见于曲线不匹配或证书链缺失 SM2 中间证书 - 通过
ssldump或 Wireshark 抓包,确认 ClientHello 中是否携带sm2p256v1曲线与国密套件标识
运维注意事项与常见坑
国密 Nginx 上线后需持续关注以下细节:
- 证书更新需同步替换双证书:SM2 和 RSA 证书有效期通常不同,自动化脚本必须同时 reload 两组文件
-
日志中无法直接区分国密/国际会话:可通过自定义 log_format 记录
$ssl_cipher,再过滤含SM3/SM4的条目 - 健康检查探针可能失败:默认 curl/wget 不支持国密套件,LVS 或 K8s readiness probe 需改用支持国密的客户端(如 tongsuo-curl)或降级为 HTTP 探活
- 动态模块加载受限:nginx-tongsuo 不兼容部分第三方模块(如 lua-nginx-module 的旧版本),升级前务必验证模块兼容性











