目录
- 背景
- 环境信息
- 为什么使用 DNS-01
- 安装 Certbot
- DNS 插件选择
- 安装腾讯云 DNS 插件
- 配置腾讯云 API
- 签发泛域名证书
- Docker Nginx 使用证书
- 自动续期
- 配置 systemd 定时任务
- 最终目录结构
- 总结
背景
服务器上部署了 GitLab、Jenkins、Kibana、WXBotAssistant 等多个服务,统一通过 Docker Nginx 做反向代理。随着服务增加,为每个子域名单独维护 HTTPS 证书越来越麻烦,因此计划申请一个泛域名证书:
*.quinlanxie.cloud覆盖:
gitlab.quinlanxie.cloud jenkins.quinlanxie.cloud kibana.quinlanxie.cloud wx.quinlanxie.cloud api.quinlanxie.cloud最终目标:
- 一个证书覆盖所有子域名
- Certbot 自动续期
- Nginx 统一引用证书
- 新增服务无需重新申请证书
最终结构:
DNSPod | | Certbot DNS-01 Challenge | | Let's Encrypt | | /data/docker/nginx/certs | | Docker Nginx环境信息
服务器:
cat/etc/os-release系统:
OpenCloudOS 9.4域名:
quinlanxie.cloud查看 DNS:
digNS quinlanxie.cloud结果:
quinlanxie.cloud. IN NS columba.dnspod.net. quinlanxie.cloud. IN NS trunk.dnspod.net.说明域名解析托管在 DNSPod。
为什么使用 DNS-01
Let’s Encrypt 支持 HTTP-01 和 DNS-01 两种验证方式。
普通域名:
example.com可以通过 HTTP 验证。
但是泛域名:
*.quinlanxie.cloud必须使用 DNS-01,通过 DNS TXT 记录完成验证:
_acme-challenge.quinlanxie.cloudCertbot 会调用 DNS API 自动创建 TXT 记录,验证完成后自动删除。
安装 Certbot
OpenCloudOS 9.4 属于 RHEL 9 系环境,采用 Python venv 安装,避免污染系统 Python。
安装依赖:
dnfinstallpython3 python3-pip python3-devel gcc-y创建虚拟环境:
mkdir-p/opt/certbot python3-mvenv /opt/certbot/venvsource/opt/certbot/venv/bin/activate升级 pip:
pipinstall--upgradepip安装 Certbot:
pipinstallcertbot验证:
certbot--version输出:
certbot 5.7.0DNS 插件选择
最开始尝试使用:
certbot-dns-dnspod但是申请时出现:
Record.Create error: http error status: 401原因是该插件依赖 DNSPod 老 API,需要:
dns_dnspod_email dns_dnspod_api_id dns_dnspod_api_token当前账号没有绑定邮箱,无法完成认证。
最终切换到:
certbot-dns-tencentcloud使用腾讯云 API:
SecretId SecretKey进行 DNS 管理。
安装腾讯云 DNS 插件
进入虚拟环境:
source/opt/certbot/venv/bin/activate安装:
pipinstallcertbot-dns-tencentcloud检查:
certbot plugins确认存在:
dns-tencentcloud配置腾讯云 API
在腾讯云控制台:
访问管理 -> API密钥管理创建密钥,获取:
SecretId SecretKey创建配置文件:
mkdir-p/root/.secrets/certbotvim/root/.secrets/certbot/tencentcloud.ini内容:
dns_tencentcloud_secret_id = AKIDxxxxxxxx dns_tencentcloud_secret_key = xxxxxxxxx设置权限:
chmod600/root/.secrets/certbot/tencentcloud.ini签发泛域名证书
证书统一存放:
/data/docker/nginx/certs/目录:
/data/docker/nginx/certs ├── letsencrypt ├── work └── logs执行:
/opt/certbot/venv/bin/certbot certonly\--config-dir /data/docker/nginx/certs/letsencrypt\--work-dir /data/docker/nginx/certs/work\--logs-dir /data/docker/nginx/certs/logs\--authenticatordns-tencentcloud\--dns-tencentcloud-credentials /root/.secrets/certbot/tencentcloud.ini\-d"*.quinlanxie.cloud"\-dquinlanxie.cloud注意:
*.quinlanxie.cloud只能匹配:
xxx.quinlanxie.cloud不包含:
quinlanxie.cloud所以需要同时申请:
*.quinlanxie.cloud quinlanxie.cloud成功后:
/data/docker/nginx/certs/letsencrypt/live/quinlanxie.cloud/生成:
cert.pem chain.pem fullchain.pem privkey.pemDocker Nginx 使用证书
docker-compose 挂载:
volumes:-/data/docker/nginx/certs/letsencrypt:/etc/letsencrypt:roNginx:
server { listen 443 ssl; server_name jenkins.quinlanxie.cloud; ssl_certificate /etc/letsencrypt/live/quinlanxie.cloud/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/quinlanxie.cloud/privkey.pem; location / { proxy_pass http://jenkins:8080; } }修改后:
nginx-t重新加载:
dockerexecnginx nginx-sreload自动续期
Let’s Encrypt 证书有效期为 90 天,Certbot 会定期检查:
- 剩余时间超过 30 天:跳过
- 剩余时间不足 30 天:自动续期
由于 Certbot 安装在 venv 中,定时任务不要依赖:
source/opt/certbot/venv/bin/activate直接调用完整路径。
创建续期脚本:
vim/usr/local/bin/certbot-renew.sh内容:
#!/bin/bash/opt/certbot/venv/bin/certbot renew\--config-dir /data/docker/nginx/certs/letsencrypt\--work-dir /data/docker/nginx/certs/work\--logs-dir /data/docker/nginx/certs/logs\--quiet\--deploy-hook"docker exec nginx nginx -s reload"授权:
chmod+x /usr/local/bin/certbot-renew.sh测试:
/usr/local/bin/certbot-renew.sh配置 systemd 定时任务
创建:
vim/etc/systemd/system/certbot-renew.service内容:
[Unit] Description=Certbot renew [Service] Type=oneshot ExecStart=/usr/local/bin/certbot-renew.sh创建定时器:
vim/etc/systemd/system/certbot-renew.timer内容:
[Unit] Description=Certbot renew timer [Timer] OnCalendar=*-*-* 03:30:00 Persistent=true [Install] WantedBy=timers.target启用:
systemctl daemon-reload systemctlenable--nowcertbot-renew.timer查看:
systemctl list-timers|grepcertbot测试续期:
/opt/certbot/venv/bin/certbot renew\--config-dir /data/docker/nginx/certs/letsencrypt\--dry-run成功:
Congratulations, all simulated renewals succeeded最终目录结构
/data/docker/nginx ├── conf.d ├── docker-compose.yml └── certs | ├── letsencrypt | | | └── live | | | └── quinlanxie.cloud | | | ├── fullchain.pem | └── privkey.pem | ├── work └── logs总结
最终方案:
OpenCloudOS 9.4 + Python venv + Certbot 5.7.0 + certbot-dns-tencentcloud + DNSPod DNS + Let's Encrypt Wildcard Certificate + Docker Nginx这套方案解决了多服务 HTTPS 维护问题。
以后新增:
xxx.quinlanxie.cloud只需要:
- 增加 Nginx 反向代理配置
- reload Nginx
无需重新申请证书。