Docker 中配置国密 SSL证书,核心思路是选择一个内置国密算法的 Web 服务器或编程语言镜像,通过卷挂载引入证书,最后进行配置。虽然流程上与配置国际 TLS 相似,但难点主要在于架构选择和镜像的定制。下面我就说一下如何选择和定制。
一、前置知识与方案选型
国密通信的核心差异在于其要求使用 双证书机制(一个签名证书,一个加密证书)和以 SM2/SM3/SM4 为代表的国密算法套件。
在构建国密容器时,主流方案可以分为以下三类:
方案类型 核心方法 优点 缺点
已集成国密的Docker镜像 直接使用社区预制的 `gmssl/gmssl-server-nginx` 等镜像,或购买商业支持(如沃通/CFCA国密镜像)。 部署最快,开箱即用。 版本可能滞后,依赖社区或商业服务。
基于主流镜像进行改造 在 `Nginx:latest` 等通用镜像内,手动编译支持国密的 OpenSSL(如铜锁/Tongsuo)。 安全性高,版本可控。 构建复杂,镜像体积大,维护成本高。
轻量级微服务框架(如Java) 使用 `openjdk` 基础镜像,并改造其安全提供者(如 `cn.gmssl.jce.GmSSLProvider`)。 与应用结合紧密,适合Java技术栈。 涉及JVM层改造,对Java生态依赖度较高。
二、战部署:以 Nginx/Tengine 为例
一个高效的做法是利用支持国密的 Nginx 发行版(如 Tengine)配合国密库(如 Tongsuo)来构建镜像。下面是详细的 Docker 部署流程。
第一步:准备国密证书
首先,从 CA 机构获取或自签名生成国密双证书。一个完整的国密证书包至少应包含以下 4 个文件:
文件名示例 用途说明
`sm2.server.crt.pem` 服务器签名证书,用于身份验证。
`sm2.server.key.pem` 签名证书对应的私钥,服务器保管。
`sm2.enc.crt.pem` 服务器**加密证书**,用于密钥协商。
`sm2.enc.key.pem` 加密证书对应的私钥,建议与签名私钥分开保管。
如果你是在测试环境,也可以使用工具生成自签名证书。
使用 GmSSL 生成:可以安装 GmSSL 工具,并使用 `gmssl` 命令生成所需证书。
使用 Tongsuo 生成:安装铜锁(Tongsuo),并根据其命令行交互生成国密证书。
第二步:编写 Dockerfile 构建国密镜像
dockerfile
# 以 CentOS 为基础镜像
FROM centos:7
# 安装编译依赖
RUN yum install -y wget gcc gcc-c++ make pcre pcre-devel gzip zlib-devel \
&& yum clean all
# 1. 下载并编译国密库 (Tongsuo)
WORKDIR /usr/local/src
ENV TONGSUO_VERSION=8.4.0
RUN wget -c https://github.com/Tongsuo-Project/Tongsuo/archive/refs/tags/${TONGSUO_VERSION}.tar.gz \
&& tar zxf ${TONGSUO_VERSION}.tar.gz \
&& cd Tongsuo-${TONGSUO_VERSION} \
&& ./config --prefix=/usr/local/tongsuo enable-ntls enable-ssl-trace enable-weak-ssl-ciphers -Wl,-rpath,/usr/local/tongsuo/lib \
&& make -j && make install \
&& cd .. && rm -rf Tongsuo-${TONGSUO_VERSION} ${TONGSUO_VERSION}.tar.gz
# 2. 下载并编译 Nginx (带国密模块)
ENV TENGINE_VERSION=3.1.0
RUN wget -c https://github.com/alibaba/tengine/archive/refs/tags/${TENGINE_VERSION}.tar.gz \
&& tar zxf ${TENGINE_VERSION}.tar.gz \
&& cd tengine-${TENGINE_VERSION} \
&& ./configure --prefix=/usr/local/tengine \
--with-openssl=/usr/local/src/Tongsuo-${TONGSUO_VERSION} \
--with-openssl-opt="enable-ntls" \
--with-http_ssl_module \
--with-http_stub_status_module \
--add-module=modules/ngx_tongsuo_ntls \
&& make -j && make install \
&& cd .. && rm -rf tengine-${TENGINE_VERSION} ${TENGINE_VERSION}.tar.gz
# 设置环境变量
ENV PATH="/usr/local/tengine/sbin:${PATH}"
# 准备配置目录
RUN mkdir -p /etc/nginx/conf.d
# 复制配置文件(将在第三步创建)
COPY nginx.conf /usr/local/tengine/conf/nginx.conf
COPY conf.d/*.conf /etc/nginx/conf.d/
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
第三步:配置国密 SSL 参数
创建 Nginx 配置文件,其中的关键是正确配置双证书并指定国密套件。
nginx
server {
listen 443 ssl;
server_name your.domain.com;
# 国密双证书配置(签名证书 + 加密证书)
ssl_certificate /path/to/certs/sm2.server.crt.pem;
ssl_certificate_key /path/to/certs/sm2.server.key.pem;
ssl_certificate /path/to/certs/sm2.enc.crt.pem;
ssl_certificate_key /path/to/certs/sm2.enc.key.pem;
# 优先使用国密密码套件
ssl_ciphers 'ECDHE-SM2-SM4-GCM-SM3:ECDHE-SM2-SM4-CBC-SM3:SM2-SM4-GCM-SM3';
ssl_prefer_server_ciphers on;
# 其他 SSL 配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# 网站根目录等配置
# ...
}
第四步:使用 Docker Compose 进行统一部署
yaml
version: '3.8'
services:
gm-nginx:
build:
context: .
dockerfile: Dockerfile
ports:
- "443:443"
volumes:
- ./certs:/path/to/certs:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./logs:/var/log/nginx
restart: always
三、证书管理与安全实践
为避免敏感信息泄露,建议采用更安全的证书管理方式:
使用 Docker Secrets:在 Docker Swarm 模式下,可使用 `docker secret create` 将证书作为 Secret 管理,并在 `docker-compose.yml` 的 `secrets` 字段中引用。
外部卷挂载:在 `docker-compose.yml` 中使用 `volumes` 将宿主机目录挂载进容器,适合单机或非 Swarm 环境。
Kubernetes + cert-manager:在 K8s 环境中,可搭配 `cert-manager` 与支持国密的 CA 插件,实现证书的自动化申请与轮换。
四、关键注意事项
1. 浏览器兼容性:全球主流浏览器(Chrome, Firefox, Safari)不支持**国密协议。商用部署时,需配合专用的国密浏览器(如 360 企业安全浏览器)访问,或采用兼容性更强的"国际+国密双证书"方案。
2. 性能考量:容器化国密网关性能强劲,实测 QPS 可达 2870 次/秒,与传统部署性能差异不足 5%,加解密延迟可控制在 11ms 以内,完全满足金融级场景需求。
3. GPU 加速:在高并发场景下,若条件允许,可以考虑配置 GPU 资源来卸载 SM2 等非对称加密的算力压力,进一步提升性能。
4. 应急方案:务必同时准备国际 SSL证书作为备选,避免因国密协议问题导致服务中断。
如果你在实操过程中遇到具体问题,欢迎继续提问。