项目简介
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 |
安装步骤
这里使用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自带的自动更新证书,而是自己写了脚本实现,如果想使用官方的自动更新证书请查看官方文档。
-
首先在刚才的目录下新建shell目录,存放相关脚本。
mkdir -p /你的路径/acme.sh/shell
-
进入shell目录
cd /你的路径/acme.sh/shell
-
新建一个名为
logfile.log
的空文件,用于存放后续脚本的日志touch logfile.log
-
新建一个名为
update_time.txt
的空文件,用于存放ssl成功更新日期touch update_time.txt
-
新建一个名为
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}
-
新建一个名为
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}
-
新建一个名为
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 ######################################"
-
新增cron定时任务
-
首先使用
crontab
命令来新增定时任务crontab -ecrontab -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
-
至此就完成了。
评论区