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。