Web 服务器

Apache 用 Certbot 配置 Let's Encrypt 免费 HTTPS 证书

作者: · 最后核实

Apache httpd 2.4 用 Certbot 的 Apache 插件配置 Let's Encrypt 证书:运行 sudo certbot --apache,Certbot 会为 example.com 和 www.example.com 签发证书、生成 443 虚拟主机、加上 HTTP 跳转,之后自动续期。适用于 Ubuntu 22.04/24.04、Debian 12/13 和 Rocky/AlmaLinux 9/10 等 RHEL 系发行版,Certbot 4.1 及以上。

前提条件

Let's Encrypt 需要从公网通过 80 端口访问你的服务器。

  • 带 systemd 和 snapd 的 Linux 服务器,有 sudo 权限。
  • 已安装 Apache 2.4,80 端口的虚拟主机能正常访问,ServerName/ServerAlias 和要申请的域名一致。
  • example.com、www.example.com 的 A/AAAA 记录指向服务器,例如 203.0.113.10。
  • 服务器在中国大陆的,域名需已 ICP 备案。
  • 系统防火墙和云服务器安全组对所有来源放行 TCP 80、443。
dig +short example.com A
sudo ufw allow 'Apache Full'          # Debian/Ubuntu 用 ufw 时
sudo firewall-cmd --permanent --add-service=http --add-service=https && sudo firewall-cmd --reload   # CentOS/Rocky

第一步:启用 mod_ssl 并检查虚拟主机

没有 mod_ssl,Certbot 无法生成 443 虚拟主机。Debian/Ubuntu:

sudo a2enmod ssl headers
sudo systemctl reload apache2

CentOS、Rocky、AlmaLinux:

sudo dnf install mod_ssl
sudo systemctl reload httpd

80 端口的虚拟主机要明确写出域名:

# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com
</VirtualHost>
sudo a2ensite example.com.conf
sudo apachectl configtest && sudo systemctl reload apache2

第二步:安装 Certbot

snap 是官方推荐的安装方式,自带 Apache 插件:

sudo apt-get remove certbot     # CentOS/Rocky 用 sudo dnf remove certbot
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot

不能用 snap 的,按 certbot.eff.org 的 pip 说明把 certbot certbot-apache 装到 /opt/certbot。

第三步:申请证书并自动配置 Apache

一条 certbot --apache 命令完成验证、签发和 Apache 配置,证书要包含的域名都用 -d 写上:

sudo certbot --apache -d example.com -d www.example.com

Certbot 用 HTTP-01 验证域名,生成 SSL 虚拟主机,询问是否加 HTTP 跳转(选是),然后重载 Apache。邮箱可以不填,Let's Encrypt 从 2025 年 6 月 4 日起不再发到期提醒邮件。只想申请证书、不改配置的,用 sudo certbot certonly --apache -d example.com -d www.example.com。

第四步:检查 SSL 虚拟主机

Certbot 生成的 443 虚拟主机引用 fullchain.pem 和 privkey.pem。自己维护配置时,下面这份和 Certbot 生成的效果相同:

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com

    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    Protocols h2 http/1.1
</VirtualHost>

SSLProtocol -all +TLSv1.2 +TLSv1.3

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

Protocols h2 需要 mod_http2(sudo a2enmod http2)。不要开启 SSLUseStapling,Let's Encrypt 证书里已经没有 OCSP 地址。检查并重载:

sudo apachectl configtest && sudo systemctl reload apache2

验证

配置正确时,证书颁发者是 Let's Encrypt,HTTP 请求返回指向 https:// 的 Location 头。用 SSL 证书检查 从外部检查,或在终端运行:

curl ssl.sh/example.com

在服务器上:

sudo certbot certificates
curl -sI http://example.com | grep -i '^location'
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

自动续期

snap 自带的 systemd 定时器每天运行两次 certbot renew;Certbot 4.1 及以上按 Let's Encrypt 的 ARI 建议时间续期,没有 ARI 时在剩余三分之一有效期时续期。用 --apache 安装的证书续期后会自动重载 Apache。

systemctl list-timers | grep certbot
sudo certbot renew --dry-run

用 certonly 申请的证书要加重载钩子(Debian/Ubuntu 是 apache2,CentOS/Rocky 是 httpd):

sudo certbot reconfigure --cert-name example.com --deploy-hook "systemctl reload apache2"

更多写法见 Certbot 续期钩子。2027 年 2 月 10 日 Let's Encrypt 默认证书改为 64 天,定时器照常工作,不用改配置。Let's Encrypt 不再发提醒邮件,建议加到 ssl.sh 监控(开发中)。

常见问题排查

  • Invalid command 'SSLEngine':没加载 mod_ssl,运行 sudo a2enmod ssl 或安装 mod_ssl。
  • Unable to find a virtual host listening on port 80:按第一步建好 *:80 虚拟主机,ServerName 要对得上。
  • Timeout during connect:80 端口不通(安全组、运营商封端口、未备案)或解析错误,见 certbot 连接超时。
  • 浏览器报 ERR_SSL_PROTOCOL_ERROR:443 虚拟主机里没写 SSLEngine on,Apache 在 443 上返回明文 HTTP,见 ERR_SSL_PROTOCOL_ERROR。
  • 浏览器正常、curl 或 Java 报错:证书链不完整,见 缺少中间证书。
  • www 访问提示证书域名不匹配:证书里没有这个域名,见 NET::ERR_CERT_COMMON_NAME_INVALID。

常见问题

还需要配置 SSLCertificateChainFile 吗?

不需要。Apache 2.4.8 起 SSLCertificateFile 可以同时包含站点证书和中间证书,直接指向 fullchain.pem。只有 2.4.8 之前的老版本才需要单独的 SSLCertificateChainFile。

Certbot 把 HTTPS 配置写到哪里了?

Debian/Ubuntu 上会生成 /etc/apache2/sites-available/example.com-le-ssl.conf(按你的 80 端口配置文件命名)并自动启用,里面引用了 Certbot 维护的 /etc/letsencrypt/options-ssl-apache.conf。

网站套了 CDN,还能用 certbot --apache 吗?

只有 CDN 把 /.well-known/acme-challenge/ 的 HTTP 请求原样回源到 Apache 时才行。CDN 强制 HTTPS 或者源站 80 端口不通时,改用 DNS-01 验证,见 acme.sh + 阿里云 DNS/DNSPod。

资料来源

  1. Certbot instructions: Apache on Linux (snap)
  2. Certbot User Guide
  3. Apache httpd: SSL/TLS Strong Encryption How-To
  4. Apache httpd: mod_ssl
  5. Let's Encrypt: Ending OCSP Support in 2025