Debian 安装与使用 Certbot

内容声明
本文仅用于技术分享和学习交流,内容不包含任何广告、推广、引流、付费课程或外链信息。所有示例和配置均为技术实践,欢迎参考和自定义。
概述
Certbot 是一个 ACME (Automated Certificate Management Environment,自动证书管理环境) 客户端。他可以申请、部署、续约和撤销 HTTPS 证书。
Certbot 通常用于申请 Let's Encrypt 证书。他支持以下验证方式:
standalonewebrootNginx 插件Apache 插件DNS 插件手动 DNS 验证本文以 Debian 系统为例,介绍 Certbot 的安装、申请、续约和自动化管理方法。
前置条件
开始申请证书前,需要确认以下条件:
域名的A 记录已指向服务器的公网 IPv4 地址。域名存在 AAAA 记录时,该记录必须指向正确的 IPv6 地址。HTTP 验证需要外部网络访问服务器的 TCP 80 端口。防火墙和云服务安全组必须允许 TCP 80 和 TCP 443。当前用户必须拥有 sudo 权限。可以使用以下命令检查 DNS 解析:
代码语言:bash复制dig short A example.comdig short AAAA example.com
安装 Certbot
安装基础组件
更新 Debian 软件包索引:
代码语言:bash复制sudo apt update
安装 Certbot:
代码语言:bash复制sudo apt install certbot
检查安装结果:
代码语言:bash复制certbot --version
输出会包含当前安装的 Certbot 版本。
安装 Web 服务插件
使用 Nginx 时,安装 Nginx 插件:
代码语言:bash复制sudo apt install python3-certbot-nginx
使用 Apache 时,安装 Apache 插件:
代码语言:bash复制sudo apt install python3-certbot-apache
查看已经安装的 Certbot 插件:
代码语言:bash复制sudo certbot plugins
申请 HTTPS 证书
使用 standalone 模式
standalone 模式会启动一个临时 HTTP 服务。该服务默认监听 TCP 80 端口。
申请单个域名证书:
代码语言:bash复制sudo certbot certonly --standalone -d example.com
申请包含多个域名的证书:
代码语言:bash复制sudo certbot certonly --standalone -d example.com -d www.example.com
该模式不会修改 Nginx 或 Apache 配置。申请成功后,需要手动配置 Web 服务。
使用该模式前,需要确认 TCP 80 端口处于空闲状态:
代码语言:bash复制sudo ss -ltnp | grep ':80'
Nginx、Apache 或 Docker 容器可能占用该端口。
使用 webroot 模式
webroot 模式通过现有 Web 服务提供验证文件。他不需要停止 Nginx 或 Apache。
指定网站根目录并申请证书:
代码语言:bash复制sudo certbot certonly --webroot -w /var/www/html -d example.com
外部网络必须能够访问 /.well-known/acme-challenge/ 路径。
使用 Nginx 插件
Nginx 插件可以申请证书,并自动修改 Nginx 配置:
代码语言:bash复制sudo certbot --nginx -d example.com -d www.example.com
使用前需要安装 python3-certbot-nginx,并确保 Nginx 配置检查通过。
申请通配符证书
通配符证书必须使用 DNS 验证:
代码语言:bash复制sudo certbot certonly --manual --preferred-challenges dns -d example.com -d '*.example.com'
Certbot 会要求用户创建 DNS TXT 记录。手动 DNS 验证不适合无人值守续约。
配置和验证证书
配置 Nginx
Certbot 默认将证书保存在以下目录:
代码语言:plain复制/etc/letsencrypt/live/example.com/
Nginx 通常使用以下两个文件:
代码语言:nginx复制ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
完整的 HTTPS 配置示例:
代码语言:nginx复制server {listen 443 ssl;listen [::]:443 ssl;server_name example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;root /var/www/html;}
检查并重载 Nginx:
代码语言:bash复制sudo nginx -tsudo systemctl reload nginx
不要将 privkey.pem 提交到 Git 仓库,也不要向其他用户开放读取权限。
验证证书
查看证书主题、签发机构和有效期:
代码语言:bash复制sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -subject -issuer -dates
测试 HTTPS 连接:
代码语言:bash复制curl -I https://example.com
检查 Nginx 配置:
代码语言:bash复制sudo nginx -t
查看证书状态
查看全部证书
列出 Certbot 管理的证书:
代码语言:bash复制sudo certbot certificates
示例输出:
代码语言:plain复制Certificate Name: example.comDomains: example.com www.example.comExpiry Date: 2026-09-20 08:00:00 00:00Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pemPrivate Key Path: /etc/letsencrypt/live/example.com/privkey.pem
Certificate Name 是 Certbot 内部使用的证书名称。续约、撤销和删除证书时,可以通过 --cert-name 指定该名称。
查看证书目录
Certbot 的常用目录如下:
用途 | |
|---|---|
| 当前有效证书的软链接 |
| 证书的历史版本 |
| 每张证书的续约配置 |
| 自动续约 Hook 脚本 |
| Certbot 日志 |
| Certbot 工作数据 |
Web 服务应引用 /etc/letsencrypt/live/ 中的文件。
不要直接修改 live 或 archive 目录中的文件。
续约证书
测试续约
使用 Let's Encrypt 测试环境模拟续约:
代码语言:bash复制sudo certbot renew --dry-run
测试成功时,会出现类似输出:
代码语言:plain复制Congratulations, all simulated renewals succeeded
--dry-run 不会替换当前使用的正式证书。
执行续约
检查全部证书并续约符合条件的证书:
代码语言:bash复制sudo certbot renew
Certbot 4.0.0 及以上版本会根据证书总有效期计算续约时间。
当证书剩余有效期少于总有效期的三分之一时,Certbot 会尝试续约。有效期不超过 10 天的证书使用二分之一作为阈值。
certbot renew 可以频繁执行。尚未进入续约期的证书会被跳过。
续约指定证书
只检查指定证书:
代码语言:bash复制sudo certbot renew --cert-name example.com
强制续约指定证书:
代码语言:bash复制sudo certbot renew --cert-name example.com --force-renewal
强制续约会申请新的正式证书。频繁执行可能触发证书颁发机构的速率限制。
Certbot 2.3.0 及以上版本可以使用 reconfigure 修改续约参数:
sudo certbot reconfigure --cert-name example.com --webroot-path /srv/www/example.com
Certbot 会先通过测试环境验证新配置。验证成功后,新配置会用于后续续约。
不建议直接编辑以下文件:
代码语言:plain复制/etc/letsencrypt/renewal/example.com.conf
错误配置可能导致自动续约失败。
使用 Hook
Hook 类型
Hook (钩子) 可以在续约流程的不同阶段执行命令。
Hook | 执行时间 | 常见用途 |
|---|---|---|
| 开始续约尝试前 | 停止占用 TCP 80 的服务 |
| 完成续约尝试后 | 恢复此前停止的服务 |
| 证书成功签发或续约后 | 重载 Web 服务或部署证书 |
pre-hook 和 post-hook 只会在 Certbot 实际尝试续约时执行。
post-hook 不代表续约成功。需要在成功后执行的操作,应使用 deploy-hook。
使用命令行 Hook
standalone 模式需要释放 TCP 80 端口时,可以停止并恢复 Nginx:
代码语言:bash复制sudo certbot renew --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"
如果 Nginx 由 Docker Compose 管理,可以执行:
代码语言:bash复制sudo certbot renew --pre-hook "docker compose -f /srv/web/compose.yaml stop nginx" --post-hook "docker compose -f /srv/web/compose.yaml start nginx"
docker compose stop nginx 会停止现有容器,但不会删除容器。
docker compose start nginx 会重新启动该容器。
定时任务的工作目录并不固定。因此,Hook 中应通过 -f 指定 Compose 文件的绝对路径。
证书成功续约后,可以重载 Nginx:
代码语言:bash复制sudo certbot renew --deploy-hook "systemctl reload nginx"
使用 Hook 脚本目录
Certbot 会自动执行以下目录中的可执行文件:
代码语言:plain复制/etc/letsencrypt/renewal-hooks/pre//etc/letsencrypt/renewal-hooks/deploy//etc/letsencrypt/renewal-hooks/post/
Hook 脚本统一使用 .sh 后缀。该后缀可以明确表示文件类型,也便于编辑器识别 Shell 语法。
脚本名称中的 10- 和 90- 用于控制执行顺序。Certbot 会按照文件名的字节顺序,执行同一个 Hook 目录中的脚本。
例如,以下脚本的执行顺序为:
代码语言:plain复制10-stop-nginx.sh20-stop-other-service.sh90-write-log.sh
pre、deploy 和 post 是相互独立的目录。文件名排序只影响同一个目录中的执行顺序。
创建 standalone 模式的 Docker Compose 停止脚本:
代码语言:bash复制sudo nano /etc/letsencrypt/renewal-hooks/pre/10-stop-nginx.sh
写入以下内容:
代码语言:sh复制#!/bin/shset -eu/usr/bin/docker compose -f /srv/web/compose.yaml stop nginx
创建恢复脚本:
代码语言:bash复制sudo nano /etc/letsencrypt/renewal-hooks/post/90-start-nginx.sh
写入以下内容:
代码语言:sh复制#!/bin/shset -eu/usr/bin/docker compose -f /srv/web/compose.yaml start nginx
授予脚本执行权限:
代码语言:bash复制sudo chmod x /etc/letsencrypt/renewal-hooks/pre/10-stop-nginx.sh /etc/letsencrypt/renewal-hooks/post/90-start-nginx.sh
检查脚本权限:
代码语言:bash复制sudo ls -l /etc/letsencrypt/renewal-hooks/pre/ /etc/letsencrypt/renewal-hooks/post/
确认 Docker 的实际路径:
代码语言:bash复制command -v docker
如果输出路径不是 /usr/bin/docker,需要同步修改脚本。
测试 deploy-hook
普通 --dry-run 不会执行 deploy-hook。
测试续约和 deploy-hook:
sudo certbot renew --dry-run --run-deploy-hooks
测试成功时,Certbot 会使用当前正式证书执行 deploy-hook。他不会部署测试环境生成的临时证书。
管理自动续约
查看定时器状态
通过 Debian 软件包安装 Certbot 后,系统通常会创建 systemd 定时器。
查看定时器状态:
代码语言:bash复制sudo systemctl status certbot.timer
查看下次执行时间:
代码语言:bash复制sudo systemctl list-timers --all | grep certbot
启用并立即启动定时器:
代码语言:bash复制sudo systemctl enable --now certbot.timer
正常运行时,状态通常为:
代码语言:plain复制Active: active (waiting)
waiting 表示定时器正在等待下一次触发。
定时器会触发以下服务:
代码语言:plain复制certbot.service
certbot.service 通常是一次性任务。任务执行完成后,显示 inactive (dead) 属于正常情况。
查看续约日志
查看 certbot.service 日志:
sudo journalctl --unit certbot.service --lines 50 --no-pager
查看最近一次启动后的日志:
代码语言:bash复制sudo journalctl --unit certbot.service --boot --no-pager
查看 Certbot 文件日志:
代码语言:bash复制sudo tail -n 100 /var/log/letsencrypt/letsencrypt.log
实时查看日志:
代码语言:bash复制sudo tail -f /var/log/letsencrypt/letsencrypt.log
撤销和删除证书
撤销证书
撤销操作会通知证书颁发机构停止信任该证书。
按证书名称撤销:
代码语言:bash复制sudo certbot revoke --cert-name example.com
也可以使用证书文件:
代码语言:bash复制sudo certbot revoke --cert-path /etc/letsencrypt/live/example.com/cert.pem
私钥泄露时,可以指定撤销原因:
代码语言:bash复制sudo certbot revoke --cert-name example.com --reason keycompromise
撤销后,如果保留续约配置,Certbot 仍可能再次尝试续约。无需继续使用时,应同时删除该证书。
删除证书
先查看证书名称:
代码语言:bash复制sudo certbot certificates
删除证书前,需要移除 Nginx、Apache 或其他服务中的证书路径引用。
确认服务配置不再引用该证书后,执行:
代码语言:bash复制sudo certbot delete --cert-name example.com
不要直接删除 /etc/letsencrypt/ 中的证书文件。
删除操作不会自动撤销证书。私钥未泄露时,通常不需要专门撤销。
常见问题
TCP 80 端口被占用
错误示例:
代码语言:plain复制Could not bind TCP port 80 because it is already in use
查看端口占用情况:
代码语言:bash复制sudo ss -ltnp | grep ':80'
也可以使用:
代码语言:bash复制sudo lsof -iTCP:80 -sTCP:LISTEN
停止对应服务后,重新测试续约:
代码语言:bash复制sudo certbot renew --dry-run
Docker Compose 服务占用端口
查看容器端口映射:
代码语言:bash复制docker compose ps
查看全部运行中的容器:
代码语言:bash复制docker ps --format 'table {{.Names}}{{.Ports}}'
停止指定 Compose 服务:
代码语言:bash复制docker compose -f /srv/web/compose.yaml stop nginx
重新启动指定服务:
代码语言:bash复制docker compose -f /srv/web/compose.yaml start nginx
start 只能启动已经存在且处于停止状态的容器。
如果容器已经通过 docker compose down 删除,需要重新创建:
docker compose -f /srv/web/compose.yaml up -d nginx
standalone 模式配合自动续约时,应配置 pre-hook 和 post-hook。否则,systemd 定时续约可能因端口冲突而失败。
域名验证失败
检查 IPv4 解析:
代码语言:bash复制dig short A example.com
检查 IPv6 解析:
代码语言:bash复制dig short AAAA example.com
检查 HTTP 是否可以访问:
代码语言:bash复制curl -I http://example.com
如果存在错误的 AAAA 记录,Let's Encrypt 可能访问错误的 IPv6 地址。此时需要修正或删除该记录。
还需要检查以下项目:
云服务安全组Debian 防火墙路由器端口转发运营商端口限制HTTP 重定向规则webroot 验证文件无法访问
创建测试文件:
代码语言:bash复制sudo mkdir -p /var/www/html/.well-known/acme-challengeecho 'certbot-test' | sudo tee /var/www/html/.well-known/acme-challenge/test
从外部访问:
代码语言:bash复制curl http://example.com/.well-known/acme-challenge/test
预期输出:
代码语言:plain复制certbot-test
测试完成后删除文件:
代码语言:bash复制sudo rm /var/www/html/.well-known/acme-challenge/test
如果返回 403 或 404,需要检查 Nginx 的 root、alias、try_files 和隐藏文件拦截规则。
查看详细错误日志:
代码语言:bash复制sudo certbot renew --dry-run -v
总结
Debian 可以通过 APT 安装 Certbot 及其 Web 服务插件。已经运行 Nginx 的服务器,优先使用 Nginx 插件或webroot 模式。这两种方式通常不需要停止 Web 服务。standalone 模式适合没有 Web 服务的服务器。该模式也适合可以短暂停止反向袋里的场景。Docker 容器占用 TCP 80 时,可以使用 Hook 停止并恢复指定服务。Hook 应使用 Compose 文件的绝对路径。Hook 脚本应使用 .sh 后缀,并通过数字前缀控制执行顺序。完成配置后,应检查 certbot.timer,并执行测试: sudo certbot renew --dry-run只有测试成功,才能确认自动续约流程可以正常工作。版权声明
本文为原创文章,作者保留版权。转载请保留本文完整内容,并以超链接形式注明作者及原文出处。
作者: 除除
原文: https://blog.mazey.net/6504.html
<!-- ID: 20260899-debian-certbot -->
(完)
-
09.01
燕云十六声不见山野外首领位置在哪
-
09.01
三角洲行动如何主动部署脚架
-
09.01
鸣潮爱弥斯培养攻略 鸣潮爱弥斯声骸武器阵容推荐
-
09.01
明日方舟终末地顶配物理队如何养成 明日方舟终末地顶配物理队养成攻略
-
09.01
黑白的守护在那里得到
-
09.01
原神龙龙同游第一关如何过
-
-
下载
- |
-
-
下载
- 《行尸走肉第一章》免安装中文汉化硬盘版下载
- 单机|436 MB
- 一款以动作冒险为主题的游戏
-
-
下载
- 《街头霸王X铁拳》免安装中文汉化硬盘版下载
- 单机|111MB
- 一款非常好玩的格斗游戏
-
-
下载
- |
-
-
下载
- 《暗黑破坏神3》免安装繁体中文正式版下载
- 单机|7630 MB
- 一款以角色扮演为主题的游戏
-
-
下载
- 《马克思佩恩3》免安装硬盘版下载
- 单机|27033 MB
- 一款以第三人称射击为主题的游戏