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 会自动:

  1. 验证域名所有权(通过 HTTP 挑战)
  2. 申请并安装证书
  3. 修改 Web 服务器配置文件
  4. 设置自动续期

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 和用户信任。