【真教程】利用acme.sh分发letsencrypt证书多端同步

如果你遇到多个服务器,想把网站同时部署到多台服务器,相同的域名,就需要同时部署多台ssl,但如果是买的ssl证书还好,免费证书的api调用有限制,而且也没必要如此浪费多个同时去部署ssl证书,我们就需要一个工具,cs模式全网负责申请证书,多客户端同步证书

图片[1]-【真教程】利用acme.sh分发letsencrypt证书多端同步 - 主机优选-主机优选

安装配置 acme.sh

这部分主要是按照 acme.sh 的官方文档来的,具体操作需要改变的地方我会说明。

安装系统环境

参考文档里面的大概需要这些:

# Debian/Ubuntu
apt-get install openssl cron socat curl -y
apt-get update ca-certificates
systemctl enable cron
systemctl start cron
# CentOS(顺便悼念一下凉凉的 CentOS 8)
yum -q -y install openssl crontabs socat curl
yum update ca-certificates
systemctl enable crond
systemctl start crond

创建工作目录

这里使用的是 /home/acme,如果这里你使用的是其他的目录的话,后面执行的命令里面也要记得一起更改:

mkdir -p /home/acme

安装 acme.sh 脚本

其中 /home/acme/acme.log 是脚本的日志文件:

curl https://get.acme.sh | sh
source ~/.bashrc
source ~/.bash_profile
acme.sh  --upgrade  --auto-upgrade --log  "/home/acme/acme.log"

定义临时变量

DOMAIN 的值修改成你要申请证书的域名,这里要申请的是通配符证书所以不需要填写子域名(除非你要申请子域名的通配符证书,但是我不知道 acme.sh 支不支持),关于后面几个变量,这里使用的 DNS 服务商是 CloudFlare,如果你使用的是其它服务商的话,可以根据文档修改,acme.sh 支持的服务商挺多的(100 多种,不愧是优秀的开源项目),在这里可以查看:DNS API plugins.

# example.com 修改成你的域名
export DOMAIN="example.com"
# 下面的内容根据所使用的 DNS 服务商更改
export CF_Key="b8e8fff91ff445a1a238fc080797910b"
export CF_Email="[email protected]"

设置 CA

具体支持看这里:Supported CA,默认是 ZeroSSL,这里换成 Let’s Encrypt 了(ZeroSSL 需要注册而且不支持签发 ECC 证书(大佬说已经支持了好诶),Let’s Encrypt 因为更换了根证书所以存在一些兼容性问题,各有各的好处吧)。

# 如果要使用 Let's Encrypt 执行以下命令
acme.sh --set-default-ca --server letsencrypt
# 如果要使用默认的 ZeroSSL 的话需要提前使用邮箱注册账户(使用 Let's Encrypt 的话无需执行)
acme.sh  --register-account  -m [email protected] --server zerossl

看见有人说 ZeroSSL 只能三个免费证书,需要说明一下,ZeroSSL 只是网页端申请免费证书限制是三个,而通过 ACME 通道申请的证书数量是没有限制的哈,参见:https://zerossl.com/documentation/acme/

申请与移动证书

签发证书

在之前的工作目录下面创建好对应域名的子目录,这个以后会用到,如果你的域名是 Emoji 或者中文之类(以及特殊字符)的话建议修改 ${DOMAIN} 为你要存放证书的目录(一般来说直接执行就行)。然后 dns_cf 改为你的 DNS 服务商,其它服务商参考上文提到的文档,稍等片刻就能申请成功。

mkdir -p /home/acme/${DOMAIN}</code><code>acme.sh --issue --dns dns_cf -d ${DOMAIN} -d *.${DOMAIN}

移动证书

官方文档说的是“安装证书”,但是我们是要部署一个证书分发服务,所以这里我把它叫做是移动证书,即把证书安装到之前所说的工作目录下,同时 reloadcmd 的作用是把当前时间戳给写入了 time.log 这个文件,这个很重要,之后在客户端上面同步证书的时候会用到:

acme.sh --install-cert -d ${DOMAIN} \--cert-file      /home/acme/${DOMAIN}/cert.pem  \--key-file       /home/acme/${DOMAIN}/key.pem  \--fullchain-file /home/acme/${DOMAIN}/fullchain.pem \--reloadcmd     "echo \$(date -d \"\$current\" +%s) > /home/acme/${DOMAIN}/time.log"

签发 ECC 证书(可选)

和上面两步基本一样,只是在签发证书的时候加了 --keylength ec-256 参数,具体看文档。注意不同的 CA 可能不支持签发 ECC 证书(目前 Let’s Encrypt 是支持的)。另外证书存放的目录加了 _ecc 后缀:

# 签发 ECC 证书
mkdir -p /home/acme/${DOMAIN}_eccacme.sh 
--issue --dns dns_cf -d ${DOMAIN} -d *.${DOMAIN} --keylength ec-256# 移动 ECC 证书acme.sh --install-cert --ecc -d ${DOMAIN} \--cert-file      /home/acme/${DOMAIN}_ecc/cert.pem  
\--key-file       /home/acme/${DOMAIN}_ecc/key.pem  
\--fullchain-file /home/acme/${DOMAIN}_ecc/fullchain.pem 
\--reloadcmd     "echo \$(date -d \"\$current\" +%s) > /home/acme/${DOMAIN}_ecc/time.log"

设置续期通知(可选)

acme.sh 脚本可以在证书续期成功或者失败的时候发送通知,这里就简单提一下(拿 Telegram 举例),具体看文档:Set notifications.

# Token returned by @BotFather during bot creation above.
export TELEGRAM_BOT_APITOKEN="6254903718:O75Sp8xv_-nXL5_YoPmFQqJ"
# Chat ID fetched from @getidsbotexport TELEGRAM_BOT_CHATID="6254903718"acme.sh --set-notify --notify-hook telegram
# Testacme.sh --cron

部署证书分发服务端

到这里证书已经申请到我们的服务器上的工作目录里面了(例如前文提到的 /home/acme 目录),接下来就要用到我们的工具 acmeDeliver 惹。

下载 acmeDeliver

去 https://github.com/julydate/acmeDeliver/releases 页面查看最新的 acmeDeliver 服务端,这里以 64 位 x86 的 Linux 为例,下载到了 /home/acme 目录:

curl -sLo /home/acme/acmeDeliver https://github.com/julydate/acmeDeliver/releases/download/v1.1/acmeDeliver_1.1_Linux_x86_64
chmod +x /home/acme/acmeDeliver

运行 acmeDeliver

首先尝试运行一下,其中 -p 指定服务端口,-d 指定了前文提到的工作目录,-k 指定的密码你得记住,因为待会儿在客户端会用到,如果没有报错就说明一切正常啦(废话)。

/home/acme/acmeDeliver -p 9929 -d "/home/acme/" -k 9bff385c71d051c3e81af2bb6950b3e4

然后就是放在后台运行:

nohup /home/acme/acmeDeliver -p 9929 -d "/home/acme/" -k 9bff385c71d051c3e81af2bb6950b3e4 > /home/acme/acmeDeliver.log 2>&1 &

如果你的服务器有防火墙,记得在服务商面板上和 iptables 里面放行对应的服务端口,具体去搜 CentOS/Debian/Ubuntu 如何放行端口,我就不废话啦。

更多关于程序的使用说明请去项目主页查看:https://github.com/julydate/acmeDeliver/tree/master#server

进程守护(可选)

服务端有时候会莫名其妙挂掉,所以还是建议弄一下进程守护。进程守护的方式有很多,这里只说两种。

第一种是用 crontab 脚本,保存以下脚本为 keepAcmeDeliver.sh,并放到 /home/acme/ 文件夹内,记得更改对应参数。

#!/bin/bash
check_pid(){
    PID=`ps -ef |grep -v grep | grep acmeDeliver |awk '{print $2}'`
}
crontab_monitor_acmedeliver(){
    check_pid
    if [[ -z ${PID} ]]; then
        echo -e "${Error} [$(date "+%Y-%m-%d %H:%M:%S %u %Z")] 检测到 acmeDeliver 服务端 未运行 , 开始启动..." | tee -a /tmp/acmeDeliverKeeper.log
        nohup /root/acmeDeliver -p 9929 -d "/home/acme/" -k 9bff385c71d051c3e81af2bb6950b3e4 > /tmp/acmeDeliver.log 2>&1 &
        sleep 1s
        check_pid
        if [[ -z ${PID} ]]; then
            echo -e "${Error} [$(date "+%Y-%m-%d %H:%M:%S %u %Z")] acmeDeliver 服务端 启动失败..." | tee -a /tmp/acmeDeliverKeeper.log && exit 1
        else
            echo -e "${Info} [$(date "+%Y-%m-%d %H:%M:%S %u %Z")] acmeDeliver 服务端 启动成功..." | tee -a /tmp/acmeDeliverKeeper.log && exit 1
        fi
    else
        echo -e "${Info} [$(date "+%Y-%m-%d %H:%M:%S %u %Z")] acmeDeliver 服务端 进程运行正常..." && exit 0
    fi
}
crontab_monitor_acmedeliver

然后执行 crontab -e 并在最后加上一行:

* * * * * /bin/bash /home/acme/keepAcmeDeliver.sh monitor

第二种是使用 systemd,执行以下命令,记得先更改对应参数。

cat > /etc/systemd/system/acmeDeliver.service << EOF
[Unit]
Description=acmeDeliver
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
Type=simple
User=root
Restart=on-failure
RestartSec=5s
DynamicUser=true
ExecStart=/home/acme/acmeDeliver -p 9929 -d "/home/acme/" -k 9bff385c71d051c3e81af2bb6950b3e4 > /home/acme/acmeDeliver.log 2>&1 &
[Install]
WantedBy=multi-user.target
EOF

然后用 root 权限执行以下命令:

# 设置开机启动
systemctl enable --now acmeDeliver
# 启动/重新启动/停止
systemctl start/restart/stop acmeDeliver

到这里,服务端的设置已经完毕。

使用证书分发客户端

接下来的操作就是在每个需要用到证书的服务器上安装客户端脚本了

安装系统环境

和服务端差不多:

# Debian/Ubuntu
apt-get install openssl cron curl -y
apt-get update ca-certificates
systemctl enable cron
systemctl start cron
# CentOS
yum -q -y install openssl crontabs curl
yum update ca-certificates
systemctl enable crond
systemctl start crond

下载客户端

从项目的 client 分支下载客户端脚本到 root 目录,当然你也可以下载到其它目录:

curl -sLo /root/acmeDeliverClient.sh https://raw.githubusercontent.com/julydate/acmeDeliver/client/client.sh
chmod +x /root/acmeDeliverClient.sh

使用客户端部署证书

更改客户端的工作目录,其实也就是你的证书需要存放的目录,默认是放在 tmp 目录的,将 \/home\/acme/ 改为你要存放的目录即可:

 sed -i 's|\/tmp\/acme|\/home\/acme/|g' /root/acmeDeliverClient.sh

测试运行客户端,其中 -p 指定的密码就是前面你部署服务端的时候设置的密码,233.233.233.233:9929 改为你服务器的 IP 和前面设置的服务端口,当然也可以绑定域名,然后example.com 改为你的域名,如果你之前是按我的教程申请的 ECC 证书,那么这里应该是有个后缀,比如 example.com_ecc.

/root/acmeDeliverClient.sh  -d "example.com" -p "9bff385c71d051c3e81af2bb6950b3e4" -s "http://233.233.233.233:9929" -c "0"

如果没有报错那就大功告成啦~,这个时候在服务器的 /home/acme 目录里面应该就能看见你的通配符证书了。

关于证书的使用参考 acme.sh 的文档,Apache 会用到 key.pemcert.pemfullchain.pem 这三个文件,NGINX 会用到 key.pemfullchain.pem 这两个文件

设置客户端定时同步

然后执行 crontab -e 在最后一行加上以下内容,其中 0 0 * * * 表示每天 0 点请求服务端看是否有文件更新,如果你之前服务端有在目录里生成一个正常的 time.log 文件,那么这里就不会有什么问题,客户端就只会在服务端证书文件更新的时候才从服务端同步每个文件:

0 0 * * * /root/acmeDeliverClient.sh  -d "example.com" -p "9bff385c71d051c3e81af2bb6950b3e4" -s "http://233.233.233.233:9929" -c "0" > /dev/null 2>&1 &

同时客户端脚本也支持证书部署之类的高级功能,更多关于客户端的使用说明请去项目主页查看:https://github.com/julydate/acmeDeliver/tree/master#client

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容