用 Let's Encrypt 获取免费的 HTTPS 证书
Let's Encrypt 是一家证书颁发机构,为您的域名签发免费的 HTTPS 证书。在您的 VPS 上,用 Certbot 只需几条命令就能获取证书,用 Caddy 则一条命令都不用,两者都会自动续期。有两个前提:域名必须指向您服务器的 IP 地址,80 和 443 端口必须能从外部访问。
为什么需要 HTTPS?
HTTPS 会加密浏览器和服务器之间的流量。网络上的第三方读不到登录表单里的密码,也读不到订单的详情。没有 HTTPS 的网站,浏览器可能显示“不安全”的警告。Let's Encrypt 的证书是免费的,所以已经没有什么好理由不用 HTTPS。
开始之前
- 域名的 A 记录必须指向您服务器的 IP 地址。要检查,请运行
dig +short example.com。输出应该是您服务器的 IP 地址。 - 80 和 443 端口必须开放,因为验证是在 80 端口上进行的(HTTP-01)。如果您使用 ufw,请运行
sudo ufw allow 80/tcp和sudo ufw allow 443/tcp。如果您的服务器在面板中有单独的防火墙,也请检查那里的规则。 - 如果域名有 AAAA(IPv6)记录,它也必须指向这台服务器。如果没有,请删除这条记录。
- 您的 Web 服务器必须正在运行,并且认识这个域名。
在 Nginx 或 Apache 上用 Certbot 安装和检查
Certbot 的官方说明推荐使用 snap 软件包。请确认服务器上已安装 snapd(Ubuntu 上通常已经有),并卸载之前通过 apt 安装的旧版 Certbot。
- 安装 Certbot:
sudo snap install --classic certbot - 让这个命令在任何位置都可用:
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot - 获取证书并把它安装到 Web 服务器中。Nginx 请运行
sudo certbot --nginx,Apache 请运行sudo certbot --apache。 - 回答提示的问题:您的邮箱地址、证书要用于哪些域名,以及是否把 HTTP 重定向到 HTTPS。
- 试一下续期:
sudo certbot renew --dry-run
如果只想获取证书、自己去设置,请运行 sudo certbot certonly --nginx。Certbot 软件包会自己添加一个计划任务(cron 或 systemd 定时器),您可以在 systemctl list-timers 的输出中看到它。sudo certbot certificates 会列出您的证书及其到期日期。Certbot 会在证书有效期快到时续期,您什么都不用做。不过续期仍有可能在某天失败(例如因为某条防火墙规则),所以请时不时运行一次 --dry-run。
要检查证书,首先看浏览器地址栏里的挂锁图标。要用命令查看到期日期,请运行:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
输出中的 notAfter 一行就是证书的到期日期。如果您不使用 Certbot 添加的重定向,请自己把 HTTP 重定向到 HTTPS。在 Nginx 上,把 return 301 https://$host$request_uri; 这一行加到监听 80 端口的 server 块中。
用 Caddy,无需任何命令
如果您使用 Caddy,就不需要额外安装任何东西。对于配置中的域名,Caddy 会从 Let's Encrypt 或 ZeroSSL 获取证书、续期,并把 HTTP 重定向到 HTTPS。根据它的官方文档,域名的 A 和 AAAA 记录必须指向服务器,80 和 443 端口必须能从外部访问,而且 Caddy 的数据文件夹必须是持久且可写的。如果您在 Docker 中运行 Caddy,请把这个文件夹挂载到一个卷上。否则容器一删,证书就会消失,再次申请还可能触发频率限制。
通配符证书
通配符证书(*.example.com)用一张证书覆盖所有子域名,并且只能通过 DNS-01 验证获得。这种验证不使用 80 端口,而是要求您在域名的 DNS 中添加一条 TXT 记录。为此,您的 DNS 服务商需要提供 API,并且您要把 API 密钥存放在服务器上。Let's Encrypt 的文档认为把这类密钥存放在 Web 服务器上有风险。如果不需要通配符,用 HTTP-01 为单个域名获取证书更简单,也不需要保存 DNS 密钥。
常见错误
| 现象 | 可能的原因 | 解决办法 |
|---|---|---|
| 验证失败,找不到域名 | A 记录指向了错误的 IP,或者还没有生效 | 用 dig +short example.com 检查 IP,然后等待 |
| 超时 | 80 端口是关闭的 | 在 ufw 和面板防火墙(如果有)中放行 80 端口 |
| 验证有时通过,有时失败 | AAAA 记录指向另一台服务器 | 修正或删除 AAAA 记录 |
| 频率限制错误 | 尝试次数过多 | 测试时使用 --dry-run,并在官方页面查看各项限制 |
| 续期没有运行 | 没有计划任务,或者 Web 服务器拦截了 80 端口 | sudo certbot renew --dry-run 会显示错误 |
错误信息通常会说明是哪项验证失败,以及 Let's Encrypt 试图访问您服务器上的哪个地址。请按原样阅读这条信息,答案往往就在其中。
根据 Let's Encrypt 官方页面,同一组域名每周最多签发 5 张证书,同一个域名每小时最多允许 5 次验证失败。所以在摸索期间请使用 --dry-run。它在测试环境中尝试续期,不会消耗您真正的额度。
在 Seturack 的一键应用上
一键应用(WordPress、Nextcloud 等)通过由您的 IP 地址生成的 sslip.io 地址以 HTTPS 方式打开,所以不需要域名。当您绑定自己的域名时,Caddy 会重新获取证书,您不需要额外安装任何东西。让 Caddy 和应用知道域名的步骤,见这篇帮助文章。
评论0
暂无评论
成为第一个分享想法的人。
请登录或注册后发表评论。