Loading

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

使用受限 API 令牌的凭证文件示例(推荐):
# Cloudflare API token used by Certbot
dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567
使用全局 API 密钥的凭证文件示例(不推荐):
# 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

 

第一次脚本:

区分第一次脚本主要是有一个交互输入的过程。用来输入你的邮箱,并同意用户协议。

  #/root/certbot.sh
#/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
View Code

 

 

 

使用证书:

获取的证书存在/root/letsencrypt/live

根据自己的需要,直接挂载NGINX也是可以的,

定时脚本,也可以再加两行:

docker compose -f *****.yaml down

*******

docker compose -f *****.yaml up -d

 

posted @ 2024-03-03 04:14  上官飞鸿  阅读(1040)  评论(0编辑  收藏  举报