一、常见国密错误类型速查

1.  基础配置错误

错误现象      日志关键线索      根本原因      快速解决  

Nginx  启动失败,报  `unknown  cipher`      `unknown  cipher  "TLS_SM4_GCM_SM3"`      未加载国密模块,或  `ssl_ciphers`  中写了国密套件但底层密码库不支持      换用  Tengine+Tongsuo  或  openresty-gm  等支持国密的版本  

  `ssl_certificate`  或  `ssl_certificate_key`  报错      `cannot  load  certificate  "xxx"`,  `PEM_read_bio_X509_AUX()  failed`      证书路径错误、文件权限不足或证书格式不正确  |  检查路径,确保私钥权限为  600,属主为  Nginx  运行用户  

SM2  私钥加载失败      无明确错误,但  `nginx  -t`  通过后握手直接断连      证书  OID  不是国密标准  OID(`id-sm2`),或私钥非  GmSSL  工具链生成      使用  `gmssl  genpkey  -algorithm  sm2  -out  sm2.key`  重新生成私钥和证书  

  `ssl_reject_handshake  on`  导致国密无法使用      配置该指令后国密握手全部失败      该指令被设置为  `on`  时,Nginx  会在  SSL  握手阶段直接拒绝所有连接,包括国密握手      将该指令显式设置为  `off`,或在单独  server  块中按域名正确处理  SNI  

2.  握手协商错误

  错误日志中的关键信息      含义      常见于国密场景的原因    排查方向  

`no  shared  cipher`  |  客户端与服务端没有共同的密码套件      ①  `ssl_ciphers`  中未配置国密套件(如  `TLS_SM4_GCM_SM3`);②  客户端浏览器不支持国密算法      检查  `ssl_ciphers`  是否正确包含国密套件;换用奇安信、360  国密版等支持国密的浏览器访问  

  `version  too  low`      客户端  TLS  版本低于服务端允许的最低版本      国密双证书场景中,客户端与服务端  GmSSL  版本差异较大,导致握手版本协商失败      统一客户端与服务端的  GmSSL  版本;确保  `ssl_protocols`  包含了客户端所使用的  TLS  版本  

  `tlsv1  alert  unknown  ca`      客户端不信任服务端证书链中的  CA      国密证书链不完整,中间证书或根证书缺失      检查证书链拼接:`cat  server_sm2.crt  intermediate_sm2.crt  root_sm2.crt  >  fullchain_sm2.crt`  

`tlsv1  alert  decrypt  error`      握手过程中的解密错误      GmSSL  版本不一致导致密钥交换或证书验证环节出错;也可能与证书链问题或密码套件不匹配有关      统一  GmSSL  版本;验证证书与私钥是否匹配;确保协议套件配置正确  

3.  证书与文件错误

错误日志关键词      含义      国密场景常见原因      解决方法  

  `SSL_do_handshake()  failed`  无其他详细错误    Nginx  未记录详细握手失败原因      ①  国密模块编译时未启用  debug  支持;②  默认  `error_log`  级别(如  warn)太低,未输出底层错误细节      ①  启用  `debug`  日志级别;②  确保编译时包含  `--with-debug`  参数;③  重新编译时添加国密扩展支持  

`peer  closed  connection  in  SSL  handshake`      对端在握手阶段关闭了连接      ①  客户端国密浏览器与服务器国密算法实现不兼容;②  使用了自签名证书但客户端未信任该  CA  |  检查证书链完整性;使用可信  CA  签发的证书或配置客户端信任自签名  CA;使用奇安信/360  国密版浏览器测试  

  `cannot  load  certificate`      无法加载  SSL  证书      ①  证书文件损坏或格式不支持(SM2  证书需要使用带正确  OID  的  PEM  格式);②  Nginx  用户无读取权限      使用  `gmssl  x509  -in`  检查证书格式;确保  Nginx  进程用户(如  `www-data`)有读取权限  

客户端提示  `ERR_CERT_AUTHORITY_INVALID`      浏览器提示证书颁发机构无效      国密证书链不完整,中间证书未正确配置到  `fullchain`  文件中      按正确顺序拼接证书链;确保  `ssl_certificate`  指向包含完整链的  PEM  文件  

二、Error.log  配置调优(让日志“说话”)

Nginx  默认的  `error_log`  级别几乎不记录握手细节,必须显式开启才能捕捉到真实的国密握手错误。

第一步:启用  debug  日志

nginx

#  在  main(全局)或至少  http  块中添加

error_log  /var/log/nginx/ssl_debug.log  debug;

注意事项:

  debug  日志量极大(可能每秒数千行),仅用于**临时排查**,生产环境问题定位后必须调回  `info`  或  `warn`

  若启动时报  `unknown  log  level  "debug"`,说明  Nginx  未带  debug  支持,需重新编译并加上  `--with-debug`,或换用已包含  debug  的二进制包

第二步:验证编译参数是否包含  debug

bash

nginx  -V  2>&1  |  grep  -o  with-debug

#  若有输出,说明  debug  支持已启用

第三步:确认国密模块是否已正确集成

bash

nginx  -V  2>&1  |  grep  --  Tongsuo

#  或

nginx  -V  2>&1  |  grep  --  gmssl

#  若输出中包含  --add-module=../tongsuo-nginx  或类似内容,说明已集成

第四步(可选):在  access_log  中增加  TLS  细节,辅助快速定位

nginx

log_format  tls_detail  '$remote_addr  [$time_local]  "$request"  $status  '

                                            '$ssl_protocol  $ssl_cipher  $ssl_server_name  $http_user_agent';

access_log  /var/log/nginx/access_tls.log  tls_detail;

配置后,每条访问日志会附带:实际协商的  TLS  版本(`$ssl_protocol`)、所选密码套件(`$ssl_cipher`)、客户端发送的  SNI  域名(`$ssl_server_name`)——可快速发现  SNI  不匹配或协议版本不对的问题。

第五步:配合关键配置确保握手能“走到”日志

  确认监听端口启用了  SSL:`listen  443  ssl  http2;`

  显式指定  TLS  版本和加密套件,避免协商失败静默降级

  若代理  HTTPS  上游,务必打开  SNI  并指定域名:`proxy_ssl_server_name  on;`

  如需验证上游证书,必须配置可信  CA:`proxy_ssl_verify  on;  proxy_ssl_trusted_certificate  ...;`

三、常见国密错误码解读表

错误码  /  关键日志      国密专属解读      排查优先级  

  `no  shared  cipher`      服务端国密套件与客户端(浏览器)支持的套件无交集——通常是因为客户端不支持国密            高  

  `version  too  low`      TLS  版本协商失败,常见于国密双证书场景中  GmSSL  版本差异过大        高  

`tlsv1  alert  unknown  ca`      国密证书链不完整          中  

  `tlsv1  alert  decrypt  error`      与国密双证书加密证书/签名证书配对失败或  GmSSL  版本不匹配高度相关          中  

  `peer  closed  connection  in  SSL  handshake`      自签名国密证书未在客户端配置信任        低  

  `PEM_read_bio_X509_AUX()  failed`      国密证书文件不是标准  PEM  格式,或  OID  不是  `id-sm2`            中    

四、国密专属配置与排查建议

1.  确认国密运行环境完整性

国密不是通过简单配置就能启用的功能。原生  Nginx  +  普通  OpenSSL  不可能支持  SM2/SM3/SM4。正确的国密环境应该满足:

  使用  Tengine  +  Tongsuo,或  openresty-gm(OpenResty  国密分支)

  密码库必须使用  GmSSL  而非标准  OpenSSL(`openssl  version`  输出应包含  `GmSSL`  字样)

  国密证书必须通过  GmSSL  工具链生成,证书中  Subject  Public  Key  Info  必须为  `sm2`  OID

2.  快速定位思路(按日志排查优先级)

第一层:配置加载阶段错误

  Nginx  启动失败  →  检查配置文件语法(`nginx  -t`)

  报  `unknown  cipher`  →  确认已集成国密模块,且  `ssl_ciphers`  中包含国密套件

  报证书加载失败  →  检查文件路径、权限、格式(PEM)、OID

第二层:握手阶段错误(需开启  debug  日志)

  日志中只有  `SSL_do_handshake()  failed`  无细节  →  debug  日志未开启或  Nginx  未编译  debug  支持

  `no  shared  cipher`  →  客户端浏览器不支持国密,换用奇安信/360  国密版测试

  `tlsv1  alert  unknown  ca`  →  证书链不完整,重新拼接  fullchain

  `tlsv1  alert  decrypt  error`  →  证书与私钥不匹配,或  GmSSL  版本不一致

第三层:客户端访问失败但服务端无任何日志

  检查  `listen`  是否包含  `ssl`  参数

  检查防火墙是否放行  443  端口

  确认客户端确实是国密浏览器(普通  Chrome/Firefox  不支持国密)

3.  典型配置对照

nginx

#  国密服务端配置示例(Tengine  +  Tongsuo)

server  {

        listen  443  ssl;

        server_name  gm.example.com;

        #  国密证书配置

        ssl_certificate          /etc/nginx/certs/fullchain_sm2.crt;

        ssl_certificate_key  /etc/nginx/certs/server_sm2.key;

        #  协议与套件

        ssl_protocols  TLSv1.2  TLSv1.3;

        ssl_ciphers  ECDHE-SM2-WITH-SM4-SM3:TLS_SM4_GCM_SM3;

        #  调试用(生产环境及时移除)

        error_log  /var/log/nginx/gm_ssl_debug.log  debug;

        #  必须关闭硬拒绝模式,按  SNI  正确处理

        ssl_reject_handshake  off;

        #  SNI  相关配置

        proxy_ssl_server_name  on;

        proxy_ssl_name  "gm.example.com";

}

注意:

  使用国密证书时,需确保`ssl_certificate`指向包含完整证书链的PEM文件

  私钥文件权限应设置为`600`,属主为Nginx运行用户(如`www-data`)

  若使用自签名证书进行测试,需要将根证书手动导入到客户端信任库

五、常用诊断命令速查

目的      命令  

查看  Nginx  错误日志      `sudo  tail  -f  /var/log/nginx/error.log`  或  `/var/log/nginx/ssl_debug.log`  

验证配置文件语法      `sudo  nginx  -t`  

检查证书与私钥是否匹配      `openssl  x509  -noout  -modulus  -in  cert.crt  \    openssl  md5`<br>`openssl  rsa  -noout  -modulus  -in  key.key  \    openssl  md5`    

查看证书详细信息      `openssl  x509  -in  cert.crt  -text  -noout`  

检查国密模块是否集成      `nginx  -V  2>&1  \    grep  -E  "(Tongsuo\|gmssl)"`  

模拟国密客户端测试      使用奇安信可信浏览器或  360  安全浏览器(国密版)访问  

  在线深度检测      [SSL  Labs  SSL  Server  Test](https://www.ssllabs.com/ssltest/

总结

国密故障排查的核心要点:

1.  日志级别是关键:默认  error_log  级别太低,必须启用  debug  级别并确保编译时包含  `--with-debug`,否则国密握手失败的详细信息不会被记录。

2.  原生  Nginx  不支持国密:必须换用  Tengine+Tongsuo  或  openresty-gm  等专门改造过的版本。

3.  先判断错误发生的阶段:是配置加载失败、握手协商失败,还是证书信任问题?不同阶段的日志线索不同,针对性排查效率更高。

4.  注意浏览器兼容性:普通  Chrome/Firefox  不支持国密,必须使用奇安信可信浏览器、360  安全浏览器(国密版)等专用浏览器测试。

5.  排查后及时关闭  debug  日志:避免磁盘空间耗尽或性能下降。

如果某条具体报错日志仍无法定位,可将完整的错误信息(含时间戳和前后文)提交至国密社区或相关技术支持渠道进一步分析。