用户要编译支持国密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上进行编译呢?如果有具体的报错信息,也可以随时贴上来,我帮用户看看具体是哪里出了问题~