用户要通过编译的方式让 Nginx 支持国密算法,核心在于使用 `--with-openssl` 参数,将其指向一个能处理国密算法的 OpenSSL 实现,而不是依赖操作系统自带的版本。
下面我说一下完整的操作步骤:
一、准备工作:确保基础环境就绪
在开始编译前,需要一个干净的 Linux 环境,并安装好 gcc、make 等基本编译工具。
下载源码
Nginx源码:从 [nginx.org](https://nginx.org/en/download.html) 下载一个稳定版本,例如 `nginx-1.24.0.tar.gz`。
国密支持库源码:请根据需求选择并下载一个支持国密的 OpenSSL 版本。
GmSSL:是一个广泛使用的、为 OpenSSL 增加国密算法支持的开源分支。建议选择最新的 3.x 稳定版。
Tongsuo (原 BabaSSL):是一个支持国密标准(如 NTLS)的通用密码库,由阿里云等发起。
openHiTLS:一个新兴的、架构更现代的密码库,支持国密算法。
PCRE 和 zlib 源码:Nginx 的两个核心依赖库。建议一并下载成源码,用 `--with-pcre=` 和 `--with-zlib=` 参数指定,避免依赖系统库版本不兼容。
编译 GmSSL (以 GmSSL 为例)
如果选择 GmSSL,需要先编译它。假设将 GmSSL 源码解压到 `/path/to/gmssl` 目录:
bash
cd /path/to/gmssl
./config --prefix=/usr/local/gmssl # 配置安装路径
make -j$(nproc) # 编译,-j参数指定并行任务数
sudo make install # 安装到指定路径
二、编译 Nginx:核心步骤
这一步是重点,需要在 Nginx 的 `./configure` 命令中加入特定参数。
1. 进入 Nginx 源码目录
bash
cd /path/to/nginx-1.24.0
2. 配置编译选项
执行 `./configure`,关键参数含义如下:
`--with-openssl=/path/to/gmssl`:最关键参数,必须指向 GmSSL 的源码目录(即解压后的根目录),而不是编译安装后的路径。
`--with-cc-opt="-I/usr/local/gmssl/include"`:添加头文件搜索路径,确保能找到 GmSSL 的 `crypto.h` 等头文件。
`--with-ld-opt="-L/usr/local/gmssl/lib"`:添加库文件搜索路径,确保链接器能找到 GmSSL 的 `libcrypto.a` 和 `libssl.a` 等静态库。
`--with-http_ssl_module`:启用 SSL/TLS 模块,这是使用 HTTPS 服务所必需的。
`--with-pcre=/path/to/pcre` 和 `--with-zlib=/path/to/zlib`:分别指定 PCRE 和 zlib 库的源码路径。
`--with-pcre-jit`:启用 PCRE JIT 编译,提升正则表达式处理性能。
* `--with-http_v2_module`:可选,启用 HTTP/2 协议支持。
一个完整的配置命令示例如下:
bash
./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-pcre=/path/to/pcre2-10.42 \
--with-zlib=/path/to/zlib-1.3.1 \
--with-openssl=/path/to/gmssl \
--with-cc-opt="-I/usr/local/gmssl/include" \
--with-ld-opt="-L/usr/local/gmssl/lib"
3. 编译与安装
bash
make -j$(nproc) # 使用所有CPU核心编译,速度快
sudo make install # 默认安装到 /usr/local/nginx
4. 验证
编译安装后,用以下命令验证:
bash
/usr/local/nginx/sbin/nginx -V 2>&1 | grep -i 'openssl\|gmssl'
这条命令应该会输出你在 configure 中指定的 GmSSL 版本号,例如 `built with OpenSSL 3.1.1-gm`,以此确认编译链路正确。
三、配置文件关键项:让国密生效
光编译还不够,还需要在 `nginx.conf` 中正确配置,才能让 Nginx 使用国密功能:
nginx
server {
listen 443 ssl;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; # 或 GMv1,视具体情况而定
# 配置国密加密套件,顺序决定了协商优先级
ssl_ciphers ECC-SM2-WITH-SM4-SM3:ECDHE-SM4-SM3:...; # 请务必包含国密套件
# 加载国密签名证书和私钥
ssl_certificate /path/to/sm2_sign.crt.pem;
ssl_certificate_key /path/to/sm2_sign.key.pem;
# 如需支持“国密双证书”(签名证书+加密证书),请额外配置
# ssl_certificate /path/to/sm2_enc.crt.pem;
# ssl_certificate_key /path/to/sm2_enc.key.pem;
}
实际操作时,加密套件的名称取决于你使用的国密库,需要参考它的官方文档或兼容性列表。
四、避坑指南:常见问题与对策
库文件过期 (GmSSL):GmSSL 的测试版可能有使用期限,若 Nginx 启动失败,提示类似“expired. Please update new version!!!”,请访问 [GmSSL官网](https://www.gmssl.cn/) 下载最新的稳定版本,并重新编译 Nginx。
证书格式错误:如果 Nginx 启动时提示证书无法解析,请确保:
证书和私钥文件的路径配置正确。
文件格式是 Linux 下的 UTF-8 编码,没有 Windows 格式的换行符。如有问题,可使用 `dos2unix` 工具转换。
私钥文件的权限设置正确,通常为 `600`,属主为 `nginx` 运行用户。
浏览器访问失败:标准的国际浏览器(如 Chrome、Firefox)不支持国密算法,访问时会报错。必须使用支持国密的专用浏览器(如密信浏览器、红莲花浏览器)或经过改造的浏览器进行测试访问。
Nginx 启动路径错误:如果服务器上已有通过包管理器安装的 Nginx,重新编译后需要确认服务脚(例如 `/usr/lib/systemd/system/nginx.service`)中的启动路径是否正确指向了新编译的二进制文件(默认在 `/usr/local/nginx/sbin/nginx`),以避免因路径不正确而导致国密不生效。
五、总结
实现 Nginx 国密支持,本质上就是用支持国密的 OpenSSL 库替代系统默认的版本。掌握这个核心逻辑,并留意我上面提到的这些常见坑点,整个编译配置过程会更加顺畅。