一、国密SSL反向代理的核心场景
方案选择速查表
场景 方案 复杂度 配置位置
Apache → 国密后端的明文HTTP 不启用SSLProxyEngine 低 仅ProxyPass
Apache ↔ 国密后端的加密通道 专用国密版Apache 高 全链路配置
前后端不同类型证书(RSA+SM2混合) 端口分离 中 独立VirtualHost
二、基础环境准备:编译支持国密的Apache
官方Apache + OpenSSL 不原生支持国密算法(SM2/SM3/SM4),需要替换为国密增强版OpenSSL(如GMSSL),然后重新编译Apache。各大云厂商也已适配该方案。
方案:国密增强版OpenSSL + 官方Apache源码
步骤1:安装编译依赖
bash
# CentOS/RHEL
yum install -y gcc gcc-c++ wget make perl pcre-devel expat-devel bison bison-devel flex flex-devel
# Ubuntu/Debian
apt-get install -y build-essential wget libpcre3-dev libexpat1-dev libssl-dev
步骤2:编译安装国密版OpenSSL(GMSSL)
从国密生态官方渠道获取GMSSL源码后编译安装。GMSSL基于OpenSSL增加了SM2、SM3、SM4算法支持。
步骤3:下载并编译Apache
bash
wget https://archive.apache.org/dist/httpd/httpd-2.4.48.tar.gz
tar -zvxf httpd-2.4.48.tar.gz
cd httpd-2.4.48/
./configure --prefix=/usr/local/httpd \
--enable-so --enable-ssl --enable-cgi \
--enable-rewrite --enable-mpms-shared=all \
--with-ssl=/usr/local/gmssl # 指向国密OpenSSL路径
make && make install
配置时需要明确指向编译好的国密OpenSSL路径,确保Apache使用的SSL库为国密版本。
三、核心配置场景与代码示例
场景1:标准反向代理(Apache启用国密对外 → 后端HTTP)
这是最常见的使用场景,客户端使用国密HTTPS访问Apache,Apache以HTTP转发给后端服务。**后端HTTP服务无需任何国密改造**,因为加密仅发生在客户端与Apache之间。
apache
<VirtualHost *:443>
ServerName www.example.com
# ===== 国密SSL配置(对外接收客户端请求) =====
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/sm2_server.crt
SSLCertificateKeyFile /etc/httpd/ssl/sm2_server.key
# 启用国密算法套件(根据权威指导优先使用GCM模式)
SSLCipherSuite ECDHE-SM2-WITH-SM4-GCM-SM3:ECDHE-SM2-WITH-SM4-CBC-SM3
SSLProtocol TLSv1.2
# ===== 反向代理配置(转发到后端HTTP) =====
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}e"
# 将请求代理到后端HTTP服务(无SSL加密)
ProxyPass /api/ http://192.168.1.100:8080/
ProxyPassReverse /api/ http://192.168.1.100:8080/
# 可选:排除某些路径不代理
ProxyPass /static/ !
</VirtualHost>
场景2:全链路国密加密(Apache ← 国密 → 后端HTTPS)
当后端服务也需国密加密保护时,Apache作为国密客户端发起连接。这对后端服务要求较高,需要后端服务也支持国密协议。
apache
<VirtualHost *:443>
ServerName www.example.com
# ===== 前端国密SSL配置(接收客户端) =====
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/sm2_frontend.crt
SSLCertificateKeyFile /etc/httpd/ssl/sm2_frontend.key
SSLCipherSuite ECDHE-SM2-WITH-SM4-GCM-SM3:ECDHE-SM2-WITH-SM4-CBC-SM3
SSLProtocol TLSv1.2
# ===== 启用国密客户端代理引擎(连接后端) =====
SSLProxyEngine on
SSLProxyProtocol TLSv1.2
SSLProxyCipherSuite ECDHE-SM2-WITH-SM4-GCM-SM3:ECDHE-SM2-WITH-SM4-CBC-SM3
# 信任后端国密证书的CA链(PEM格式)
SSLProxyCACertificateFile /etc/httpd/ssl/backend_ca_bundle.crt
# 强制校验证书(生产环境必须开启)
SSLProxyVerify require
SSLProxyVerifyDepth 2
SSLProxyCheckPeerName on
SSLProxyCheckPeerExpire on
# ===== 反向代理配置(国密到后端) =====
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "https"
# 转发至支持国密的后端服务
ProxyPass /api/ https://192.168.1.101:8443/
ProxyPassReverse /api/ https://192.168.1.101:8443/
</VirtualHost>
场景3:双证书部署(SM2 + RSA混合)
为兼容各类浏览器,生产环境通常采用SM2/RSA双证书部署。SM2证书用于国密浏览器(如密信浏览器、红莲花浏览器),RSA证书兼容主流浏览器。需监听不同端口或依赖SNI区分。
apache
# RSA证书的VirtualHost(监听443端口)
<VirtualHost *:443>
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/rsa_server.crt
SSLCertificateKeyFile /etc/httpd/ssl/rsa_server.key
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5
# ... 反向代理配置
</VirtualHost>
# SM2证书的VirtualHost(监听8443端口,供国密浏览器访问)
<VirtualHost *:8443>
SSLEngine on
SSLCertificateFile /etc/httpd/ssl/sm2_server.crt
SSLCertificateKeyFile /etc/httpd/ssl/sm2_server.key
SSLCipherSuite ECDHE-SM2-WITH-SM4-GCM-SM3
SSLProtocol TLSv1.2
# ... 反向代理配置
</VirtualHost>
四、进阶配置
4.1 客户端证书认证(mTLS)
若后端需要Apache提供客户端证书进行身份验证,可使用`SSLProxyMachineCertificateFile`将所有内容合并,或分别使用`SSLProxyCertificateFile`和`SSLProxyCertificateKeyFile`:
apache
SSLProxyEngine on
# 合并方式(证书在前,私钥在后)
SSLProxyMachineCertificateFile /etc/httpd/ssl/apache_client.pem
4.2 多路径精细化代理
apache
ProxyPass /api/v1/ https://backend1:8443/ retry=0 timeout=30
ProxyPass /api/v2/ https://backend2:8443/ retry=3 timeout=45
ProxyPass /socket/ ws://backend:8080/ # WebSocket协议
4.3 SSL卸载权衡建议
建议加密:公网或跨信任域传输、数据敏感(支付、个人信息)、合规审计场景
建议明文:后端与Apache同在一个可信内网、非敏感数据、对性能要求极高
五、故障排查
常见错误与解决方案
错误现象 可能原因 解决方案
`SSLProxyEngine not enabled` 未在VirtualHost内正确配置SSLProxyEngine 将`SSLProxyEngine on`置于正确的作用域内
`SSL handshake failed / certificate verify failed` 国密后端证书无法验证 使用`SSLProxyCACertificateFile`指定信任的CA证书文件
`unable to get local issuer certificate` CA证书链不完整或路径错误 | 确保证书链包含完整的根证书和中间证书
`Peer certificate does not match hostname` 证书中的域名与ProxyPass中配置的目标域名不匹配 | 确保证书SAN包含目标域名
调试命令
bash
# 验证国密证书有效性
openssl s_client -connect backend.internal:8443 -CAfile /path/to/ca-bundle.crt
# 排查证书链
openssl s_client -connect backend.internal:8443 -showcerts
# 查看Apache详细日志
tail -f /var/log/httpd/error_log
# 开启debug级别(用于深入调试)
LogLevel ssl:debug proxy:debug
六、快速部署核对清单
Apache使用国密增强版OpenSSL编译(非官方默认版本)
已安装`mod_ssl`、`mod_proxy`、`mod_proxy_http`等核心模块
服务器443端口已开放
国密证书文件已上传至指定目录,权限为600(私钥需严格保护)
VirtualHost中正确配置国密算法套件(优先GCM模式)
反向代理指向正确的后端服务地址和端口
`SSLProxyEngine`已根据需要开启
已配置`ProxyPass`和`ProxyPassReverse`指令
已配置请求头透传(`X-Forwarded-*`)
双证书场景(如需兼容)已完成独立端口配置
生产环境已关闭调试日志,提升性能与安全
如需更具体的定制化配置细节,可提供后端服务的详细情况,我可以给出更具针对性的配置建议。