Let's Encrypt 是一个免费的证书颁发机构,通过 Certbot 客户端工具签发 SSL 证书并自动续期。本指南介绍如何在 Ubuntu VPS 上为 Nginx 和 Apache 安装 SSL 证书。
系统要求
- 具有 root 权限的 Ubuntu 20.04/22.04/24.04 VPS
- 域名 DNS A 记录指向 VPS IP 地址
- 已安装并运行 Nginx 或 Apache
- 防火墙已开放 80 和 443 端口
安装 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 安装检查清单
- 证书安装成功 —
sudo certbot certificates显示 VALID - 续期演练通过:
sudo certbot renew --dry-run - HTTP 正确跳转至 HTTPS(在浏览器或用 curl 测试)
- 响应头中包含 HSTS:
curl -I https://yourdomain.com | grep Strict - 无混合内容警告 — 所有页面资源均通过 HTTPS 加载
- SSL Labs 评分达 A 级或更高
- systemd 定时器运行正常:
sudo systemctl status certbot.timer
验证 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 的额外技巧
- 频率限制:Let's Encrypt 每周每个域名最多签发 5 张证书。测试时请使用
--staging标志,避免触及限制。 - 使用 snap 安装 Certbot:snap 版本可自动保持最新,apt 包可能更新较慢。
- Webroot 插件:如果不希望 Certbot 修改服务器配置,可使用
--webroot -w /var/www/html进行手动控制。 - Standalone 模式:若尚未运行 Web 服务器,可使用
--standalone,Certbot 会在 80 端口临时启动一个服务器进行验证。
总结:通过 Certbot 使用 Let's Encrypt 是 VPS 上最简单的免费 SSL 方案,每 90 天自动续期。如需 OV/EV 或覆盖多个子域名的通配符 SSL,AsiaGB 提供多种商业 SSL 证书可供选择。