典型生产环境中,这些路径映射为:
/etc/letsencrypt/live/: 包含指向最新证书的符号链接,如fullchain.pem和privkey.pem/etc/letsencrypt/archive/: 存储所有历史证书版本(自动轮转)/etc/letsencrypt/renewal/: 域名续期配置文件(.conf格式)
警告:live目录下的证书文件实为符号链接,直接复制可能导致备份失效,需通过配置文件获取真实路径。
在原服务器备份
# 创建迁移包(排除敏感日志)
tar -czf certbot-migration.tar.gz --exclude=logs /etc/letsencrypt/{live,archive,renewal}
# 会有两不影响压缩的提示
tar: Removing leading `/' from member names
tar: Removing leading `/' from hard link targets
在目标服务器还原
# 在目标服务器还原
tar -xzf /tmp/certbot-migration.tar.gz -C /
# 检查 renewal配置文件
vim /etc/letsencrypt/renewal/example.com.conf
# 关键参数检查:
# - authenticator(验证方式)
# - installer(服务器类型)
# - server(ACME端点URL)
# 检查权限:私钥权限必须为600,为仅root可读写
sudo find /etc/letsencrypt -type f -name "*.pem"|xargs sudo ls -l
# chmod 600 /etc/letsencrypt/live/*/privkey.pem
# chown -R root:root /etc/letsencrypt/
完成迁移后,需要执行全面检查
| 检查项 | 验证命令 | 预期结果 |
|---|---|---|
| 证书有效期 | sudo certbot certificates | 所有证书状态为”Valid” |
| 续期验证 | sudo certbot renew --dry-run | 能续期成功 |
| 自动续期配置 | sudo systemctl status certbot.timer或 sudo crontab -l | 定时器处于active状态 或 有 0 2 5,20 * * /usr/bin/certbot renew --quiet记录 |
| HTTPS连通性 | curl -I https://example.com | 响应码200,包含”Server: nginx”等 |
| OCSP stapling | openssl s_client -connect example.com:443 -status | 包含”OCSP Response Status: successful” |
Systemd 中的 certbot 定时器
$ sudo systemctl list-unit-files --type service # 查看所有 Service 单元
$ sudo systemctl list-unit-files --type timer # 查看所有 Timer 单元
/lib/systemd/system/:系统默认的单元文件/etc/systemd/system/:用户安装的软件的单元文件/usr/lib/systemd/system/:用户自己定义(机器范围)的单元文件~/.config/systemd/user/:用户自己定义(用户范围,需要对用记登录后,才会被执行)的单元文件,还有在使用systemctl时,要加上--user参数,比如:
systemctl --user daemon-reload
systemctl --user start test.timer
systemctl --user list-timers
systemctl --user stop test.timer
systemctl --user status test.service
certbot定时器的配置文件
$ sudo cat /usr/lib/systemd/system/certbot.timer
[Unit]
Description=Run certbot twice daily
[Timer]
OnCalendar=*-*-* 00,12:00:00
RandomizedDelaySec=43200
Persistent=true
[Install]
WantedBy=timers.target
$ sudo cat /usr/lib/systemd/system/certbot.service
[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://certbot.eff.org/docs
[Service]
Type=oneshot
ExecStart=/usr/bin/certbot -q renew --no-random-sleep-on-renew
PrivateTmp=true
定时器分为两种类型:实时定时器和单调定时器,官方文档:时间写法/时间表示方法、定时器单元配置描述。
- 实时定时器基于绝对时间,也就是日历事件(如每天、每周),使用
OnCalendar=配置。 - 单调定时器基于相对时间(如系统启动后 15 分钟),使用
OnBootSec=或OnUnitActiveSec=等等字段,更多看官方配置说明。OnActiveSec:定时器生效后,多少时间开始执行任务OnBootSec:系统启动后,多少时间开始执行任务OnStartupSec:Systemd 进程启动后,多少时间开始执行任务OnUnitActiveSec:该单元上次执行后,等多少时间再次执行OnUnitInactiveSec: 定时器上次关闭后多少时间,再次执行AccuracySec:如果因为各种原因,任务必须推迟执行,推迟的最大秒数,默认是60秒
certbot.timer的配置描述
OnCalendar=*-*-* 00,12:00:00表示每天的0点和12点。=1h表示每一小时,=*-*-* 02:00:00表示每天凌晨两点,=Mon *-*-* 02:00:00表示每周一凌晨两点。更多见时间表示方法。
RandomizedDelaySec=43200表示可以随机延时范围在43200s,也就是6小时之间。起到避免在同一个时间里,有大量定时任务被触发;对应,有一个相反作用的参数AccuracySec或者配置“RandomizedDelaySec=0`。Persistent=true表示定时器到时没有启动,也会自动执行相应的单元,仅对使用”OnCalendar=“配置的计时器有效。Unit=表示当此计时器到期时激活的执行单位。如果在[Timer]里面没有Unit=时,则默认为与计时器单位名称相同的服务,可以下面查看状态中看到相关内容。WantedBy=timers.target表示此定时器归属于timers.target。- Target 指的是一组相关进程,有点像 init 进程模式下面的启动级别。启动某个Target 的时候,属于这个 Target 的所有进程都会全部启动。
certbot.timer的状态查看
$ sudo systemctl list-timers|grep -e certbot -e NEXT
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sat 2026-01-17 06:43:12 CST 6h Fri 2026-01-16 18:33:40 CST 5h 47min ago certbot.timer certbot.service
$ sudo systemctl status certbot.timer
● certbot.timer - Run certbot twice daily
Loaded: loaded (/usr/lib/systemd/system/certbot.timer; enabled; preset: enabled)
Active: active (waiting) since Fri 2025-11-28 21:12:13 CST; 1 month 18 days ago
Trigger: Sat 2026-01-17 06:43:12 CST; 6h left
Triggers: ● certbot.service
Nov 28 21:12:13 vps-251018 systemd[1]: Started certbot.timer - Run certbot twice daily.
$ sudo systemctl status certbot.service
○ certbot.service - Certbot
Loaded: loaded (/usr/lib/systemd/system/certbot.service; static)
Active: inactive (dead) since Sat 2026-01-17 17:12:21 CST; 4min 29s ago
TriggeredBy: ● certbot.timer
Docs: file:///usr/share/doc/python-certbot-doc/html/index.html
https://certbot.eff.org/docs
Process: 949468 ExecStart=/usr/bin/certbot -q renew --no-random-sleep-on-renew (code=exited, status=0/SUCCESS)
Main PID: 949468 (code=exited, status=0/SUCCESS)
CPU: 1.053s
Jan 17 17:12:19 vps-251018 systemd[1]: Starting certbot.service - Certbot...
Jan 17 17:12:21 vps-251018 systemd[1]: certbot.service: Deactivated successfully.
Jan 17 17:12:21 vps-251018 systemd[1]: Finished certbot.service - Certbot.
Jan 17 17:12:21 vps-251018 systemd[1]: certbot.service: Consumed 1.053s CPU time.
Systemd timers
Systemd timers 与传统的 crontab 相比,使用 Systemd 管理定时任务主要有以下优势:
- 统一的日志系统:日志自动汇集到journald,方便搜索和分析
- 资源控制能力:可以限制任务占用的CPU和内存等资源,且不会重复执行定时任务
- 模块化管理:依赖关系清晰,易于管理复杂任务
缺点也有,就看你的使用场景。
systemd timer 入门示例
创建systemd timer定时任务时,需要同时编写两个文件:
- 编写一个以.timer为后缀的Systemd Unit,该文件描述定时任务如何定时
- 编写一个以.service为后缀的Systemd Service Unit,该文件描述定时任务要执行的操作
这两个文件名称通常保持一致(除了后缀部分),它们可以放在/usr/lib/systemd/system
backup.sh
在 /tmp/backup_output.log 中写入“Backup Completed!”及当前时间和日期信息。
#!/bin/bash
echo "Backup Completed! $(date)" >> /tmp/backup_output.log
配置可执行权限
chmod +x backup.sh
backup.service
如果服务以非零退出码结束,则会尝试在定义的时间间隔内重新启动至指定的次数。
[Unit]
Description=Backup Script
[Service]
ExecStart=/path/to/backup.sh
Restart=on-failure
RestartSec=10s
StartLimitInterval=60s
StartLimitBurst=5
backup.timer
周一到周五的2点启动
[Unit]
Description=Backup Timer
[Timer]
OnCalendar=Mon..Fri:02:00:00
Persistent=true
[Install]
WantedBy=timers.target
启用并启动定时器
sudo systemctl daemon-reload
# 是由 backup.timer 去启动 backup.service,所以不需要配置 backup.service
sudo systemctl enable backup.timer
sudo systemctl start backup.timer
# 查看 backup.service 的日志
sudo journalctl -u backup.service
发表回复