# 使用 acme.sh 加上 Docker 獲得 ZeroSSL 免費憑證

# 簡介

通過 acme.sh 工具,加上 DNS API 與免費憑證簽發機構 ZeroSSL,包裝成 Docker 容器排程執行,實現自動更新的 SSL 憑證的服務。

# 教程

# 建立 Dockerfile

FROM ubuntu:20.04
RUN apt update && \
	apt-get install -y wget curl tar cron socat jq && \
	DEBIAN_FRONTEND=noninteractive TZ=Asia/Taipei apt-get -y install tzdata
RUN TZ=Asia/Taipei \
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \
&& dpkg-reconfigure -f noninteractive tzdata 
WORKDIR /app
COPY ./*.sh .
RUN chmod +x ./*.sh
RUN service cron start && \
echo "0 0 * * *" "/usr/bin/acme.sh --cron" >> mycron && \
crontab mycron && \
rm mycron
ENTRYPOINT ["/bin/bash","-c","/app/entry.sh"]

# 建立 entry.sh

#!/bin/bash
# install acme.sh
if  [[ ! -f /root/.acme.sh/acme.sh ]]
then
  curl -sSL https://get.acme.sh  | sh -s email=$ACME_EMAIL
fi
if  [[ ! -f /usr/bin/acme.sh ]]
then
  ln -s /root/.acme.sh/acme.sh /usr/bin/acme.sh
  echo [$(date)]  acme.sh has been installed
  acme.sh --set-default-ca --server zerossl
fi
service cron start
# install set notify
acme.sh --set-notify --notify-level 3
acme.sh --set-notify --notify-mode 0
acme.sh --set-notify --notify-hook telegram
# logging
if [[ ! -f /root/.acme.sh/acme.sh.log ]]; then
  touch /root/.acme.sh/acme.sh.log
fi
tail -f /root/.acme.sh/acme.sh.log

# 建立 env

  • 根據需要的 dns_api 服務來添加參數 參考
# 必要
ACME_EMAIL=email@example.com
# dns_api 參數
CF_Token=1111111111111111111111111111
CF_Account_ID=1111111111111111111111111111
DPI_Id=123
DPI_Key=1111111111111111111111111111
# 更新 Telegram Bot 通知
TELEGRAM_BOT_APITOKEN="1111111:aaaaaaaaaaaaaaaaaaaaaaa"
TELEGRAM_BOT_CHATID="1111111"

# 建立 init.sh

#!/bin/bash
ISSUE="/usr/bin/acme.sh --server zerossl --register-account -m ${ACME_EMAIL} --issue --force --log"
CERT_LOCATION=""
if [ $# -ne 0  ]; then
    CERT_LOCATION="${1%/}"
    INSTALL="/usr/bin/acme.sh --install-cert --key-file $CERT_LOCATION/cert.key --fullchain-file $CERT_LOCATION/cert.pem --log"
    shift
    ISSUE=$(echo "$ISSUE --dns $1")
    shift
    while [ $# != 0 ]
    do
        ISSUE=$(echo $ISSUE -d "$1")
        INSTALL=$(echo $INSTALL -d "$1")
        shift
    done
else
    echo "Usage: \"./init.sh cert_location dns_api domain1 domain2...\"";
    exit
fi
echo $ISSUE
echo $INSTALL

# 建立 docker-compose.yml

version: "3.9"
services:
  acme-sh:
    build: .
    image: acme-sh
    tty: true
    stdin_open: true
    container_name: acme-sh
    restart: always
    env_file:
     - .env
    volumes:
     - /volumes/acme/cert:/cert
     - /volumes/acme/home:/root/.acme.sh
    network_mode: host

# 啟動服務

docker-compose up -d --build

# 新增要安裝的憑證

用法: docker exec -it acme-sh ./init.sh 憑證存放位置 dns_api 域名1 域名2...
例如:使用 Cloudflare 託管的域名 example.com ,憑證存放在 example.com 目錄下

  1. 執行下面指令
docker exec -it acme-sh ./init.sh /cert/example.com dns_cf example.com
  1. 就會印出下面兩行指令
/usr/bin/acme.sh --server zerossl --register-account -m email@example.com --issue --force --log --dns dns_cf -d example.com
/usr/bin/acme.sh --install-cert --key-file /cert/example.com/cert.key --fullchain-file /cert/example.com/cert.pem --log -d example.com
  1. 將其前方加入 docker exec -it acme-sh ,改為下方指令並執行
docker exec -it acme-sh /usr/bin/acme.sh --server zerossl --register-account -m email@example.com --issue --force --log --dns dns_cf -d example.com
docker exec -it acme-sh /usr/bin/acme.sh --install-cert --key-file /cert/example.com/cert.key --fullchain-file /cert/example.com/cert.pem --log -d example.com
  1. 完成
更新於

請我喝咖啡~( ̄▽ ̄)~*