# 使用 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  | 
 |  | 
 |  | 
 | 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  | 
 |  | 
 |  | 
 | acme.sh --set-notify --notify-level 3  | 
 | acme.sh --set-notify --notify-mode 0  | 
 | acme.sh --set-notify --notify-hook telegram  | 
 |  | 
 |  | 
 | 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
 |  | 
 | ACME_EMAIL=email@example.com  | 
 |  | 
 | CF_Token=1111111111111111111111111111  | 
 | CF_Account_ID=1111111111111111111111111111  | 
 | DPI_Id=123  | 
 | DPI_Key=1111111111111111111111111111  | 
 |  | 
 | 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 目錄下
- 執行下面指令
 
 | docker exec -it acme-sh ./init.sh /cert/example.com dns_cf example.com  | 
- 就會印出下面兩行指令
 
 | /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  | 
- 將其前方加入 
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  | 
- 完成