certbot自动申请及更新证书 cloudflare DNS认证 token认证
简介:#
搞了几次,证书都不太方便。
最终找到certbot这个工具。
每周可以创建5个证书。
Certbot 是 EFF 加密整个互联网工作的一部分。Web 上的安全通信依赖于 HTTPS,这需要使用数字证书来验证 Web 服务器的身份(例如,这真的 google.com 吗?Web 服务器从受信任的第三方(称为证书颁发机构 (CA)获取其证书。Certbot 是一个易于使用的客户端,它从 Let's Encrypt(由 EFF、Mozilla 和其他公司启动的开放证书颁发机构)获取证书,并将其部署到 Web 服务器。
任何经历过建立安全网站的人都知道获取和维护证书是多么麻烦。Certbot 和 Let's Encrypt 可以自动消除痛苦,让您使用简单的命令打开和管理 HTTPS。使用 Certbot 和 Let's Encrypt 是免费的。
欢迎使用 certbot-dns-cloudflare 的文档!— certbot-dns-cloudflare 0 文档
有配合cloudflare验证域名所有权的专用插件,也有专门的docker镜像。
安装:#
我是喜欢使用docker的,那么就继续docker吧。
创建一个配置文件:
我的目录在 ~/certbot/cloudflare.ini
凭证
#
使用此插件需要一个包含 Cloudflare API 的配置文件 凭据,从您的 Cloudflare 仪表板获取。
然而,以前,Cloudflare 的“全局 API 密钥”用于身份验证 此密钥可以访问您帐户中所有域的整个 Cloudflare API, 这意味着如果泄漏,可能会造成很大的损害。
Cloudflare 的新 API Token 可以限制为特定域和 操作,因此现在是推荐的身份验证选项。
Certbot 所需的 API Token 只需要 您需要证书的区域。Zone:DNS:Edit
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
# Cloudflare API credentials used by Certbot
dns_cloudflare_email = cloudflare@example.com
dns_cloudflare_api_key = 0123456789abcdef0123456789abcdef01234
配置文件:#
#/root/certbot/cloudflare.ini
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
第一次脚本:#
区分第一次脚本主要是有一个交互输入的过程。用来输入你的邮箱,并同意用户协议。
#/bin/bash # 同目录创建certbot/cloudflare.ini文件 # Cloudflare API credentials used by Certbot # dns_cloudflare_email = jack***********.com # dns_cloudflare_api_token = e***********************************1sudo docker run -i --rm --name certbot \ -v "$PWD/certbot/letsencryptetc:/etc/letsencrypt" \ -v "$PWD/certbot/letsencryptvar:/var/lib/letsencrypt" \ -v "$PWD/certbot/log:/var/log" \ -v "$PWD/certbot:/certbot" \ certbot/dns-cloudflare certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /certbot/cloudflare.ini \ --dns-cloudflare-propagation-seconds 60 \ -d *.jackadam.top
后续脚本:#
后续脚本也有一些问题,需要输入2,更新这个证书文件。
#/bin/bash # 同目录创建certbot/cloudflare.ini文件 # Cloudflare API credentials used by Certbot # dns_cloudflare_api_token = e***********************************1 # 第一次会交互输入一下邮箱,给certbot验证身份,并同意用户许可协议。 # 第一次脚本 sudo docker run -i --rm --name certbot \ -v "$PWD/certbot/letsencryptetc:/etc/letsencrypt" \ -v "$PWD/certbot/letsencryptvar:/var/lib/letsencrypt" \ -v "$PWD/certbot/log:/var/log" \ -v "$PWD/certbot:/certbot" \ certbot/dns-cloudflare certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /certbot/cloudflare.ini \ --dns-cloudflare-propagation-seconds 60 \ -d *.jackadam.top # 后续脚本 echo "2" | sudo docker run -i --rm --name certbot \ -v "$PWD/certbot/letsencryptetc:/etc/letsencrypt" \ -v "$PWD/certbot/letsencryptvar:/var/lib/letsencrypt" \ -v "$PWD/certbot/log:/var/log" \ -v "$PWD/certbot:/certbot" \ certbot/dns-cloudflare certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /certbot/cloudflare.ini \ --dns-cloudflare-propagation-seconds 60 \ -d *.jackadam.top
测试服务器#
certbot有每周5张证书的限制。所以建议你先使用测试服务器来玩通,再使用正式服务器。
# 后续脚本 echo "2" | sudo docker run -i --rm --name certbot \ -v "$PWD/certbot/letsencryptetc:/etc/letsencrypt" \ -v "$PWD/certbot/letsencryptvar:/var/lib/letsencrypt" \ -v "$PWD/certbot/log:/var/log" \ -v "$PWD/certbot:/certbot" \ certbot/dns-cloudflare certonly \ --dns-cloudflare \ --dns-cloudflare-credentials /certbot/cloudflare.ini \ --dns-cloudflare-propagation-seconds 60 \ --test-cert \ -d *.jackadam.top
加上红色这行。
定时任务:#
设置个定时脚本,定时检查吧。
User Guide — Certbot 2.10.0.dev0 documentation (eff-certbot.readthedocs.io)
官方脚本:
SLEEPTIME=$(awk 'BEGIN{srand(); print int(rand()*(3600+1))}'); echo "0 0,12 * * * root sleep $SLEEPTIME && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
没成功,还是手动设置吧。官方有个随机暂停,我们也设置吧。
0 3 * * * root sleep 369 && cd /root; certbot.sh
每周5张,有效期3个月,连续申请,大概最大容纳你60张证书吧,需要你自己把计划任务排好。
不过现在可以申请泛域名了,就是*.aaaaa.com,应该好用了。
88天循环脚本:#
为了保证不过期,三个月最长是有89天,那么我们应该88天更新证书。
但是cron不支持88天循环。自己写脚本吧。
#!/bin/bash # 配置文件路径 CONFIG_FILE="next_run_date.conf" # 获取当前日期 CURRENT_DATE=$(date +%Y-%m-%d) # 检查配置文件是否存在 if [ ! -f "$CONFIG_FILE" ]; then # 如果配置文件不存在,初始化下次运行日期为今天 echo "$CURRENT_DATE" > "$CONFIG_FILE" echo "配置文件不存在,已初始化为今天。" exit 0 fi # 读取配置文件中的下次运行日期 NEXT_RUN_DATE=$(cat "$CONFIG_FILE") # 检查今天是否是下次运行日期 if [ "$CURRENT_DATE" == "$NEXT_RUN_DATE" ]; then echo "今天是执行任务的日子,开始执行任务..." # 在这里执行你的任务 # your_command_here # 计算下次运行日期(88天后) NEXT_RUN_DATE=$(date -d "$CURRENT_DATE + 88 days" +%Y-%m-%d) echo "$NEXT_RUN_DATE" > "$CONFIG_FILE" echo "任务已执行,下次运行日期已更新为 $NEXT_RUN_DATE。" else echo "今天不是执行任务的日子。下次运行日期是 $NEXT_RUN_DATE。" fi
深入思考:#
我们已经写了这么多功能,那么我们是否可以再检查一下配置文件是否存在?
不存在,则执行交互命令,存在,则执行自动更新命令?
给小白准备个一键脚本。写了一半

1 #!/bin/bash 2 3 # 获取当前脚本的目录路径 / Get the directory path of the current script 4 SCRIPT_DIR=$(dirname "$(realpath "$0")") 5 6 # 配置文件路径 / Configuration file path 7 CONFIG_FILE="$SCRIPT_DIR/cert.json" 8 9 # 检查 jq 是否已安装 / Check if jq is installed 10 check_jq_installed() { 11 if ! command -v jq &> /dev/null; then 12 echo "jq 未安装。请使用以下命令安装 jq:" "jq is not installed. Please install jq using the following command:" 13 echo "Debian/Ubuntu: sudo apt install jq" 14 echo "Red Hat/CentOS: sudo yum install jq" 15 echo "Fedora: sudo dnf install jq" 16 echo "macOS: brew install jq" 17 exit 1 18 fi 19 } 20 21 # 获取当前脚本的完整路径 / Get the full path of the current script 22 get_script_path() { 23 realpath "$0" 24 } 25 26 # 生成随机的小时和分钟 / Generate random hour and minute 27 generate_random_time() { 28 local random_hour=$((RANDOM % 24)) 29 local random_minute=$((RANDOM % 60)) 30 echo "$random_minute $random_hour" 31 } 32 33 # 检查并添加 cron 任务 / Check and add cron task 34 check_and_add_cron_task() { 35 local cron_identifier=$(jq -r '.cron_identifier' "$CONFIG_FILE") 36 local script_path=$(get_script_path) 37 if crontab -l | grep -q "$cron_identifier"; then 38 output_message "cron 中已包含该任务。" "The task is already in cron." 39 else 40 output_message "cron 中不包含该任务,正在添加..." "The task is not in cron, adding it..." 41 local random_time=$(generate_random_time) 42 (crontab -l 2>/dev/null; echo "$random_time * * * $script_path # $cron_identifier") | crontab - 43 output_message "cron 任务已添加,时间为每天的 $random_time。" "Cron task added, scheduled at $random_time every day." 44 fi 45 } 46 47 # 获取当前日期 / Get the current date 48 get_current_date() { 49 date +%Y-%m-%d 50 } 51 52 # 初始化配置文件 / Initialize configuration file 53 initialize_config() { 54 local current_date=$(get_current_date) 55 cat <<EOF > "$CONFIG_FILE" 56 { 57 "next_run_date": "$current_date", 58 "email": "your_email@example.com", 59 "token": "your_token", 60 "certificate_path": "/path/to/certificate", 61 "cron_identifier": "88day for certbot", 62 "language": "en" 63 } 64 EOF 65 output_message "配置文件不存在,已初始化。" "Configuration file not found, initialized." 66 } 67 68 # 读取下次运行日期 / Read the next run date 69 read_next_run_date() { 70 jq -r '.next_run_date' "$CONFIG_FILE" 71 } 72 73 # 更新下次运行日期 / Update the next run date 74 update_next_run_date() { 75 local current_date=$(get_current_date) 76 local next_run_date=$(date -d "$current_date + 84 days" +%Y-%m-%d) 77 jq --arg next_run_date "$next_run_date" '.next_run_date = $next_run_date' "$CONFIG_FILE" > tmp.$$.json && mv tmp.$$.json "$CONFIG_FILE" 78 output_message "任务已执行,下次运行日期已更新为 $next_run_date。" "Task executed, next run date updated to $next_run_date." 79 } 80 81 # 执行任务 / Execute the task 82 execute_task() { 83 output_message "今天是执行任务的日子,开始执行任务..." "Today is the day to execute the task, starting..." 84 # 在这里执行你的任务 / Execute your task here 85 # 你可以使用 jq 提取其他配置项,例如:/ You can use jq to extract other configuration items, for example: 86 local email=$(jq -r '.email' "$CONFIG_FILE") 87 local token=$(jq -r '.token' "$CONFIG_FILE") 88 local certificate_path=$(jq -r '.certificate_path' "$CONFIG_FILE") 89 # 使用这些变量执行你的任务 / Use these variables to execute your task 90 # your_command_here 91 } 92 93 # 输出信息 / Output message 94 output_message() { 95 local message_cn="$1" 96 local message_en="$2" 97 local language=$(jq -r '.language' "$CONFIG_FILE") 98 if [ "$language" == "cn" ]; then 99 echo "$message_cn" 100 else 101 echo "$message_en" 102 fi 103 } 104 105 # 主函数 / Main function 106 main() { 107 check_jq_installed 108 109 if [ ! -f "$CONFIG_FILE" ]; then 110 initialize_config 111 exit 0 112 fi 113 114 check_and_add_cron_task 115 116 local current_date=$(get_current_date) 117 local next_run_date=$(read_next_run_date) 118 119 if [ "$current_date" == "$next_run_date" ]; then 120 execute_task 121 update_next_run_date 122 else 123 output_message "今天不是执行任务的日子。下次运行日期是 $next_run_date。" "Today is not the day to execute the task. Next run date is $next_run_date." 124 fi 125 } 126 127 # 调用主函数 / Call the main function 128 main
使用证书:#
获取的证书存在/root/letsencrypt/live
根据自己的需要,直接挂载NGINX也是可以的,
定时脚本,也可以再加两行:
docker compose -f *****.yaml down
*******
docker compose -f *****.yaml up -d
作者:上官飞鸿
出处:https://www.cnblogs.com/jackadam/p/18049561
版权:本作品采用「知识共享-署名-非商业性-禁止演绎(CC-BY-NC-ND)」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2023-03-03 修复cmd bat 批处理的打开方式
2018-03-03 docker(三)容器的基本操作