SSL 证书配置与自动续期实战 — 让你的网站永远绿锁

在当今互联网安全环境下,HTTPS 已经成为网站的标配。没有 SSL 证书的网站不仅会被浏览器标记为“不安全”,还会影响搜索引擎排名和用户信任度。本文将从证书申请、配置到自动续期,带你完整搭建一套永不失效的 SSL 证书体系。

一、为什么需要 SSL 证书?

1.1 数据加密传输

SSL 证书能在客户端和服务器之间建立加密通道,所有数据传输都是密文,即使被中间人劫持也无法读取内容。这对登录、支付、表单提交等敏感操作至关重要。

1.2 身份认证

CA 机构在颁发证书前会验证域名所有权,确保访问者连接的是真实的服务器,而不是钓鱼网站。

1.3 搜索引擎权重

Google、百度等搜索引擎都会给 HTTPS 网站更高的权重,SEO 效果更好。

1.4 浏览器信任

Chrome、Firefox 等主流浏览器会在 HTTP 网站显示“不安全”警告,严重影响用户体验。

二、选择合适的 SSL 证书

2.1 证书类型对比

证书类型验证级别域名数量价格适用场景
DV(域名验证)仅验证域名所有权单域名/泛域名免费 ~ 几百元/年个人博客、小型网站
OV(组织验证)验证企业组织身份多域名几千元/年企业官网、电商网站
EV(扩展验证)最高级别企业验证多域名万元/年金融机构、大型企业

2.2 免费证书推荐

  • Let's Encrypt:最主流的免费证书,90天有效期,支持自动续期
  • ZeroSSL:另一个不错的免费选择,同样90天有效期
  • 阿里云/腾讯云:云厂商提供的免费单域名证书,1年有效期

对于绝大多数运维场景,Let's Encrypt 完全够用,配合自动续期脚本可以实现永久免费。

三、使用 Certbot 申请 Let's Encrypt 证书

Certbot 是 EFF 推出的官方客户端,自动化程度最高,支持几乎所有主流 Linux 发行版和 Web 服务器。

3.1 安装 Certbot

Ubuntu/Debian 系统:

# 更新包列表
sudo apt update

# 安装 Certbot 和 Nginx 插件(如果用 Nginx)
sudo apt install -y certbot python3-certbot-nginx

# 如果用 Apache
sudo apt install -y certbot python3-certbot-apache

CentOS/RHEL 系统:

# 安装 EPEL 源
sudo yum install -y epel-release

# 安装 Certbot
sudo yum install -y certbot python3-certbot-nginx

3.2 自动获取并配置证书(推荐)

如果你已经在运行 Nginx 或 Apache,Certbot 可以一键完成证书申请、配置和重载:

# Nginx 自动配置
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Apache 自动配置
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

运行后会交互式提示你输入邮箱、同意服务条款,以及是否强制 HTTPS 跳转。建议选择强制跳转,Certbot 会自动配置 301 重定向规则。

3.3 手动模式(证书文件模式)

如果你的服务不支持自动配置,或者需要单独的证书文件,可以使用 certonly 模式:

# Webroot 模式(需要网站目录可写)
sudo certbot certonly --webroot -w /var/www/html -d yourdomain.com

# 独立模式(临时启动验证服务器,需要80端口空闲)
sudo certbot certonly --standalone -d yourdomain.com

# DNS 验证模式(适合泛域名证书,需要配置 DNS 插件)
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.secrets/cloudflare.ini -d "*.yourdomain.com"

3.4 证书文件说明

申请成功后,证书文件会保存在 /etc/letsencrypt/live/yourdomain.com/ 目录下:

  • privkey.pem:私钥文件(保密!)
  • fullchain.pem:完整证书链(最常用)
  • cert.pem:服务器证书
  • chain.pem:中间证书

四、Nginx SSL 最佳配置

4.1 基础 SSL 配置

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    # 证书路径
    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # 安全头
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";

    # 站点根目录
    root /var/www/html;
    index index.html index.htm;
}

# HTTP 强制跳转到 HTTPS
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}

4.2 高级安全配置(A+ 评级)

如果你想在 SSL Labs 测试中获得 A+ 评级,需要进一步优化加密套件:

server {
    listen 443 ssl http2;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # 协议版本 - 禁用不安全的 SSLv3 和 TLS 1.0/1.1
    ssl_protocols TLSv1.2 TLSv1.3;

    # 加密套件优先级
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    # OCSP 装订
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/yourdomain.com/chain.pem;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    # 会话缓存
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_session_tickets off;

    # 安全头
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
}

配置完成后验证并重载 Nginx:

sudo nginx -t
sudo systemctl reload nginx

五、自动续期:再也不用担心证书过期

Let's Encrypt 证书有效期只有 90 天,手动续期太麻烦。好在 Certbot 自带自动续期功能。

5.1 测试自动续期

先手动测试续期是否正常工作:

sudo certbot renew --dry-run

如果看到 "The dry run was successful" 说明一切正常。

5.2 配置定时任务

Certbot 安装后通常会自动创建 systemd timer 或 cron 任务,可以通过以下命令检查:

# 检查 systemd timer
systemctl list-timers | grep certbot

# 检查 cron
cat /etc/cron.d/certbot

如果没有,可以手动添加 cron 任务:

sudo crontab -e

# 添加这一行(每天凌晨2点检查续期,成功后自动重载 Nginx)
0 2 * * * /usr/bin/certbot renew --quiet --renew-hook "systemctl reload nginx"

5.3 多服务自动续期钩子

如果你的证书同时给 Nginx、Postfix、Dovecot 等多个服务使用,可以配置续期钩子:

# 创建续期钩子脚本
sudo tee /etc/letsencrypt/renewal-hooks/post/reload-services.sh << 'EOF'
#!/bin/bash
systemctl reload nginx
systemctl reload postfix
systemctl reload dovecot
EOF

# 添加执行权限
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-services.sh

这样每次证书续期成功后,都会自动重载所有使用该证书的服务。

六、泛域名证书申请(DNS 验证)

如果你有多个子域名,一张泛域名证书可以搞定所有子域名,比一张张申请方便得多。

以 Cloudflare DNS 为例:

  1. 安装 DNS 插件:

    sudo apt install -y python3-certbot-dns-cloudflare
  2. 创建 Cloudflare 凭证文件:

    mkdir -p ~/.secrets
    tee ~/.secrets/cloudflare.ini << 'EOF'
    dns_cloudflare_email = "your-email@example.com"
    dns_cloudflare_api_key = "your-global-api-key"
    EOF
    chmod 600 ~/.secrets/cloudflare.ini
  3. 申请泛域名证书:

    sudo certbot certonly \
      --dns-cloudflare \
      --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
      --dns-cloudflare-propagation-seconds 60 \
      -d "*.yourdomain.com" \
      -d "yourdomain.com"

这样一张证书可以同时用于 yourdomain.com 和 *.yourdomain.com 的所有子域名。

七、常见问题排查

7.1 80/443 端口被占用

如果 80 端口被其他服务占用,可以先临时停止服务申请证书,或者改用 DNS 验证模式。

7.2 证书续期失败

检查防火墙是否开放 80 端口,Certbot 续期时需要通过 80 端口进行 HTTP 验证。也可以切换到 DNS 模式,不需要开放任何端口。

7.3 浏览器提示证书不安全

  • 检查系统时间是否正确
  • 确认使用的是 fullchain.pem 而不是 cert.pem
  • 排查是否有中间证书缺失

7.4 SSL Labs 评级低

  • 禁用 TLS 1.0 和 1.1
  • 启用 HSTS 头
  • 优化加密套件顺序
  • 启用 OCSP 装订

八、总结

一套完整的 HTTPS 部署流程应该是:

  1. 选择合适的证书类型(推荐 Let's Encrypt)
  2. 使用 Certbot 自动化申请证书
  3. 配置安全的 Nginx SSL 参数
  4. 设置自动续期和服务重载钩子
  5. 定期用 SSL Labs 测试检查评级

按照本文配置后,你的网站可以获得浏览器绿锁、SSL Labs A+ 评级,并且证书会自动续期永不过期。HTTPS 不是一次性工作,需要持续关注安全漏洞和最佳实践,定期更新加密配置。