用户要编译支持国密SM2的Nginx,本质上是用一个支持国密的加密库(如`GmSSL`)来替换掉标准Nginx所使用的`OpenSSL`库。

目前主要有两种主流的方案,都可以实现你的目标:

方案一:使用  GmSSL  +  OpenSSL  兼容层(通用性强,推荐)

这种方案通过在标准Nginx源码旁,配置一个GmSSL加密库和一个兼容层来实现。兼容层作为桥梁,让Nginx能顺利调用GmSSL提供的国密算法功能。

操作步骤概览:

1.    下载源码:获取GmSSL、兼容层和Nginx的源码。

2.    编译安装:先编译安装GmSSL,再在编译Nginx时指向兼容层路径。

3.    配置生效:修改Nginx配置文件,指定国密证书和加密套件。

以下是具体的命令行操作步骤。

1.  环境准备与依赖安装

bash

#  安装编译工具和依赖库(以CentOS为例)

yum  install  -y  gcc  gcc-c++  make  pcre-devel  zlib-devel

#  Ubuntu/Debian  使用:apt-get  install  -y  build-essential  libpcre3-dev  zlib1g-dev

2.  下载并编译GmSSL

bash

#  创建工作目录并下载GmSSL(以3.x版本为例)

mkdir  -p  /usr/local/src/gmssl  &&  cd  /usr/local/src/gmssl

git  clone  https://github.com/Guanzhi/GmSSL.git

cd  GmSSL

#  编译安装

./config  --prefix=/usr/local/gmssl

make  -j$(nproc)

make  install

#  配置动态库路径

echo  '/usr/local/gmssl/lib'  >  /etc/ld.so.conf.d/gmssl.conf

ldconfig

注意:务必配置动态库路径  (`ldconfig`),否则后续编译或运行时会报找不到库文件的错误。

3.  下载并编译支持国密的Nginx

这里我们使用  `nginx-gm`  这个社区维护的国密版,它已经适配好相关接口,使用起来更稳定。

bash

#  下载nginx-gm源码

cd  /usr/local/src

git  clone  https://github.com/nginx-gm/nginx-gm.git

cd  nginx-gm

#  配置编译选项(关键步骤)

./configure  \

prefix=/usr/local/nginx  \

with-http_ssl_module  \

with-openssl=/usr/local/src/gmssl/GmSSL  \

with-openssl-opt='enable-ntls  enable-sm2  enable-sm3  enable-sm4'  \

with-http_v2_module

#  编译并安装

make  -j$(nproc)

make  install

在  `./configure`  阶段,务必通过  `--with-openssl`  参数指向GmSSL的源码目录,并通过  `--with-openssl-opt`  明确开启国密相关的功能,否则Nginx将无法识别国密算法。

4.  配置Nginx使用国密证书

编译安装完成后,你需要修改Nginx的配置文件(通常是  `/usr/local/nginx/conf/nginx.conf`)来加载国密证书。

nginx

server  {

        listen  443  ssl;

        server_name  your-domain.com;

        #  签名证书和私钥

        ssl_certificate          /path/to/your/SS_sign.crt;

        ssl_certificate_key  /path/to/your/SS_sign.key;

        #  加密证书和私钥(国密双证书结构)

        ssl_certificate_enc          /path/to/your/SE_enc.crt;

        ssl_certificate_key_enc  /path/to/your/SE_enc.key;


        #  启用国密加密套件

        ssl_ciphers  "ECDHE-SM2-WITH-SMS4-SM3:ECDHE-SM2-WITH-SMS4-GCM-SM3";

        ssl_protocols  TLSv1.2  TLSv1.3;

        ssl_prefer_server_ciphers  on;

}

方案二:使用  Tongsuo  +  nginx-tongsuo(阿里系方案,功能完善)

这是由阿里云开源的方案,`Tongsuo`(铜锁)是一个功能更丰富的密码学库,`nginx-tongsuo`则是与之配套的Nginx发行版,同样可以方便地编译使用。

1.    下载源码:

        bash

        git  clone  https://github.com/Tongsuo-Project/Tongsuo.git

        git  clone  https://github.com/Tongsuo-Project/nginx-tongsuo.git

2.    编译步骤:

        bash

        cd  nginx-tongsuo

        ./configure  --with-openssl=../Tongsuo  \

                                --with-http_ssl_module  \

                                --with-openssl-opt='enable-ntls'  #  关键:启用国密

        make  &&  make  install

3.    配置与使用:`nginx-tongsuo`的配置与`nginx-gm`类似,同样支持双证书配置。

关键要点与建议

双证书结构:国密SSL证书使用双证书体系,即一个用于签名的签名证书,和一个用于加密的加密证书。在Nginx中需要通过  `ssl_certificate`  和  `ssl_certificate_enc`  这两个指令分别指定。

客户端兼容性:配置好国密Nginx后,需要使用支持国密的专用浏览器(如红莲花、奇安信可信浏览器)来访问,标准浏览器(如Chrome)无法直接建立国密连接。

推荐生产方案:如果你的网站需要同时兼容国密和国际标准浏览器,可以考虑部署SM2/RSA双证书方案,实现自适应加密。

常见问题排查

如果在编译或启动过程中遇到问题,可以按以下思路排查

错误现象      可能原因        解决建议

  `gmssl:  error  while  loading  shared  libraries...`      GmSSL的动态库路径未注册  |  检查并确认`ldconfig`步骤执行成功  

  `SSL_CTX_use_certificate_chain_file...`      国密证书文件格式或内容错误        确保证书为PEM格式,并包含完整的证书链  

  Nginx启动报错  `unknown  directive  "ssl_certificate_enc"`      编译时未正确加载国密模块      重新编译Nginx,并确保`--with-openssl-opt`中包含`enable-ntls`  

  浏览器访问时无法建立安全连接      未使用支持国密的浏览器      切换至国密专用浏览器访问  

编译时找不到`openssl`头文件      `./configure`脚本未找到源码路径      检查`--with-openssl`参数指向的路径是否正确  

用户目前是在CentOS还是Ubuntu上进行编译呢?如果有具体的报错信息,也可以随时贴上来,我帮用户看看具体是哪里出了问题~