使用 Certbot 在 VPS 上安装 Let's Encrypt SSL

Let's Encrypt 是一个免费的证书颁发机构,通过 Certbot 客户端工具签发 SSL 证书并自动续期。本指南介绍如何在 Ubuntu VPS 上为 Nginx 和 Apache 安装 SSL 证书。

系统要求

安装 Certbot

sudo apt update
sudo apt install snapd -y
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

为 Nginx 申请证书

sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Certbot 会自动修改 Nginx 配置并添加 HTTP → HTTPS 跳转。

如需手动控制,使用 certonly 模式:

sudo certbot certonly --nginx -d yourdomain.com

为 Apache 申请证书

sudo apt install python3-certbot-apache -y
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com

Let's Encrypt 与付费 SSL:如何选择

Let's Encrypt 适合大多数只需基础 HTTPS 的网站。但在某些场景下,付费 SSL 证书能提供更多价值。参考以下对比,找到最适合你的方案。

对比项目 Let's Encrypt 付费 SSL (OV/EV)
费用 免费 1,000+ 泰铢/年起
证书类型 仅 DV DV / OV / EV / 通配符
有效期 90 天(自动续期) 1 年或 3 年
身份验证 仅验证域名 OV:组织验证 / EV:严格验证
通配符 支持,需 DNS 挑战验证 完整支持,无需 DNS 挑战
保险赔偿 无 含(因颁发机构而异)
适合场景 个人网站、博客、开发服务器、初创企业 电商、金融、企业、多子域名场景

总结:如果你的网站是 WordPress 博客、作品集或不直接处理支付的 Web 应用,Let's Encrypt 完全足够。若需要电商功能或通配符证书覆盖多个子域名,付费 SSL 证书更值得考虑。

验证安装结果

sudo certbot certificates

测试续期:

sudo certbot renew --dry-run

自动续期

Certbot 会自动安装 systemd 定时器,每日检查并续期证书。查看状态:

sudo systemctl status certbot.timer

添加续期后钩子以重载 Nginx:

sudo nano /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
#!/bin/bash
systemctl reload nginx
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh

配置 HTTPS 强制跳转与 HSTS 以最大化安全性

安装 SSL 后,下一个关键步骤是将所有流量强制跳转至 HTTPS,并添加 HTTP 严格传输安全(HSTS)响应头,告知浏览器必须通过 HTTPS 连接。这可以防止降级攻击和混合内容问题。

Nginx:HTTPS 跳转与 HSTS

# /etc/nginx/sites-available/yourdomain.com

# HTTP to HTTPS redirect
server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}

# HTTPS server block
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;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # HSTS (1 year)
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "SAMEORIGIN" always;
}

Apache:HTTPS 跳转与 HSTS

# /etc/apache2/sites-available/yourdomain.com.conf

<VirtualHost *:80>
    ServerName yourdomain.com
    Redirect permanent / https://yourdomain.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName yourdomain.com
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/yourdomain.com/chain.pem

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
</VirtualHost>

编辑配置后重启 Web 服务器:

# Nginx
sudo nginx -t && sudo systemctl reload nginx

# Apache
sudo apachectl configtest && sudo systemctl reload apache2

在 SSL Labs(ssllabs.com/ssltest/)检测你的 SSL 配置评分及改进建议,目标为 A 级或更高。

自动监控证书到期

即使 Certbot 会自动续期,仍建议设置额外监控,以便在证书到期前收到警报——尤其是当 Certbot 遇到错误或 DNS 问题时。

使用 openssl 检查证书到期日期:

echo | openssl s_client -servername yourdomain.com \
  -connect yourdomain.com:443 2>/dev/null \
  | openssl x509 -noout -dates

创建一个在剩余不足 30 天时触发警告的脚本:

#!/bin/bash
# /usr/local/bin/check-cert-expiry.sh
DOMAIN="yourdomain.com"
DAYS_WARN=30
EXPIRY=$(echo | openssl s_client -servername $DOMAIN \
  -connect $DOMAIN:443 2>/dev/null \
  | openssl x509 -noout -enddate \
  | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
NOW_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 ))

if [ $DAYS_LEFT -le $DAYS_WARN ]; then
  echo "WARNING: Certificate for $DOMAIN expires in $DAYS_LEFT days!"
  # Add email notification command here
fi

将此脚本添加到 cron 每日运行:

# Run check every day at 09:00
0 9 * * * /usr/local/bin/check-cert-expiry.sh

也可以使用 Uptime Kuma 等监控工具,它内置 SSL 证书监控并支持自定义告警阈值;或使用任何外部监控服务,在证书即将到期时发送邮件或 Webhook 通知。

常见问题排查

80 端口被封锁

sudo ufw allow 80/tcp && sudo ufw allow 443/tcp

DNS 尚未传播

检查:dig +short yourdomain.com — 必须返回你的 VPS IP 地址。

证书已过期且无法续期

sudo certbot renew --force-renewal -d yourdomain.com

SSL 最佳实践与上线前检查清单

在将网站推送到生产环境之前,请确认 SSL 配置完整且安全。使用以下清单避免常见问题。

SSL 安装检查清单

验证 TLS 协议版本

禁用旧版 TLS(1.0 和 1.1),仅启用 TLS 1.2 和 1.3。对于 Nginx,检查 /etc/letsencrypt/options-ssl-nginx.conf 是否包含:

ssl_protocols TLSv1.2 TLSv1.3;

对于 Apache,检查 ssl.conf:

SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1

禁用旧版 TLS 可防止 POODLE 和 BEAST 等漏洞,并提升 SSL Labs 评分。

多域名证书(SAN)

如果在单台 VPS 上托管多个域名,可以用一条命令申请涵盖所有域名的证书:

sudo certbot --nginx \
  -d domain1.com -d www.domain1.com \
  -d domain2.com -d www.domain2.com \
  -d domain3.com

Let's Encrypt 每张证书最多支持 100 个域名(SAN)。实际使用中,建议按应用分组管理证书,便于续期跟踪。

在 VPS 上使用 Let's Encrypt 的额外技巧

总结:通过 Certbot 使用 Let's Encrypt 是 VPS 上最简单的免费 SSL 方案,每 90 天自动续期。如需 OV/EV 或覆盖多个子域名的通配符 SSL,AsiaGB 提供多种商业 SSL 证书可供选择。

为您的 Web 服务器选择 VPS

AsiaGB VPS Ubuntu 提供完整 Root 权限,可立即安装 Nginx/Apache + SSL。月租低至 500 泰铢起。

查看 VPS 方案