部署国密SSL证书时，为兼顾各类浏览器的兼容性，通常采用 SM2/RSA 双证书方案——同时在服务器上配置国际通用的 RSA 证书和国密标准的 SM2 证书。本文介绍如何使用 Tengine + Tongsuo（铜锁）组合在 Linux 服务器上部署双证书。

**重要**

本文以 Linux 操作系统、Tongsuo 8.2.1 和 Tengine 2.4.1 为例介绍，SSL 证书为 Wosign 品牌的 DV 证书。不同版本的部署操作可能有所差异。

## **背景信息**

Tengine 是一款基于 Nginx 的开源 Web 服务器和反向代理服务器，针对高访问量场景增加了多项高级功能和特性。更多说明请参见[Tengine官网](https://tengine.taobao.org)。

Tengine 已对铜锁/Tongsuo（原名 BabaSSL）完成适配，增加了对 NTLS（国密 TLS）的支持。需要使用国密算法进行安全通信的用户可以直接采用 Tengine + Tongsuo 方案。

**说明**

铜锁/Tongsuo 是提供现代密码学算法和安全通信协议的开源基础密码库，更多详情请参见[铜锁密码库](https://www.tongsuo.net/)。

## 前提条件

-   已通过数字证书管理服务签发国密标准证书（双证书方案还需要签发国际标准证书）。具体操作，请参见[购买正式证书](https://help.aliyun.com/zh/ssl-certificate/purchase-an-ssl-certificate#task-q3j-zfp-ydb)和[申请证书](https://help.aliyun.com/zh/ssl-certificate/apply-for-a-certificate)。
    
-   域名已正确解析至当前服务器，且已完成工信部 ICP 备案（适用于中国内地服务器）。
    
    **如何查看域名解析记录以及 ICP 备案信息**
    
    打开[网络拨测工具](https://boce.aliyun.com/home)，选择**网络诊断分析**，输入当前域名，确认以下信息：
    
    -   **DNS 服务商解析结果**中 A 记录的 IP 为当前服务器的公网 IP。
        
    -   **备案检查**为**网站已备案**。若显示“**网站未备案，请咨询网站服务器提供商**”，请完成备案后再安装证书。
        
        -   如果您使用的是阿里云服务器，请前往[阿里云备案系统](https://beian.aliyun.com/order/index?spm=a2c4g.11186623.0.0.31773cd9txeAI4)进行网站备案，具体操作请参见[ICP备案流程](https://help.aliyun.com/zh/icp-filing/basic-icp-service/user-guide/icp-filing-application-overview#title-vff-7fj-ag2)。
            
        -   如果您使用的不是阿里云服务器，请前往服务器提供商的备案系统或[工信部备案官网](https://beian.miit.gov.cn/)进行备案。
            
    
-   已获得本服务器的管理权限（即“root账号”或“有 sudo 权限”的账号）。
    

## **操作步骤**

### **步骤一：下载SSL证书**

1.  进入[SSL证书管理](https://yundunnext.console.aliyun.com/?p=cas#/instance/buy)页面，定位需部署的目标证书，并确认以下信息：
    
    1.  **证书状态**：确保其为**已签发**。若为**即将过期**或**已过期**，则需[续费SSL证书](https://help.aliyun.com/zh/ssl-certificate/user-guide/renew-ssl-certificate/)。
        
    2.  **绑定域名**：确保其能够匹配所有需保护的域名，否则未匹配的域名访问 HTTPS 时将出现安全警告。如需添加或修改，请参见[追加和更换域名](https://help.aliyun.com/zh/ssl-certificate/change-a-domain-name)。
        
        确认证书是否匹配目标域名
        
        证书的**绑定域名**可包含多个精确域名和通配符域名。每类域名的匹配规则如下：
        
        -   精确域名：仅对指定域名生效。
            
            -   `example.com` 仅对 `example.com` 生效。
                
            -   `www.example.com` 仅对 `www.example.com` 生效。
                
        -   通配符域名：仅对其一级子域名生效。
            
            -   `*.example.com` 对 `www.example.com`、`a.example.com` 等一级子域名生效。
                
            -   `*.example.com` 对根域名 `example.com` 和多级子域名 `a.b.example.com` 不生效。
                
        
        **说明**
        
        如需匹配多级子域名，**绑定域名**中需包含该域名（如 `a.b.example.com`），或包含相应的通配符域名（如 `*.b.example.com`）。
        
2.  在目标证书的**操作**列单击**下载**，然后下载**服务器类型**为 Nginx 的证书。
    
3.  解压下载的证书压缩包，其中包含以下文件：
    
    -   签名证书：`<证书绑定域名>_sm2_sign.pem` 和 `<证书绑定域名>_sm2_sign.key`。
        
    -   加密证书：`<证书绑定域名>_sm2_enc.pem` 和 `<证书绑定域名>_sm2_enc.key`。
        
        **说明**
        
        若申请证书时使用 OpenSSL 或 Keytool 生成 CSR 文件，私钥仅保存在本地，下载的证书包中不包含私钥。如私钥遗失，证书将无法使用，需重新[购买正式证书](https://help.aliyun.com/zh/ssl-certificate/purchase-an-ssl-certificate)并生成 CSR 和私钥。
        

### **步骤二：在Tengine服务器安装证书**

1.  登录 Linux 服务器。
    
    -   阿里云服务器：请参考[使用Workbench登录Linux实例](https://help.aliyun.com/zh/ecs/user-guide/connect-to-a-linux-instance-by-using-a-password-or-key)。
        
    -   非阿里云服务器：请通过对应厂商提供的远程连接功能登录服务器终端。
        
    
    后续部分命令因操作系统类型不同而略有差异。请根据实际的服务器操作系统，选择对应的命令操作。
    
    -   **RHEL/CentOS 系列**：包括 Alibaba Cloud Linux、Red Hat Enterprise Linux、CentOS、AlmaLinux、Rocky Linux、Anolis OS 及其衍生版本。
        
    -   **Debian/Ubuntu 系列**：包括 Debian、Ubuntu 及其衍生版本。
        
    
    **如何确认操作系统所属系列**
    
    在服务器终端执行 `cat /etc/os-release`，根据输出的 `ID_LIKE`、`ID` 判断：
    
    -   若 `ID_LIKE` 或 `ID` 包含 rhel 或 centos，操作系统属于 RHEL/CentOS 系列。
        
    -   若 `ID_LIKE` 或 `ID` 包含 debian 或 ubuntu，操作系统属于 Debian/Ubuntu 系列。
        
    
2.  开放安全组和防火墙的 443 端口。
    
    1.  在服务器终端执行以下命令，检测443端口的开放情况：
        
        #### **RHEL/CentOS**
        
        ```
        command -v nc > /dev/null 2>&1 || sudo yum install -y nc
        # 请将以下的 <当前服务器的公网 IP> 替换为当前服务器的公网 IP
        sudo ss -tlnp | grep -q ':443 ' || sudo nc -l 443 & sleep 1; nc -w 3 -vz <当前服务器的公网 IP> 443
        ```
        
        如果输出 `Ncat: Connected to <当前服务器公网 IP>:443`，则表明443端口已开放。否则需在安全组和防火墙中开放443端口。
        
        #### **Debian/Ubuntu**
        
        ```
        command -v nc > /dev/null 2>&1 || sudo apt-get install -y netcat
        # 请将以下的 <当前服务器的公网 IP> 替换为当前服务器的公网 IP
        sudo ss -tlnp | grep -q ':443 ' || sudo nc -l -p 443 & sleep 1; nc -w 3 -vz <当前服务器的公网 IP> 443
        ```
        
        若输出 `Connection to <当前服务器公网 IP> port [tcp/https] succeeded!` 或 `[<当前服务器公网 IP>] 443 (https) open`，则表明443端口已开放。否则需在安全组和防火墙中开放443端口。
        
    2.  在安全组配置开放443端口。
        
        请确保安全组已开放 443 端口 (TCP)，否则外部无法访问服务。以下操作以阿里云 ECS 为例：
        
        1.  进入[云服务器ECS实例](https://ecs.console.aliyun.com/server/)页面，选择目标 ECS 实例所在地域，单击目标实例名称，进入实例详情页。
            
        2.  单击**安全组 >** **内网入方向全部规则**，确保存在一条**授权策略**为**允许**、**协议类型**为 **TCP**、**目的端口范围**为 **HTTPS(443)**、**授权对象**为**任何位置(0.0.0.0/0)**（或其它地址，确保 PC 可远程访问即可）的规则。
            
        3.  如不存在上述规则，请参照[添加安全组规则](https://help.aliyun.com/zh/ecs/user-guide/add-a-security-group-rule#concept-sm5-2wz-xdb)在目标安全组中添加相应规则。
            
    3.  在防火墙中开放443端口。
        
        执行以下命令，识别系统当前的防火墙服务类型：
        
        ```
        if command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet firewalld; then
            echo "firewalld"
        elif command -v ufw >/dev/null 2>&1 && sudo ufw status | grep -qw active; then
            echo "ufw"
        elif command -v nft >/dev/null 2>&1 && sudo nft list ruleset 2>/dev/null | grep -q 'table'; then
            echo "nftables"
        elif command -v systemctl >/dev/null 2>&1 && systemctl is-active --quiet iptables; then
            echo "iptables"
        elif command -v iptables >/dev/null 2>&1 && sudo iptables -L 2>/dev/null | grep -qE 'REJECT|DROP|ACCEPT'; then
            echo "iptables"
        else
            echo "none"
        fi
        ```
        
        若输出为 `none`，则无需进一步操作。否则，请根据输出的类型（`firewalld`、`ufw`、`nftables`、`iptables`），执行以下命令开放 443 端口：
        
        #### firewalld
        
        ```
        sudo firewall-cmd --permanent --add-port=443/tcp && sudo firewall-cmd --reload
        ```
        
        #### **ufw**
        
        ```
        sudo ufw allow 443/tcp
        ```
        
        #### **nftables**
        
        ```
        sudo nft add table inet filter 2>/dev/null
        sudo nft add chain inet filter input '{ type filter hook input priority 0; }' 2>/dev/null
        sudo nft add rule inet filter input tcp dport 443 counter accept 2>/dev/null
        ```
        
        #### iptables
        
        ```
        sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
        ```
        
        为避免 iptables 规则在系统重启后失效，请执行以下命令持久化 iptables 规则：
        
        ##### RHEL/CentOS
        
        ```
        sudo yum install -y iptables-services
        sudo service iptables save
        ```
        
        ##### **Debian/Ubuntu**
        
        ```
        sudo apt-get install -y iptables-persistent
        sudo iptables-save | sudo tee /etc/iptables/rules.v4 >/dev/null
        ```
        
3.  在 Tengine 配置文件目录中创建证书存放目录。
    
    ```
    cd /usr/local/tengine/conf #步骤二中指定的Tengine安装目录，请您可以根据实际配置调整。
    mkdir cert #创建证书目录，命名为cert。
    ```
    
4.  将证书相关文件上传到 cert 目录（示例中为 /usr/local/tengine/conf/cert）。
    
    **说明**
    
    您可以使用远程登录工具的本地文件上传功能来上传文件。例如**PuTTY**、**Xshell**或**WinSCP**等工具。如果您使用的是阿里云云服务器 ECS，关于上传文件的具体操作，请参见[上传或下载文件](https://help.aliyun.com/zh/ecs/user-guide/upload-a-file-from-on-premises-to-an-ecs-instance/)。
    
5.  通过包管理器安装编译所需的基础工具包：
    
    ## **RHEL/CentOS 系列**
    
    ```
    sudo yum -y install wget 
    sudo yum -y install gcc gcc-c++
    sudo yum -y install make
    sudo yum -y install pcre pcre-devel
    sudo yum -y install gzip
    sudo yum -y install zlib-devel
    ```
    
    ## **Debian/Ubuntu 系列**
    
    ```
    sudo apt update
    sudo apt install -y wget
    sudo apt install -y gcc g++
    sudo apt install -y make
    sudo apt install -y libpcre3 libpcre3-dev
    sudo apt install -y gzip
    sudo apt install -y zlib1g-dev
    ```
    
6.  下载并解压 Tongsuo 和 Tengine 源代码。
    
    -   下载 Tongsuo 8.2.1 并解压。
        
        ```
        wget -c https://github.com/BabaSSL/BabaSSL/archive/refs/tags/8.2.1.tar.gz
        tar -zxvf 8.2.1.tar.gz  #解压BabaSSL压缩包
        ```
        
    -   下载 Tengine 2.4.1 并解压。
        
        ```
        wget -c https://tengine.taobao.org/download/tengine-2.4.1.tar.gz
        tar -zxvf tengine-2.4.1.tar.gz
        ```
        
7.  在 Tengine 解压目录下，执行以下命令编译安装 Tengine 并关联 Tongsuo。
    
    执行前请根据实际情况修改以下参数中的路径：
    
    -   **\--prefix=/usr/local/tengine**：指定 Tengine 安装目录，可按需修改为其他路径。
        
    -   **\--add-module=modules/ngx\_tongsuo\_ntls**：加载 Tongsuo NTLS 模块。Tengine 2.4.1 之前的版本需替换为 **ngx\_openssl\_ntls**。
        
    -   **\--with-openssl=../Tongsuo-8.2.1**：指定 Tongsuo 路径以启用 SM2 支持，需替换为实际的 Tongsuo 安装路径。
        
    
    ```
    ./configure --prefix=/usr/local/tengine  \
    --add-module=modules/ngx_tongsuo_ntls  \
    --with-openssl=../Tongsuo-8.2.1   \
    --with-openssl-opt="enable-ntls"  \
    --with-http_ssl_module   \
    --with-stream \
    --with-stream_ssl_module \
    --with-stream_sni
    make -j
    make install
    ```
    
8.  编辑 Tengine 配置文件 nginx.conf（示例中位于 /usr/local/tengine/conf），配置证书相关参数。
    
    ```
    server {
        listen 443 ssl;
        server_name aliyundoc.com; #需修改为对应的网站域名
    
        # 启用NTLS。Tengine针对BabaSSL中的NTLS功能进行了适配，本文使用BabaSSL作为Tengine的底层密码库来实现通信加密的能力。
        enable_ntls on;
    
        # 配置国密标准算法签名证书
        ssl_sign_certificate cert/server_sign.pem; #需修改为实际证书文件路径
        ssl_sign_certificate_key cert/server_sign.key; #需修改为实际私钥文件路径
    
        # 配置国密标准算法证书
        ssl_enc_certificate cert/server_enc.pem; #需修改为实际证书文件路径
        ssl_enc_certificate_key cert/server_enc.key; #需修改为实际私钥文件路径
    
        # （可选）配置国际标准算法证书
        ssl_certificate cert/server_rsa.pem; #需修改为实际证书文件路径
        ssl_certificate_key cert/server_rsa.key; #需修改为实际私钥文件路径
    
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout 5m;
    
        # 配置加密套件# ssl_ciphers HIGH: !aNULL: !MD5;
        ssl_ciphers ECC-SM2-SM4-CBC-SM3:ECC-SM2-SM4-GCM-SM3:ECDHE-SM2-SM4-CBC-SM3:ECDHE-SM2-SM4-GCM-SM3:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!RC4:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
    
        location / {
            root html;
            index index.html index.htm;
        }
    }
    ```
    
9.  重新载入 Tengine 配置文件使配置生效。
    
    ```
    cd /usr/local/tengine/sbin #进入Tengine服务的可执行目录。
    ./nginx -s reload  #重新载入配置文件。
    ```
    

### **步骤三：验证安装是否成功**

1.  请通过 HTTPS 访问您已绑定证书的域名（如 `https://example.com`，`example.com` 需替换为实际域名）。
    
2.  若浏览器地址栏显示安全锁图标，说明证书已成功部署。如访问异常或未显示安全锁，请先清除浏览器缓存或使用无痕（隐私）模式重试。
    
    ![image](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/0358333571/p986900.png)
    
    Chrome 浏览器自 117 版本起，地址栏中的![image](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/0412215371/p885852.png)已被新的![image](https://help-static-aliyun-doc.aliyuncs.com/assets/img/zh-CN/0412215371/p885866.png)替代，需单击该图标后查看安全锁信息。
    

**重要**

国密标准 SSL 证书需要与支持国密算法的浏览器（如 360、密信、红莲花浏览器）配合使用，才能正常建立安全通信。

### **后续步骤（可选）**

#### **开启**域名监控

建议在证书部署完成后，为域名开启域名监控功能。系统将自动检测证书有效期，并在到期前发送提醒，帮助您及时续期，避免服务中断。具体操作请参见[购买并开启公网域名监控](https://help.aliyun.com/zh/ssl-certificate/domain-name-monitoring-1)。

## 常见问题

### **安装或更新证书后，证书未生效或 HTTPS 无法访问**

常见原因如下：

-   域名未完成 ICP 备案。请参见[如何查看域名解析记录以及 ICP 备案信息](#0ef83a70355yn)。
    
-   服务器安全组或防火墙未开放 443 端口。请参见[开放安全组和防火墙的 443 端口](#d3e04d3dadlv2)。
    
-   证书的**绑定域名**未包含当前访问的域名。请参见[如何判断绑定域名是否已匹配所有需保护的域名](#a2eff8de79fvu)。
    
-   修改 Tengine 配置文件后未重载服务。具体操作可参见[重启Tengine服务](#step-m5e-rft-g4d)。
    
-   证书文件未正确替换，或 Tengine 配置未正确指定证书路径。请检查 Nginx 配置文件和所用证书文件是否为最新且有效。
    
-   域名已接入 CDN、SLB 或 WAF 等云产品，但未在相应产品中安装证书。请参阅[流量经过多个云产品时证书的部署位置](https://help.aliyun.com/zh/ssl-certificate/ssl-certificate-deployment-scheme-selection#8eaf8a5b5bhi5)完成相关操作。
    
-   当前域名的 DNS 解析指向多台服务器，但证书仅在部分服务器上安装。需分别在每个服务器中安装证书。
    

**说明**

如需进一步排查，请参考：[根据浏览器错误提示解决证书部署问题](https://help.aliyun.com/zh/ssl-certificate/resolve-certificate-deployment-issues-based-on-browser-prompts) 和 [SSL证书部署故障自助排查指南](https://help.aliyun.com/zh/ssl-certificate/troubleshoot-ssl-certificate-deployment-failures)。

### **如何更新（替换）Tengine 中已安装的 SSL 证书**

先备份服务器上原有的 .pem 和 .key 证书文件，然后登录数字证书管理服务控制台下载新证书，上传到服务器覆盖原文件（保持路径和文件名一致），最后重新载入 Tengine 服务使新证书生效。

### **如何在 Tengine 中关闭 TLSv1.0 和 TLSv1.1 以避免部分浏览器提示"证书不符合标准"**

在监听 443 端口的 server 块中，将 `ssl_protocols` 的值修改为仅保留 TLSv1.2 和 TLSv1.3，即 `ssl_protocols TLSv1.2 TLSv1.3;`。修改完成后执行 `nginx -s reload` 使配置生效。

### **重载（reload）Tengine 时报错：No such file or directory:fopen('/cert/3970497\_demo.aliyundoc.com.pem','r') error**

证书路径配置不正确。请将 Nginx 配置文件中的证书文件路径修改为实际地址，确保文件存在于指定位置。