在Nginx服务器安装国密SSL证书(Linux)

更新时间:
复制 MD 格式

本文介绍如何在 Linux 系统的 Nginx 服务器上部署国密 SSL 证书,包括下载和上传证书文件、配置 Nginx 证书参数以及验证安装结果。

背景信息

国密SSL证书是指根据中国国家密码局制定的密码算法标准所生成的SSL证书,主要用于满足企业对HTTPS协议国产化改造及国密算法应用的合规要求。如果您的Web应用服务器仅部署了国密SSL证书,则只能在支持国密算法的浏览器中访问,如密信浏览器和红莲花浏览器。因此,为了确保与各类浏览器的兼容性,通常会采取SM2/RSA双证书部署方案。

重要
  • 本文以 Linux 操作系统、Nginx 1.18.0、Wosign DV 国密 SSL 证书为例。不同版本的操作系统和 Web 服务器,部署操作可能有所差异。

  • 如果服务器上已安装 Nginx,需要先卸载再重新安装。官方版 Nginx 结合 OpenSSL 不支持国密算法,因此适配国密算法需要重新编译 Nginx,并指定 Wosign 厂商的国密 SM2 模块(wotrus_ssl)。

前提条件

  • 已通过数字证书管理服务签发国密标准证书(双证书方案还需要签发国际标准证书)。具体操作,请参见购买正式证书申请证书

  • 域名已正确解析至当前服务器,且已完成工信部 ICP 备案(适用于中国内地服务器)。

    如何查看域名解析记录以及 ICP 备案信息

    打开网络拨测工具,选择网络诊断分析,输入当前域名,确认以下信息:

    • DNS 服务商解析结果中 A 记录的 IP 为当前服务器的公网 IP。

    • 备案检查网站已备案。若显示“网站未备案,请咨询网站服务器提供商”,请完成备案后再安装证书。

  • 已获得本服务器的管理权限(即“root账号”或“有 sudo 权限”的账号)。

操作步骤

步骤一:下载SSL证书

  1. 进入SSL证书管理页面,定位需部署的目标证书,并确认以下信息:

    1. 证书状态:确保其为已签发。若为即将过期已过期,则需续费SSL证书

    2. 绑定域名:确保其能够匹配所有需保护的域名,否则未匹配的域名访问 HTTPS 时将出现安全警告。如需添加或修改,请参见追加和更换域名

      确认证书是否匹配目标域名

      证书的绑定域名可包含多个精确域名和通配符域名。每类域名的匹配规则如下:

      • 精确域名:仅对指定域名生效。

        • example.com 仅对 example.com 生效。

        • www.example.com 仅对 www.example.com 生效。

      • 通配符域名:仅对其一级子域名生效。

        • *.example.com 对 www.example.coma.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 文件,私钥仅保存在您本地,下载的证书包中不包含私钥。如私钥遗失,证书将无法使用,需重新购买正式证书并生成 CSR 和私钥。

步骤二:安装Nginx服务和Wosign(沃通)国密SM2模块

  1. 登录 Linux 服务器。

    • 阿里云服务器:请参考使用Workbench登录Linux实例

    • 非阿里云服务器:请通过对应厂商提供的远程连接功能登录服务器终端。

    后续部分命令因操作系统类型不同而略有差异。请根据实际的服务器操作系统,选择对应的命令操作。

    • RHEL/CentOS 系列:包括 Alibaba Cloud Linux、Red Hat Enterprise Linux、CentOS、AlmaLinux、Rocky Linux、Anolis OS 及其衍生版本。

    • Debian/Ubuntu 系列:包括 Debian、Ubuntu 及其衍生版本。

    如何确认操作系统所属系列

    在服务器终端执行 cat /etc/os-release,根据输出的 ID_LIKEID 判断:

    • 若 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实例页面,选择目标 ECS 实例所在地域,单击目标实例名称,进入实例详情页。

      2. 单击安全组 > 内网入方向全部规则,确保存在一条授权策略允许协议类型TCP目的端口范围HTTPS(443)授权对象任何位置(0.0.0.0/0)(或其它地址,确保 PC 可远程访问即可)的规则。

      3. 如不存在上述规则,请参照添加安全组规则在目标安全组中添加相应规则。

    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,则无需进一步操作。否则,请根据输出的类型(firewalldufwnftablesiptables),执行以下命令开放 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. 安装 Nginx 依赖:

    RHEL/CentOS 系列

    sudo yum -y install gcc gcc-c++ pcre pcre-devel zlib zlib-devel openssl openssl-devel

    Debian/Ubuntu 系列

    sudo apt install -y gcc g++ libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev
  4. 下载 Nginx 安装包并解压:

    wget https://nginx.org/download/nginx-1.18.0.tar.gz
    #解压下载完成后的安装包
    tar -zxvf nginx-1.18.0.tar.gz
  5. 下载国密 SM2 模块并解压:

    wget https://www.wotrus.com/download/wotrus_ssl.tar.gz
    #解压
    tar -zxvf wotrus_ssl.tar.gz
  6. 编译安装 Nginx,执行以下命令:

    #进入nginx-1.18.0目录配置(wotrus_ssl2.0 根据模块解压后文件夹名称配置)
    ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-stream --with-http_ssl_module --with-stream_ssl_module --with-openssl=/usr/local/wotrus_ssl2.0
    #编译安装
    make && make install

    如果编译过程中出现报错:make[1]: *** [/usr/local/wotrus_ssl2.0/.openssl/include/openssl/ssl.h] Error 127,需要修改 /usr/local/nginx-1.18.0/auto/lib/openssl 目录下的 conf 文件。修改内容如下:

    CORE_INCS="$CORE_INCS $OPENSSL/.openssl/include"
    CORE_DEPS="$CORE_DEPS $OPENSSL/.openssl/include/openssl/ssl.h"
    CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
    CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"

    将上述内容替换为:

    CORE_INCS="$CORE_INCS $OPENSSL/include"
    CORE_DEPS="$CORE_DEPS $OPENSSL/include/openssl/ssl.h"
    CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libssl.a"
    CORE_LIBS="$CORE_LIBS $OPENSSL/lib/libcrypto.a"
  7. 进入 Nginx 安装目录,启动 Nginx:

    cd /usr/local/nginx/sbin
    #启动nginx
    ./nginx
  8. 通过 curl 测试 Nginx 是否正常运行:

    #yourdomain替换为您的域名或者IP地址
    curl yourdomain

步骤三:在 Nginx 服务器配置 SSL 证书

  1. 在 Nginx 配置文件目录下创建证书存放目录:

    #在Nginx的配置文件目录下,创建一个用于存放国际(可选)和国密标准的证书cert目录。cert目录仅为示例,证书存放目录没有命名限制。
    mkdir /usr/local/nginx/conf/cert
  2. 将证书文件上传至创建的目录中。

    说明

    您可以使用远程登录工具的本地文件上传功能来上传文件。例如PuTTYXshellWinSCP等工具。如果您使用的是阿里云云服务器 ECS,关于上传文件的具体操作,请参见上传或下载文件

  3. 修改 Nginx 配置文件:

    1. /usr/local/nginx/conf 目录下,编辑 nginx.conf 配置文件,在 server 块中添加以下配置:

      server {
      	listen 443 ssl;
      	server_name yourdomain.com;
      	#配置国密标准证书
      	ssl_certificate /usr/local/nginx/conf/cert/yourdomain.com_sm2_sign.pem;
      	ssl_certificate_key /usr/local/nginx/conf/cert/yourdomain.com_sm2_sign.key;
      	ssl_certificate /usr/local/nginx/conf/cert/yourdomain.com_sm2_enc.pem;
      	ssl_certificate_key /usr/local/nginx/conf/cert/yourdomain.com_sm2_enc.key;
      	#(可选)配置国际标准证书
      	ssl_certificate /usr/local/nginx/conf/cert/yourdomain.com.pem;
      	ssl_certificate_key /usr/local/nginx/conf/cert/yourdomain.com.key;
      	#设置ssl 的会话超时时间为 5 分钟
      	ssl_session_timeout 5m;
      	ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
      	#配置ssl证书所需的加密套件
      	ssl_ciphers ECC-SM4-SM3:ECDH:AESGCM:HIGH:MEDIUM:!RC4:!DH:!MD5:!aNULL:!eNULL;
      	ssl_prefer_server_ciphers on;
      	location / {
      		root html;
      		index index.html index.htm;
      	}
      }
      说明

      以上配置仅供参考,请根据实际环境修改证书目录、证书名称及域名等参数。

    2. 验证配置文件是否正确:

      /usr/local/nginx/sbin/nginx -t

      若配置文件无误,将提示 nginx.conf test is successful,此时可以启动 Nginx 服务。

    3. 如果提示错误,请根据报错信息排查问题,修复配置文件后重新验证,直到提示正常。

    4. 重启 Nginx 服务使配置生效:

      #重启Nginx服务
      /usr/local/nginx/sbin/nginx -s reload

步骤四:验证SSL证书是否配置成功

  1. 请通过 HTTPS 访问您已绑定证书的域名(如 https://example.comexample.com 需替换为实际域名)。

  2. 若浏览器地址栏显示安全锁图标,说明证书已成功部署。如访问异常或未显示安全锁,请先清除浏览器缓存或使用无痕(隐私)模式重试。

    image

    Chrome 浏览器自 117 版本起,地址栏中的image已被新的image替代,需单击该图标后查看安全锁信息。

重要

国密 SSL 证书需与支持国密算法的浏览器(如 360 浏览器、密信浏览器、红莲花浏览器)配合使用,以确保通信安全。这类浏览器能识别并启用国密算法,与部署了国密 SSL 证书的服务器建立安全连接。

后续步骤(可选)

开启域名监控

建议在证书部署完成后,为域名开启域名监控功能。系统将自动检测证书有效期,并在到期前发送提醒,帮助您及时续期,避免服务中断。具体操作请参见购买并开启公网域名监控

常见问题

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

常见原因如下:

如何更新(替换)Nginx 中已安装的 SSL 证书

先备份服务器上原有的证书文件(.pem 和 .key),然后登录数字证书管理服务控制台,下载新证书并上传到目标服务器覆盖原有文件(确保路径和文件名一致)。最后,执行 /usr/local/nginx/sbin/nginx -s reload 重载 Nginx 服务,使新证书生效。

如何查找 Nginx 使用的配置文件

在终端执行以下命令:ps -ef | grep '[n]ginx: master' | grep -- ' -c '。如果输出类似 -c /etc/nginx/custom.conf,说明 Nginx 使用的是 /etc/nginx/custom.conf。如果没有输出,执行 nginx -V 2>&1 | grep -oP -- '--conf-path=[^ ]*' 查看默认配置文件路径(例如输出 --conf-path=/etc/nginx/nginx.conf,表示默认使用 /etc/nginx/nginx.conf)。

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

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

测试配置文件报错:cannot load certificate "/etc/nginx/ssl/domain.pem" : BIO_new_file() failed

证书文件 /etc/nginx/ssl/domain.pem 的路径不正确。请将 Nginx 配置文件中的证书路径修改为实际地址。

重载(reload)Nginx 时报错:No such file or directory:fopen('/cert/3970497_demo.aliyundoc.com.pem','r') error

证书文件 /cert/3970497_demo.aliyundoc.com.pem 的路径不正确。请将 Nginx 配置文件中的证书路径修改为实际地址。