侧边栏壁纸
博主头像
高压锅里的小白 博主等级

行动起来,活在当下

  • 累计撰写 65 篇文章
  • 累计创建 26 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Docker部署acme.sh申请ssl证书,并自动更新

高压锅里的小白
2024-04-02 / 0 评论 / 0 点赞 / 93 阅读 / 0 字
温馨提示:
本文最后更新于2024-04-08,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

项目简介

​ ​ acme.sh是github上的一个开源项目,它可以自动为你的网站向Let’s Encrypt申请并部署SSL证书。它具有以下特点:

  • 一个纯粹使用Shell(Unix shell)语言编写的ACME协议客户端。
  • 完整的ACME协议实现,支持ECDSA证书。
  • 支持SAN和通配符证书
  • 简单、强大且非常易于使用。
  • 兼容Bash、dash和sh。
  • 纯粹使用Shell编写,不依赖于python。
  • 只需一个脚本即可自动发放、更新和安装您的证书。
  • 无需root/sudoer权限。
  • 支持Docker
  • 支持IPv6
  • 用于续签或错误等的Cron作业通知。
  • 这可能是最简单且最智能的shell脚本,用于自动颁发和续签免费证书。

安装环境

工具 版本
系统 CentOS 7
Docker 25.0.4
Docker-Compose 2.24.7
acme.sh neilpang/acme.sh:latest

acme.sh GitHub

安装步骤

这里使用Docker-Compose的方式部署

安装Docker

具体安装步骤见:Docker安装教程

安装docker-compose

具体安装步骤见:Docker-Compose安装教程

安装acme.sh

新建目录

mkdir -p /你的路径/acme.sh/data

编写docker-compose.yml文件

在acme.sh目录下新建docker-compose.yml文件,并填写以下内容

version: "3"
services:
  acme.sh:
    image: neilpang/acme.sh:latest
    command: daemon
    environment:
      # 服务商的账号与key,这里是cloudflare,自己按需替换
      - CF_Key="xxxxxx"
      - CF_Email="xxx@xxx.com"
    volumes:
      # 将存放生成的证书文件的目录映射出来
      - $PWD/data:/acme.sh
      # 将update_time.txt文件映射进容器,用于后续逻辑
      - $PWD/shell/update_time.txt:/acme.sh/shell/update_time.txt
      - /etc/localtime:/etc/localtime:ro
    network_mode: host
    restart: unless-stopped

启动容器

在docker-compose.yml文件所在目录下执行

docker-compose up -d

至此acme.sh就安装好了

详细使用配置请查看官方文档

申请证书

docker-compose exec acme.sh --issue -d xxx.com --dns dns_cf --server letsencrypt

申请多个证书或泛域名证书

docker-compose exec acme.sh --issue -d xxx.com -d *.xxx.com --dns dns_cf --server letsencrypt

自动更新

​ ​ 在这里我没有使用acme.sh自带的自动更新证书,而是自己写了脚本实现,如果想使用官方的自动更新证书请查看官方文档

  1. 首先在刚才的目录下新建shell目录,存放相关脚本。

    mkdir -p /你的路径/acme.sh/shell
    
  2. 进入shell目录

    cd /你的路径/acme.sh/shell
    
  3. 新建一个名为 logfile.log的空文件,用于存放后续脚本的日志

    touch logfile.log
    
  4. 新建一个名为 update_time.txt的空文件,用于存放ssl成功更新日期

    touch update_time.txt
    
  5. 新建一个名为 start_acme.sh的脚本文件,用于更新ssl证书

    #!/bin/bash
    
    # 定义日志文件路径
    log_file="/你的路径/acme.sh/shell/logfile.log"
    
    # 指定日志输出路径
    exec >> ${log_file} 2>&1
    
    echo "################################ $(date) Start Update SSL #####################################" >> ${log_file}
    
    cd /你的路径/acme.sh
    # --reloadcmd是acme.sh的钩子函数,会在更新ssl证书成功后执行
    /usr/local/bin/docker-compose exec acme.sh --issue -d xxx.com -d *.xxx.com --dns dns_cf --server letsencrypt --reloadcmd "echo $(date '+%Y-%m-%d %H:%M:%S') >> /acme.sh/shell/update_time.txt"
    
    echo "################################# $(date) End Update SSL ######################################" >> ${log_file}
    
  6. 新建一个名为 check_ssl.sh的脚本文件,用于判断今日是否更新了证书

    #!/bin/bash
    
    # 定义日志文件路径
    log_file="/你的路径/acme.sh/shell/logfile.log"
    
    echo "" >> ${log_file}
    echo "################################ $(date) Start Check SSL Update Status #####################################" >> ${log_file}
    
    # 定义要检查的文件
    file_path="/你的路径/acme.sh/shell/update_time.txt"
    
    # 获取日志文件最后一行的日期
    last_date=$(date -d "$(tail -n1 $file_path)" "+%Y-%m-%d")
    
    # 获取今天的日期
    current_date=$(date "+%Y-%m-%d")
    
    # 记录日志
    echo "[$(date)] Start checking file ${file_path}. last_date is: ${last_date} current_date is: ${current_date}." >> ${log_file}
    
    # 判断日志文件最后一行的日期是否为今天
    if [ "$last_date" = "$current_date" ]; then
        # 如果是今天,记录信息并执行更新脚本
        echo "[$(date)] The file ${file_path} was changed today. Running script update_ssl.sh." >> ${log_file}
        ./update_ssl.sh
    else
        # 如果不是今天,记录信息
        echo "[$(date)] The file ${file_path} was not changed today." >> ${log_file}
    fi
    
    echo "################################# $(date) End Check SSL Update Status ######################################" >> ${log_file}
    echo "" >> ${log_file}
    
  7. 新建一个名为 update_ssl.sh的脚本文件,用于在更新ssl证书成功后,执行相关操作。
    下面的例子更新了本地与远程服务器的证书并重启了对应的nginx,可根据自己实际需求修改。

    #!/bin/bash
    
    # 定义日志文件路径
    log_file="/你的路径/acme.sh/shell/logfile.log"
    
    # 指定日志输出路径
    exec >> ${log_file} 2>&1
    
    echo "################################ $(date) Start Update SSL File #####################################"
    
    chmod -R 755 /你的路径/acme.sh/data/xxx.com_ecc
    
    # 重启nginx
    cd /你的路径/nginx
    docker-compose restart
    
    # 操作远程服务器nginx
    scp -r /你的路径/acme.sh/data/xxx.com_ecc root@xxx:/root/soft/ssl
    ssh root@xxx "cd /root/soft/nginx ; chmod -R 755 /root/soft/ssl ;  docker-compose restart"
    
    echo "################################# $(date) End Update SSL File ######################################"
    
  8. 新增cron定时任务

    • 首先使用 crontab命令来新增定时任务crontab -e

      crontab -e
      
      这会打开一个编辑器,允许你添加或修改计划任务。
      在这个编辑器中,你可以添加你的定时任务。每行一个任务,格式如下:
      * * * * * command-to-be-executed
      - - - - -
      | | | | |
      | | | | ----- Day of the week (0 - 7) (Sunday=0 or 7)
      | | | ------- Month (1 - 12)
      | | --------- Day of the month (1 - 31)
      | ----------- Hour (0 - 23)
      ------------ - Minute (0 - 59)
      
      例如,如果你想在每天晚上 11 点执行一个脚本 my-script.sh,你可以这样写:
      0 23 * * * /path/to/my-script.sh
      
    • 增加如下定时任务

      # 每周一0点更新ssl证书
      0 0 * * 1 /你的路径/acme.sh/shell/start_acme.sh
      
      # 每周一0点半检查今日正式是否更新成功,成功则更新文件
      30 0 * * 1 /你的路径/acme.sh/shell/check_ssl.sh
      

至此就完成了。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区