Let's Encrypt 免费 SSL 证书申请教程:Certbot 自动化配置
Let's Encrypt 是一个免费、自动化和开放的证书颁发机构(CA),全球已有超过 4 亿个网站使用其证书。它的证书有效期只有 90 天,这看起来像缺点,其实是刻意的设计:短有效期倒逼自动化,配合 ACME 协议和 Certbot 工具,证书可以全自动签发、安装和续期,真正做到"一次配置、永不过期"。对预算有限的个人站和小型企业来说,这是把 HTTPS 从"要花钱的事"变成"默认动作"的关键一步。
一、准备工作
1.1 环境要求
- 服务器:拥有 root 或 sudo 权限
- 域名:已解析到服务器 IP
- Web 服务器:Nginx 或 Apache
- 防火墙:80 和 443 端口开放
- 系统:Ubuntu/Debian/RHEL/CentOS
1.2 安装 Certbot
# Ubuntu/Debian
apt update
apt install certbot python3-certbot-nginx
# RHEL/CentOS 8+
dnf install certbot python3-certbot-nginx
# CentOS 7
yum install epel-release
yum install certbot python2-certbot-nginx
1.3 三种域名验证方式
申请证书前,Let's Encrypt 需要证明你拥有这个域名,常见的有三种挑战(challenge)方式:
| 方式 | 原理 | 适用场景 |
|---|---|---|
| HTTP-01 | 在 http://域名/.well-known/acme-challenge/ 下放验证文件 |
80 端口可访问的常规站点 |
| DNS-01 | 在 DNS 解析中添加 TXT 记录 | 通配符证书、80 端口不可用 |
| TLS-ALPN-01 | 在 443 端口的 TLS 握手中响应 | 仅 HTTPS 的环境 |
Certbot 的 --nginx / --apache 自动模式默认走 HTTP-01;要签发 *.example.com 这类通配符证书,就必须用 DNS-01。
二、申请证书
2.1 自动模式(推荐)
如果 Web 服务器已配置好并可以正常访问,使用自动模式最简单:
# Nginx
certbot --nginx -d example.com -d www.example.com
# Apache
certbot --apache -d example.com -d www.example.com
Certbot 会自动:
- 验证域名所有权(通过 HTTP 挑战)
- 申请并安装证书
- 修改 Web 服务器配置文件
- 设置自动续期
2.2 手动模式
如果不想让 Certbot 修改配置文件,使用 certonly 参数:
# 仅获取证书,不修改 Web 服务器配置
certbot certonly --nginx -d example.com -d www.example.com
# 或使用 Webroot 方式
certbot certonly --webroot -w /var/www/example.com -d example.com
2.3 DNS 验证模式
对于通配符证书(*.example.com)或未开放 80 端口的场景:
# 使用 DNS 验证
certbot certonly --manual --preferred-challenges dns -d *.example.com -d example.com
# 或使用 DNS 插件(如 Cloudflare、阿里云 DNS)
certbot certonly --dns-cloudflare --dns-cloudflare-credentials ~/.cloudflare/credentials -d *.example.com
三、证书文件
申请成功后,证书文件保存在 /etc/letsencrypt/live/example.com/:
$ ls -l /etc/letsencrypt/live/example.com/
total 0
lrwxrwxrwx 1 root root 36 Jul 18 10:00 cert.pem -> ../../archive/example.com/cert1.pem
lrwxrwxrwx 1 root root 37 Jul 18 10:00 chain.pem -> ../../archive/example.com/chain1.pem
lrwxrwxrwx 1 root root 41 Jul 18 10:00 fullchain.pem -> ../../archive/example.com/fullchain1.pem
lrwxrwxrwx 1 root root 33 Jul 18 10:00 privkey.pem -> ../../archive/example.com/privkey1.pem
| 文件 | 用途 |
|---|---|
cert.pem |
服务器证书 |
chain.pem |
中间证书链 |
fullchain.pem |
完整证书链(cert + chain) |
privkey.pem |
私钥(请保密!) |
四、Web 服务器配置
4.1 Nginx SSL 配置
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL 证书配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL 安全配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
root /var/www/example.com;
index index.html;
}
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
4.2 Apache SSL 配置
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
# SSL 安全配置
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder on
DocumentRoot /var/www/example.com
</VirtualHost>
五、自动续期
5.1 测试续期
# 模拟续期(不实际执行)
certbot renew --dry-run
# 如果测试成功,说明自动续期已正常工作
5.2 自动续期机制
Certbot 安装时会自动配置续期定时任务:
# 查看 systemd 定时器
systemctl list-timers | grep certbot
# 或查看 crontab
systemctl cat certbot.timer
默认情况下,Certbot 每天检查两次,在证书过期前 30 天自动续期。
5.3 手动续期
# 立即续期所有证书
certbot renew
# 续期后重载 Web 服务器
certbot renew --post-hook "systemctl reload nginx"
六、申请成功后的检查
拿到证书只是第一步,还要确认配置真的生效:
# 列出当前所有证书与到期时间
certbot certificates
# 查看握手时返回的证书主体
curl -vI https://example.com 2>&1 | grep -i "subject:\|issuer:"
# 直接看证书有效期
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
还可以把域名提交到 SSL Labs(https://www.ssllabs.com/ssltest/)跑一次评级,A 以下通常说明配置还有优化空间。
七、替代方案对比
| 方案 | 特点 | 适合 |
|---|---|---|
| Let's Encrypt + Certbot | 免费、全自动、生态最大 | 自己管理服务器的站点 |
| ZeroSSL | 90 天证书 + Web 面板 | 不喜欢命令行的用户 |
| Cloudflare SSL | 一键开启、自带 CDN | 已用 Cloudflare 的站点 |
| 云厂商免费证书 | 一年期、需手动续期 | 国内备案站点 |
八、常见问题
- 续期失败:多半是 80 端口被防火墙挡、DNS 解析没生效或磁盘空间不足;先跑
certbot renew --dry-run看具体报错。 - 提示证书不受信任:Nginx/Apache 里要配
fullchain.pem而不是cert.pem,少了中间证书链浏览器就会报错。 - 开了 HSTS 后访问不了:先用短期
max-age测试,确认全站 HTTPS 正常后再调成includeSubDomains。 - 要不要申请通配符证书:子域名不多时,把
www一起写进-d参数更省事;子域名很多或会动态新增时才考虑走 DNS 验证的通配符。
九、总结
对自管服务器来说,Let's Encrypt + Certbot 是目前最省心的免费 HTTPS 方案:一次性配好自动续期,之后基本不用再管证书。再配合 HSTS 与安全响应头配置,能把站点的传输安全做到相当高的水准。
参考:Let's Encrypt 官方文档 https://letsencrypt.org/docs/;Certbot 文档 https://certbot.eff.org/docs/
六、其他免费 SSL 方案
| 方案 | 特点 | 适用场景 |
|---|---|---|
| Let's Encrypt + Certbot | 最主流,自动续期 | 自管服务器 |
| Cloudflare SSL | 一键开启,CDN 整合 | 使用 Cloudflare 的网站 |
| ZeroSSL | 提供 90 天证书 + 管理面板 | 不想用命令行的用户 |
| 阿里云/腾讯云免费证书 | 1 年有效期,手动续期 | 国内云厂商用户 |
七、常见问题
证书续期失败
# 检查续期日志
certbot renew --dry-run -v
# 常见原因:
# - 80 端口未开放(HTTP 验证需要)
# - DNS 解析错误
# - 磁盘空间不足
证书不信任
# 确保安装了完整的证书链
# 使用 fullchain.pem 而不是 cert.pem
RC4/3DES 等弱加密算法如何禁用
# 在 Nginx 配置中添加
ssl_ciphers HIGH:!aNULL:!MD5:!3DES:!RC4;
八、总结
Let's Encrypt + Certbot 是目前申请免费 SSL 证书的最佳方案。通过自动续期,可以实现"一次配置、永久免费"。对于使用 Nginx 或 Apache 的服务器,几分钟内就能完成 HTTPS 配置。建议所有网站都启用 HTTPS——不仅为了安全,也为了 SEO 和用户信任。