前言 #
为什么需要使用SSL证书自动部署?
- SSL证书的时间比较短,之前可以使用1年证书的时候手动部署无所谓,但是最近两年(指从24年开始)免费证书的有效期都普遍变成了3个月。每三个月都得手动续期一下,我自己每三个月拉一次证书和私钥、然后传到服务器上的这个流程已经做了十几遍了,流汗了🤣😅。
- 现在的短有效期证书以后可能会更短,据说CA/Browser Forum通过的决议会在2029年让证书最长有效期会缩到47天。这种短周期会让倒闭证书的自动化部署流程,同时减少网站内容传输没有被SSL证书加密、而被劫持的风险。
- 现在的SSL证书本质上就是可以给你的网站内容传输做一次加密,实际上也是WebPKI信任模型的边界:证书不能帮你证明这是家合法合规公司,他只负责加密通道。
证书自动化的机制:
- ACME协议把证书申请变成了可编程的API:通过DNS验证某个域名是你自己的,CA就会给你发证书。(
Let's Encrypt真是能和cloudflare类比的大好人啊,我以前还以为证书都需要自己花钱买的。)
我的情况:
- 我只需要更新SSL的cert和key,将cert和key替换原来的证书和密钥文件,然后重启nginx,现在需要做的就是实现这个流程的自动化。
- 之前我在ohttps上申请证书并部署到服务器上,使用fullchain.pem(证书和中间证书)和certkey.pem(私钥)两个文件。
- 现在使用certbot和python3-certbot-dns-cloudflare自动化该流程,向
let's encrypt申请通配符证书到本地。
关于我为什么需要SSL证书:
- Damn的密码管理器VaultWarden强制需要SSL证书,不然不给连接。
CertBot使用 #
基本流程:
- 1、安装
- 2、DNS 验证插件安装
- 3、使用CertBot申请证书
1、安装 #
两种方式: 1)使用snap安装
sudo apt update
sudo apt install snapd -y
sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
2)使用apt安装
apt install certbot
验证
certbot --version
2、DNS 验证插件安装 #
(1) 申请cloudflare的api token
申请cloudflare的api token(注意不是global token)
登录 Cloudflare:
- 进入 → My Profile
- 选择 → API Tokens
- 点击 → Create Token
- 使用模板:Edit zone DNS,其中权限必须包含:Zone:DNS+Zobe
- Zone Resources 选择:Include → Specific zone → aoidayo.site
保存并复制完整 token。
⚠️ 注意:不要多复制空格或换行。
(2) DNS API自动验证
DNS API自动验证:以Cloudflare为例:
1、安装插件
sudo apt install python3-certbot-dns-cloudflare
2、创建 API Token 文件
sudo nano /root/.cloudflare.ini
写入:
dns_cloudflare_api_token = NEywfvoLF012e5bvEQyqqntGL4V4L971YnTInGqd
设置权限:
sudo chmod 600 /root/.cloudflare.ini
3、certbot使用 #
1、申请通配符证书
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.cloudflare.ini \
-d aoidayo.site \
-d "*.aoidayo.site"
这一步需要你添加通知邮箱和一些协议,我都默认yes了。
❯ sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.cloudflare.ini \
-d aoidayo.site \
-d "*.aoidayo.site"
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for aoidayo.site and *.aoidayo.site
Waiting 10 seconds for DNS changes to propagate
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/aoidayo.site/fullchain.pem
Key is saved at: /etc/letsencrypt/live/aoidayo.site/privkey.pem
This certificate expires on 2026-05-31.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
成功后证书在:
/etc/letsencrypt/live/example.com/
2、同时certbot会自动创建定时任务:
查看:
systemctl list-timers | grep certbot
#
Tue 2026-03-03 09:46:37 CST 17h left n/a n/a certbot.timer certbot.service
3、测试续期:
sudo certbot renew --dry-run # 测试续期
sudo certbot renew --force-renewal # 强制续期
4、添加续期后hook
🤔 添加续期后hook,在复制证书后,自动reload nginx,最后写入nginx/ssl的op.log中。
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh #
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh # 赋权
我的bash脚本如下:
#!/bin/bash
set -e
# ==============================
# 基本变量
# ==============================
DOMAIN="aoidayo.site"
SRC_DIR="/etc/letsencrypt/live/$DOMAIN"
DST_DIR="/home/dockers/nginx/ssl/aoidayo"
LOG_FILE="$DST_DIR/op.log"
SRC_CERT="$SRC_DIR/fullchain.pem"
SRC_KEY="$SRC_DIR/privkey.pem"
DST_CERT="$DST_DIR/fullchain.pem"
DST_KEY="$DST_DIR/certkey.pem"
TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# ==============================
# 检查源文件是否存在
# ==============================
if [[ ! -f "$SRC_CERT" || ! -f "$SRC_KEY" ]]; then
echo "[$TIMESTAMP] ERROR: Source certificate files not found." >> "$LOG_FILE"
exit 1
fi
# ==============================
# 创建目标目录
# ==============================
mkdir -p "$DST_DIR"
# ==============================
# 复制并覆盖
# ==============================
cp -f "$SRC_CERT" "$DST_CERT"
cp -f "$SRC_KEY" "$DST_KEY"
# 设置合理权限
chmod 644 "$DST_CERT"
chmod 600 "$DST_KEY"
# ==============================
# 重启 docker nginx
# ==============================
if docker restart nginx-server > /dev/null 2>&1; then
echo "[$TIMESTAMP] SUCCESS: Certificate updated and nginx-server restarted." >> "$LOG_FILE"
else
echo "[$TIMESTAMP] ERROR: Docker restart failed!" >> "$LOG_FILE"
exit 1
fi
exit 0
参考 #
最后给出本文参考。
参考: