在Nginx或Tengine服务器安装 SSL证书(Linux)

本文详细介绍如何在 Linux 环境下,为 Nginx 或 Tengine 服务器安装 SSL 证书,实现 HTTPS 安全访问。内容涵盖证书的下载与上传、服务器配置步骤、密钥参数设置、安装效果验证,以及常见问题的排查与处理方法。

重要
  • 适用范围:本文以 Nginx 1.14.2 为例进行说明,其同样适用于与 Nginx 配置兼容的 Tengine。

  • 兼容说明:不同 Linux 发行版或 Nginx 版本的命令和配置路径可能存在差异,请根据实际情况进行调整。

  • 技术支持:如需协助,请参见专家一对一服务

前提条件

  • 已通过数字证书管理服务购买和申请证书(状态已签发)。如需购买和申请证书,请参见购买正式证书申请证书

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

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

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

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

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

  • 待部署的证书为国际标准证书。若需部署国密证书,请参见Nginx服务器安装国密SSL证书(Linux)

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

操作步骤

步骤一:下载 SSL 证书和私钥文件

  1. 登录数字证书管理服务控制台。在左侧导航栏选择证书管理 > SSL证书管理

  2. 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)。

  3. 在目标证书操作列单击更多进入证书详情页面,然后在下载页签中下载服务器类型Nginx 的证书。

  4. 解压下载的证书压缩包:

    • 若同时包含证书文件(.pem)和私钥文件(.key),请妥善保存上述文件,后续部署时均需使用。

    • 若仅包含证书文件(.pem),不含私钥文件(.key),需配合您本地保存的私钥文件一起部署。

      说明

      若申请证书时使用 OpenSSL、Keytool 等工具生成 CSR 文件,私钥文件仅保存在您本地,下载的证书包中不包含私钥。如私钥遗失,证书将无法使用,需重新购买正式证书并生成CSR和私钥。

步骤二:安装 SSL 证书到 Nginx

  1. 登录 Linux 服务器。

    阿里云服务器

    以下操作以阿里云云服务器 ECS 为例进行说明,其他类型的服务器请参照对应产品文档进行操作。

    1. 登录ECS管理控制台,在页面左侧顶部,选择目标ECS实例所在地域。

    2. 在左侧导航栏中选择实例与镜像 > 实例,在实例页面找到目标ECS实例,点击操作列的远程连接

    3. 在弹出的对话框中,选择通过Workbench远程连接并单击立即登录

    4. 选择终端连接作为连接方式,输入相关认证信息,并根据页面提示完成登录,即可进入服务器终端。详细操作请参考使用Workbench登录ECS实例

      说明

      若系统弹出“安全组白名单开通提示”面板,请按照页面提示单击一键添加

    其他云厂商服务器

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

    非云厂商服务器(如物理服务器、IDC托管主机等)

    请在本地使用SSH工具登录服务器终端。

    • Windows:在命令提示符(cmd)或PowerShell中运行:ssh用户名@服务器IP。如不支持 ssh 命令,可使用第三方软件(如 PuTTYWinSCP等)进行连接。

    • macOS/Linux:在系统自带的终端(Terminal)中运行:ssh用户名@服务器IP

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

    • 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端口。

      1. 在安全组中开放 443 端口

      重要

      若您的服务器部署在云平台,请确保其安全组已开放 443 端口 (TCP),否则外部无法访问服务。以下操作以阿里云 ECS 为例,其他云平台请参考其官方文档。

      1. 登录ECS管理控制台,在页面左侧顶部,选择目标 ECS 实例所在地域。在实例页面,找到目标 ECS 实例。

      2. 单击目标实例名称,进入实例详情页面,单击安全组 > 内网入方向全部规则,确保存在一条授权策略允许协议类型为 TCP、目的端口范围为 HTTPS(443)、授权对象任何位置(0.0.0.0/0)的规则。

      3. 如不存在上述规则,请按以下步骤添加。更多安全组配置请参见添加安全组规则

        1. 在 ECS 实例详情页面,单击安全组 > 安全组列表,选择目标安全组并进入其详情页。

        2. 在安全组详情页的安全组详情 > 入方向下,单击增加规则

        3. 新建安全组规则面板,将访问目的(本实例)设置为 HTTPS(443),其余参数保持默认值,单击确定即可。

      2. 在服务器本地防火墙中开放 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 安装 SSL 模块。

    执行以下命令,若输出--with-http_ssl_module则说明已安装 SSL 模块,否则需进行安装。

    nginx -V 2>&1 | grep -o -- '--with-http_ssl_module'
    说明

    若系统提示 nginx: command not found,请根据 Nginx 的实际安装路径(如 /usr/local/nginx/sbin/nginx)运行命令,例如:/usr/local/nginx/sbin/nginx -V 2>&1 | grep -o -- '--with-http_ssl_module'

    为 Nginx 安装 SSL

    请根据 Nginx 的安装方式(编译安装或包管理工具安装),选择对应的 SSL 模块安装方法:

    包管理工具安装
    重要
    • 在升级 Nginx 过程中,Nginx 服务可能会短暂中断,影响线上业务。

    • 请务必提前备份所有 Nginx 配置文件和站点数据,并选择业务低峰期操作,完成升级后及时恢复配置并验证服务正常。

    RHEL/CentOS 系列

    添加 Nginx 官方仓库。

    sudo tee /etc/yum.repos.d/nginx.repo <<EOF
    [nginx-stable]
    name=nginx stable repo
    baseurl=https://nginx.org/packages/centos/\$releasever/\$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    module_hotfixes=true
    EOF

    升级 Nginx。

    sudo yum upgrade nginx

    Debian/Ubuntu 系列

    升级 Nginx。

    sudo apt-get update
    sudo apt-get install --only-upgrade nginx
    编译安装

    在服务器终端按以下步骤进行相关命令:

    1. 安装依赖包。

      RHEL/CentOS 系列

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

      Debian/Ubuntu 系列

      sudo apt-get update
      sudo apt-get install -y build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev
    2. 查看当前 Nginx 编译参数。

      nginx -V

      记录 configure arguments: 后的所有参数,后续重新编译时需要全部保留。

    3. 下载与当前 Nginx 版本一致的源码包。

      执行 nginx -v查看当前 Nginx 版本(以 1.14.2 为例)。然后下载当前 Nginx 版本所对应的源码包并解压:

      wget http://nginx.org/download/nginx-1.14.2.tar.gz
      tar -zxvf nginx-1.14.2.tar.gz
      cd nginx-1.14.2
    4. 重新编译 Nginx,添加 SSL 模块。

      在前面步骤复制的参数(configure arguments: 后的所有参数)基础上,加上 --with-http_ssl_module,重新配置和编译:

      # 注意:一定要保留所有原有参数,以免丢失现有功能模块。
      ./configure <原有参数> --with-http_ssl_module
      make
      说明

      若在执行 make 时出现错误 error: ‘ENGINE_by_id’ is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations],说明 Nginx 某些代码在 OpenSSL 3.0 及以上版本中已被标记为废弃,编译器将其视为错误。可通过以下命令忽略此类警告,完成编译:make CFLAGS='-Wno-error=deprecated-declarations'

    5. 替换 nginx 可执行文件。

      备份原有 nginx(以原有 nginx 可执行文件路径为 /usr/local/nginx/sbin/nginx 为例):

      # 请将 /usr/local/nginx/sbin/nginx 替换为 nginx 文件的实际路径
      sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak

      覆盖原有 nginx 可执行文件:

      # 请将 /usr/local/nginx/sbin/nginx 替换为 nginx 文件的实际路径
      sudo cp objs/nginx /usr/local/nginx/sbin/nginx
    6. 验证 SSL 模块是否安装成功。

      nginx -V 2>&1 | grep -o -- '--with-http_ssl_module'

      若输出 --with-http_ssl_module 则说明 SSL 模块已安装成功。

  4. 上传 SSL 证书和私钥文件。

    重要

    本文以 ssl.pem(证书文件)和 ssl.key(私钥文件)为例,将其上传至服务器的 /etc/nginx/cert 目录。若该目录不存在,可执行sudo mkdir -p /etc/nginx/cert进行创建。

    1. 上传证书文件到服务器的目标目录。

      阿里云服务器

      以下操作以阿里云云服务器 ECS 为例进行说明,其他类型的服务器请参照对应产品文档进行操作。

      1. 在前面步骤打开的 Workbench 页面中,选择顶部菜单栏的文件 > 打开新文件树

      2. 在左侧文件树中,右键点击存放证书文件的目标目录(/etc/nginx/cert),选择上传文件,选择并上传证书文件 ssl.pem

      3. 重复上述操作,再次右键点击目标目录(/etc/nginx/cert),选择上传文件,选择并上传私钥文件 ssl.key

      4. 上传完成后,证书文件路径为 /etc/nginx/cert/ssl.pem,私钥文件路径为 /etc/nginx/cert/ssl.key

      其他云厂商服务器

      请通过对应云厂商提供的文件上传功能,将证书和私钥文件上传到服务器的目标目录(/etc/nginx/cert)。

      非云厂商服务器(如物理服务器、IDC 托管主机等)

      在本地使用 SSH 工具上传证书文件和私钥文件。以下示例中,<username>为当前服务器的用户名,<server_ip>为当前服务器的公网 IP。

      Windows
      1. 使用系统自带的命令提示符(cmd)或 PowerShell,通过 scp 命令上传文件。以证书文件和私钥文件存在本地 C:\ 目录为例。

        # 上传本地证书文件到服务器,请将路径 C:\ssl.pem 和 /etc/nginx/cert 替换为实际的源文件和目标目录
        scp C:\ssl.pem <username>@<server_ip>:/etc/nginx/cert
        
        # 上传本地私钥文件到服务器,请将路径 C:\ssl.pem 和 /etc/nginx/cert 替换为实际的源文件和目标目录
        scp C:\ssl.key <username>@<server_ip>:/etc/nginx/cert
      2. 若系统未集成 scp 命令,可以使用开源免费的 PuTTY 客户端,并配合其附带的 pscp.exe 工具通过命令行上传文件。也可以使用图形化的 WinSCP 上传文件。

      Linux/macOS

      使用系统自带的终端,执行 scp 命令上传文件。以证书文件和私钥文件存在本地 /tmp 目录为例。

      # 上传本地证书文件到服务器,请将路径 /tmp/ssl.pem 和 /etc/nginx/cert 替换为实际的源文件和目标目录
      scp /tmp/ssl.pem <username>@<server_ip>:/etc/nginx/cert
      
      # 上传本地私钥文件到服务器,请将路径 /tmp/ssl.pem 和 /etc/nginx/cert 替换为实际的源文件和目标目录
      scp /tmp/ssl.key <username>@<server_ip>:/etc/nginx/cert
    2. 修改证书文件及目录权限。

      执行以下命令,为 Nginx 配置文件(如 nginx.conf)中 user指令所指定的用户(如 nginx)添加相关权限:

      # 请将以下目录和文件路径替换为实际路径
      sudo chmod +x /etc/nginx/cert
      sudo chmod +r /etc/nginx/cert/ssl.pem /etc/nginx/cert/ssl.key
  5. 在 Nginx 中配置 SSL 证书和私钥文件。

    重要

    本文以 Nginx 配置文件 /etc/nginx/nginx.conf 为例,请根据实际情况调整文件路径。如需查找配置文件位置,请参见如何查找 Nginx 使用的配置文件

    1. 执行以下命令打开配置文件。

      sudo vim /etc/nginx/nginx.conf
    2. 添加监听 443 端口的 server 块。

      将现有监听 80 端口的 server 块复制为新的配置块,修改其监听端口为 listen 443 ssl,并补充 SSL 证书配置(包括 ssl_certificatessl_certificate_key 指令),其余配置项维持不变。

      # 原有监听 80 端口的 server 块
      server {
          listen 80;
          server_name yourdomain.com www.yourdomain.com;
          
          # 其它配置
          location / {
              proxy_pass http://127.0.0.1:8000;
          }
      }
      
      # 复制已有监听 80 端口的 server 块,新增为一个新的 server 块
      server {
          # 将原有 listen 80 修改为 listen 80 改为 listen 443 ssl
          listen 443 ssl;
          # 原有 server_name,可继续新增更多当前证书支持的域名
          server_name yourdomain.com www.yourdomain.com;
          
          # ======================= 证书配置开始 =======================
          # 指定证书文件(中间证书可以拼接至该pem文件中),请将 /etc/nginx/cert/ssl.pem 替换为您实际使用的证书文件的绝对路径
          ssl_certificate /etc/nginx/cert/ssl.pem;
          # 指定私钥文档,请将 /etc/nginx/cert/ssl.key 替换为您实际使用的私钥文件的绝对路径
          ssl_certificate_key /etc/nginx/cert/ssl.key;
          # 配置 SSL 会话缓存,提高性能
          ssl_session_cache shared:SSL:1m;
          # 设置 SSL 会话超时时间
          ssl_session_timeout 5m;
          # 自定义设置使用的TLS协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
          ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
          # 指定允许的 TLS 协议版本,TLS协议版本越高,HTTPS通信的安全性越高,但是相较于低版本TLS协议,高版本TLS协议对浏览器的兼容性较差
          ssl_protocols TLSv1.2 TLSv1.3;
          # 优先使用服务端指定的加密套件
          ssl_prefer_server_ciphers on;
          # ======================= 证书配置结束 =======================
         
          # 其它配置
      }
    3. 可选:设置 http 请求自动跳转到 https。在原有监听 80 端口的 server 块中添加 return 指令即可。

      # 原有监听 80 端口的 server 块
      server {
          listen 80;
          server_name yourdomain.com www.yourdomain.com;
              
          # 设置HTTP请求自动跳转到HTTPS
          return 301 https://$host$request_uri;
          
          # 原有其它配置
      }
    4. 执行以下命令验证配置文件的合法性与正确性。若输出syntax is oktest is successful则表示测试通过,否则需根据提示修正配置,直至测试通过。

      sudo nginx -t -c /etc/nginx/nginx.conf
  6. 重载 Nginx 服务。

    重要

    本文以 Nginx 使用默认配置文件路径启动为例。如有自定义安装路径或配置文件,请根据实际情况相应调整命令和路径。

    请根据 Nginx 当前的运行状态选择合适的操作:

    若 Nginx 服务已启动

    执行以下命令可重新加载 Nginx 配置文件,无需重启服务进程且不中断现有连接。如重载失败,请参考常见问题进行排查。

    sudo nginx -s reload

    若 Nginx 服务未启动

    执行以下命令以启动 Nginx 服务。

    nginx

步骤三:验证 SSL证书是否安装成功

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

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

    image

    说明

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

    image

说明

如仍有问题,请参考常见问题进行排查。

后续步骤(可选)

开启域名监控

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

常见问题

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

常见原因如下:

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

请先备份服务器上原有的证书文件(.pem 和 .key),然后登录数字证书管理服务控制台,下载新的证书文件(.pem 和 .key),并上传到目标服务器覆盖原有文件(确保路径和文件名一致)。最后,重载(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;。此时将禁用不安全的 TLSv1.0 和 TLSv1.1。配置完成后,执行 nginx -s reload 使设置生效。

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

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

重载(reload)Nginx 时报错:the "ssl" parameter requires ngx_http_ssl_module

您需要为 Nginx 安装 SSL 模块,具体操作请参见为 Nginx 安装 SSL 模块

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

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

重载(reload)Nginx 时报错:permission denied

检查 Nginx 配置文件(如 nginx.conf)中,user指令所指定的用户(如 nginx)是否有权限访问证书文件及目录。具体可参见修改认证书文件及目录权限