├── .gitignore ├── CHANGES.md ├── LICENSE ├── README.md ├── actions ├── clean-dns-record.sh ├── create-dns-record.sh ├── hook-after-sample.sh ├── hook-before-sample.sh └── load-config.sh ├── default.conf ├── initialize-env.sh ├── renew-all.sh └── sign-all.sh /.gitignore: -------------------------------------------------------------------------------- 1 | /domains/ 2 | *.log 3 | /.config.bash_rc 4 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | # Change logs 2 | 3 | ## v0.3.0 4 | 5 | - 支持 ACMEv2 的通配符证书申请。 6 | - 修复多域名证书域名列表错误。 7 | 8 | ## v0.2.3 9 | 10 | - 修复域名中带横线“-”时无法识别的 Bug。(Issue #2) 11 | 12 | ## v0.2.2 13 | 14 | - 配置文件添加 `certbot-root` 配置项以允许使用自定义的 Certbot 的命令名称。(Issue #1) 15 | 16 | ## v0.2.1 17 | 18 | - 修复 LE-AliDNS 脚本路径, 19 | 20 | ## v0.2.0 21 | 22 | - 完善使用教程 23 | - 配置文件添加 `no-auto-upgrade` 配置项以禁止 certbot 自动更新,**默认开启**。 24 | - 增加根据证书存储目录,检测域名是否已经签发证书。 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Angus.Fenying 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LE-AliDNS 2 | 3 | > DEPRECATED: Please use [acme.sh](https://acme.sh) instead. 4 | 5 | 通过阿里云 DNS 为 Let's Encrypt 签发证书提供验证的脚本工具。 6 | 7 | ## 功能 8 | 9 | - 支持签发多域名证书 10 | - 支持签发 ACMEv2 的通配符证书(配置开启 `acme-version=v2`) 11 | 12 | > 如果此前使用了 ACMEv1 签发的证书,那么建议在升级前将 /etc/letsencrypt 目录备份 13 | > 例如改个名。 14 | 15 | - 支持刷新证书 16 | 17 | ## 使用条件 18 | 19 | 1. 一台能运行 Certbot 的 Linux/Mac 设备 20 | 2. 安装有 Python 2.7.x (需自行手动安装) 21 | 3. 安装有 Certbot (需自行手动安装) 22 | 4. 要签发(续签)的所有证书,域名都是通过阿里云 DNS 管理的。 23 | 24 | ## 使用方式 25 | 26 | ### 安装 27 | 28 | 使用 Git Clone 仓库,例如: 29 | 30 | ```sh 31 | LE_ALIDNS_INSTALL_ROOT=/usr/local 32 | LE_ALIDNS_DIRNAME=le-alidns 33 | LE_ALIDNS_ROOT="${LE_ALIDNS_INSTALL_ROOT}/${LE_ALIDNS_DIRNAME}" 34 | cd $LE_ALIDNS_INSTALL_ROOT 35 | git clone https://github.com/fenying/le-alidns.git $LE_ALIDNS_DIRNAME 36 | cd $LE_ALIDNS_ROOT 37 | find '.' -name '*.sh' -exec chmod 0700 {} \; # 设置 Shell 脚本执行权限 38 | git config --local core.filemode false # 忽略该git仓库的文件权限属性改动 39 | ``` 40 | 41 | ### 更新版本 42 | 43 | ```sh 44 | LE_ALIDNS_INSTALL_ROOT=/usr/local 45 | LE_ALIDNS_DIRNAME=le-alidns 46 | LE_ALIDNS_ROOT="${LE_ALIDNS_INSTALL_ROOT}/${LE_ALIDNS_DIRNAME}" 47 | cd $LE_ALIDNS_ROOT 48 | git config --local core.filemode false 49 | git pull 50 | find '.' -name '*.sh' -exec chmod 0700 {} \; # 设置 Shell 脚本执行权限 51 | ``` 52 | 53 | ### 初始化 54 | 55 | > 依赖如下组件: (可以通过 initialize-env.sh 自动安装) 56 | > 57 | > - Pip 58 | > - Aliyun CLI 命令行工具 59 | > - Aliyun AliDNS Python SDK 60 | 61 | 1. 运行脚本 initialize-env.sh 安装 Python 2.7, PIP, Aliyun-CLI, 62 | Aliyun-SDK-AliDNS 等组件,并配置 Access-Key 和 Secret-Key。 63 | > Access-Key 需要 AliyunDNSFullAccess 权限。参考: 64 | [配置命令行工具和 SDK](https://help.aliyun.com/document_detail/43039.html?spm=a2c4g.11186623.6.550.ap6b0e)。 65 | 66 | 2. 复制 default.conf 配置文件为 /etc/le-alidns.conf,并根据需要配置。 67 | 68 | ### 配置 Pip 源 69 | 70 | 由于某些不可描述的原因,对于在国内使用 Pip 会出现无法下载或者下载极其缓慢的情况。 71 | 这个情况请修改 Pip 配置文件(一般是 `~/.pip/pip.conf`),使用清华大学的源: 72 | 73 | > 不要使用阿里云的源。 74 | 75 | ```ini 76 | [global] 77 | index-url=https://pypi.tuna.tsinghua.edu.cn/simple 78 | 79 | [install] 80 | trusted-host=pypi.tuna.tsinghua.edu.cn 81 | ``` 82 | 83 | > 参考:https://github.com/certbot/certbot/issues/2516 84 | 85 | ### 签发新证书 86 | 87 | 执行 `sudo /path/to/sign-all.sh` 即可为 domains 里配置的所有域名都签发证书。 88 | 89 | ### 续签证书 90 | 91 | 执行 `sudo /path/to/renew-all.sh` 可以续签所有已经签发的证书(包括手动签发的)。 92 | 93 | > 执行前使用 `export LEALIDNS_FORCE=1` 可以强制续签证书,但是一般情况请不要使用。 94 | 95 | ## 作者 96 | 97 | Angus.Fenying <[i.am.x.fenying@gmail.com](mailto:i.am.x.fenying@gmail.com)> 98 | 99 | ## License 100 | 101 | 本项目基于 [MIT 协议](./LICENSE)开源,可自由使用,如果使用过程中发生任何意外,本人 102 | 不承担任何责任。 103 | -------------------------------------------------------------------------------- /actions/clean-dns-record.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -f "${RECORD_ID_LIST_FILE}" ] 4 | then 5 | echo "No record-id-list file found." 6 | exit 7 | fi 8 | 9 | RECORD_ID_LIST=$(cat $RECORD_ID_LIST_FILE) 10 | 11 | if [ -z "$RECORD_ID_LIST" ] 12 | then 13 | echo "No records to be clean." 14 | exit 15 | fi 16 | 17 | for RecordId in $RECORD_ID_LIST 18 | do 19 | echo "Deleting DNS record of Id ${RecordId}" >> $CFG_LOG_FILE 20 | API_RESULT=$(aliyuncli alidns DeleteDomainRecord \ 21 | --RecordId ${RecordId} \ 22 | --output table \ 23 | ) 24 | 25 | echo "API Result: ${API_RESULT}" >> $CFG_LOG_FILE 26 | 27 | done 28 | 29 | rm -f $RECORD_ID_LIST_FILE 30 | -------------------------------------------------------------------------------- /actions/create-dns-record.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | declare WRITE_LOG_TARGET=$CFG_LOG_FILE 4 | 5 | write_log() { 6 | 7 | echo $1; 8 | echo $1 >> $WRITE_LOG_TARGET; 9 | } 10 | 11 | if [ -z "$CERTBOT_DOMAIN" ] || [ -z "$CERTBOT_VALIDATION" ] 12 | then 13 | echo "EMPTY DOMAIN OR VALIDATION" 14 | exit -1 15 | fi 16 | 17 | write_log "Certbot Domain: ${CERTBOT_DOMAIN}"; 18 | 19 | write_log "Certbot Validation: ${CERTBOT_VALIDATION}"; 20 | 21 | API_DomainName=$(echo $CERTBOT_DOMAIN | grep -P "\w[-\w]*\.\w[-\w]*$" -o) 22 | DomainRecord=$(echo $CERTBOT_DOMAIN | grep -P ".+(?=\.\w[-\w]*\.\w[-\w]*$)" -o) 23 | 24 | if [[ "$DomainRecord" == "" ]]; then 25 | API_RR=_acme-challenge 26 | else 27 | API_RR=_acme-challenge.$DomainRecord 28 | fi; 29 | 30 | write_log "Domain: ${API_DomainName}"; 31 | 32 | write_log "Domain Record: ${DomainRecord}"; 33 | 34 | write_log "Target Record: ${API_RR}"; 35 | 36 | API_RESULT=$(aliyuncli alidns AddDomainRecord \ 37 | --DomainName ${API_DomainName} \ 38 | --Type TXT \ 39 | --RR "${API_RR}" \ 40 | --Value "${CERTBOT_VALIDATION}" \ 41 | --output table \ 42 | ) 43 | 44 | write_log "API Result: ${API_RESULT}"; 45 | 46 | RecordId=$(echo $API_RESULT | grep -P "\|\s+(\d+)\s+\|" -o | grep -P "\d+" -o) 47 | 48 | write_log "Record Id: ${RecordId}"; 49 | 50 | echo $RecordId >> $RECORD_ID_LIST_FILE 51 | 52 | echo "" 53 | -------------------------------------------------------------------------------- /actions/hook-after-sample.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hook[After-Cert]: Action ${LEALIDNS_ACTION} completed." 4 | -------------------------------------------------------------------------------- /actions/hook-before-sample.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Hook[Before-Cert]: Action ${LEALIDNS_ACTION} started." 4 | -------------------------------------------------------------------------------- /actions/load-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Initialize the configuration 4 | 5 | if [ -z "$LEALIDNS_CONFIG" ] 6 | then 7 | export CONFIG_FILE=/etc/le-alidns.conf 8 | else 9 | export CONFIG_FILE=$LEALIDNS_CONFIG 10 | fi 11 | 12 | echo "- Using configuration file '${CONFIG_FILE}'." 13 | 14 | if [ ! -f $CONFIG_FILE ] 15 | then 16 | echo "Configuration file ${CONFIG_FILE} not found." 17 | exit -1 18 | fi 19 | 20 | export CFG_FIELDS="domains email log-file certbot-root certbot-cmd rsa-key-size" 21 | export CFG_FIELDS="${CFG_FIELDS} after-cert before-cert after-new-cert" 22 | export CFG_FIELDS="${CFG_FIELDS} no-auto-upgrade acme-version" 23 | export CFG_RSA_KEY_SIZE=2048 24 | export CFG_LOG_FILE=./le-alidns.log 25 | export CFG_CERTBOT_ROOT=/usr/local/certbot 26 | export CFG_CERTBOT_CMD=certbot-auto 27 | export CFG_NO_AUTO_UPGRADE=on 28 | export CFG_ACME_VERSION=v1 29 | 30 | for line in `cat ${CONFIG_FILE} | tr -d '[ \t]'` 31 | do 32 | if [[ "${line:0:1}" == "#" ]] # ignore comment lines 33 | then 34 | continue; 35 | fi; 36 | 37 | # remove inline comments 38 | line=$(echo $line | sed s/#.*//g); 39 | 40 | FIELD_NAME=$(echo $line | grep -P "^[-\w]+\=" -o | cut -d "=" -f 1) 41 | 42 | FIELD_VALUE=$(echo $line | cut -d "=" -f 2) 43 | 44 | if [[ $CFG_FIELDS =~ "$FIELD_NAME" ]] 45 | then 46 | if [ "$FIELD_VALUE" == "" ] 47 | then 48 | echo "Configuration field ${FIELD_NAME} can not be empty." 49 | exit -1; 50 | fi 51 | else 52 | echo "Unknown field ${FIELD_NAME}." 53 | fi; 54 | 55 | if [ "$FIELD_NAME" == "domains" ] 56 | then 57 | export CFG_DOMAINS="$FIELD_VALUE ${CFG_DOMAINS}" 58 | fi; 59 | 60 | if [ "$FIELD_NAME" == "domain" ] 61 | then 62 | export CFG_DOMAINS="${FIELD_VALUE} ${CFG_DOMAINS}" 63 | fi; 64 | 65 | if [ "$FIELD_NAME" == "email" ] 66 | then 67 | export CFG_EMAIL=$FIELD_VALUE 68 | fi; 69 | 70 | if [ "$FIELD_NAME" == "acme-version" ] 71 | then 72 | export CFG_ACME_VERSION=$FIELD_VALUE 73 | fi; 74 | 75 | if [ "$FIELD_NAME" == "certbot-root" ] 76 | then 77 | export CFG_CERTBOT_ROOT=$FIELD_VALUE 78 | fi; 79 | 80 | if [ "$FIELD_NAME" == "certbot-cmd" ] 81 | then 82 | export CFG_CERTBOT_CMD=$FIELD_VALUE 83 | fi; 84 | 85 | if [ "$FIELD_NAME" == "log-file" ] 86 | then 87 | export CFG_LOG_FILE=$FIELD_VALUE 88 | fi; 89 | 90 | if [ "$FIELD_NAME" == "rsa-key-size" ] 91 | then 92 | export CFG_RSA_KEY_SIZE=$FIELD_VALUE 93 | fi; 94 | 95 | if [ "$FIELD_NAME" == "after-new-cert" ] 96 | then 97 | export CFG_ON_NEW_CERT="--deploy-hook $FIELD_VALUE" 98 | fi; 99 | 100 | if [ "$FIELD_NAME" == "before-cert" ] 101 | then 102 | export CFG_ON_START=$FIELD_VALUE 103 | fi; 104 | 105 | if [ "$FIELD_NAME" == "after-cert" ] 106 | then 107 | export CFG_ON_END=$FIELD_VALUE 108 | fi; 109 | 110 | if [ "$FIELD_NAME" == "no-auto-upgrade" ] 111 | then 112 | export CFG_NO_AUTO_UPGRADE=$FIELD_VALUE 113 | fi; 114 | done 115 | -------------------------------------------------------------------------------- /default.conf: -------------------------------------------------------------------------------- 1 | # 使用 domain 或 domains 指定要签发证书的域名 2 | # 每行一个证书,单域名证书用 domain ,多域名证书用 domains (多域名用半角逗号隔开) 3 | 4 | domain = test1.sample.com # 签署单个域名的证书 5 | domain = test2.sample.com # 签署单个域名的证书 6 | domains = a.test1.sample.com, b.test2.sample.com # 签署多个域名的证书 7 | 8 | # 你的邮箱,用于 Let's Encrypt 登记 9 | email = admin@sample.com 10 | 11 | # 使用的 ACME 服务器版本,要使用通配符证书请设置为 v2 12 | # 由于 v1 和 v2 的服务器认证不兼容,因此之前使用 v1 申请的证书,改用 v2 时不能用 13 | # renew,请全部重新申请。(可以考虑直接删除 /etc/letsencrypt 目录) 14 | # 15 | # 默认值:v1 (保持兼容) 16 | # acme-version=v1 17 | 18 | # 关闭 Certbot 的自动更新功能。 19 | # 默认值:on 20 | # no-auto-upgrade = on 21 | 22 | # Certbot 的安装目录 23 | # 默认值:/usr/local/certbot 24 | # certbot-root = /usr/local/certbot 25 | 26 | # Certbot 的命令名称 27 | # 默认值:certbot-auto 28 | # certbot-cmd = certbot-auto 29 | 30 | # 工作日志存放路径 31 | # 默认值:./le-alidns.log 32 | # log-file = ./le-alidns.log 33 | 34 | # RSA 密钥长度,可以设置 2048 或 4096。 35 | # 默认值:2048 36 | # rsa-key-size = 2048 37 | 38 | # 当有新证书被签发时触发的钩子,必须是一个可执行的路径。 39 | # 可以使用这个钩子来自动执行脚本,例如重启 Nginx 加载新证书或者发邮件通知自己。 40 | # 默认值:无 41 | # after-new-cert = /path/to/hook-after-new-cert.sh 42 | 43 | # 当有签发/续签任务开始执行的时候触发的钩子,必须是一个可执行的路径。 44 | # 可以使用这个钩子来自动执行脚本,例如发邮件通知自己。 45 | # 默认值:无 46 | # before-cert = /usr/local/le-alidns/actions/hook-before-sample.sh 47 | 48 | # 当有签发/续签任务结束的时候触发的钩子,必须是一个可执行的路径。 49 | # 可以使用这个钩子来自动执行脚本,例如发邮件通知自己。 50 | # 默认值:无 51 | # after-cert = /usr/local/le-alidns/actions/hook-after-sample.sh 52 | -------------------------------------------------------------------------------- /initialize-env.sh: -------------------------------------------------------------------------------- 1 | type python >/dev/null 2>&1 || { 2 | echo >&2 "Please install Python 2.7 manually, aborting..."; 3 | exit 1; 4 | } 5 | 6 | type wget >/dev/null 2>&1 || { 7 | echo >&2 "Please install wget manually, aborting..."; 8 | exit 1; 9 | } 10 | 11 | type pip >/dev/null 2>&1 || { 12 | 13 | type wget >/dev/null 2>&1 || { 14 | echo >&2 "Please install wget manually, aborting..."; 15 | exit 1; 16 | } 17 | 18 | echo "Automatically installing pip."; 19 | 20 | wget "https://bootstrap.pypa.io/get-pip.py" -O "pip-install.py"; 21 | 22 | sudo python pip-install.py; 23 | 24 | echo "Installed pip."; 25 | } 26 | 27 | type aliyuncli >/dev/null 2>&1 || { 28 | 29 | echo "Automatically installing aliyun console toolkits."; 30 | 31 | sudo pip install aliyuncli; 32 | } 33 | 34 | ALI_CLI_PACKAGES=$(aliyuncli) 35 | 36 | CHECK_ALI_DNS_PY_PACKAGE=$(echo $ALI_CLI_PACKAGES | grep "alidns") 37 | 38 | if [[ "$CHECK_ALI_DNS_PY_PACKAGE" == "" ]] 39 | then 40 | sudo pip install aliyun-python-sdk-alidns 41 | fi 42 | -------------------------------------------------------------------------------- /renew-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Initialize the path to root of LE-AliDNS 4 | export LEALIDNS_ACTION=renew-all 5 | export LEALIDNS_ROOT=$(cd `dirname $0`; pwd)/ 6 | 7 | # Load configuration 8 | source ${LEALIDNS_ROOT}actions/load-config.sh 9 | 10 | declare WRITE_LOG_TARGET=$CFG_LOG_FILE 11 | 12 | write_log() { 13 | 14 | echo $1; 15 | echo $1 >> $WRITE_LOG_TARGET; 16 | } 17 | 18 | if [[ "$CFG_ON_START" != "" && -x $CFG_ON_START ]]; then 19 | write_log "Executing hook[before-cert] ${CFG_ON_START}..."; 20 | $CFG_ON_START 21 | fi 22 | 23 | if [[ "$CFG_NO_AUTO_UPGRADE" == "on" ]]; then 24 | ARG_NO_AUTO_UPGRADE="--no-bootstrap --no-self-upgrade" 25 | write_log "Turned off certbot aoto-updates."; 26 | fi 27 | 28 | if [[ "$CFG_ACME_VERSION" == "v2" ]]; then 29 | USE_CUSTOM_SERVER="--server https://acme-v02.api.letsencrypt.org/directory" 30 | CHALLENGE_METHOD=dns-01 31 | write_log "Using ACMEv2 protocol."; 32 | else 33 | CHALLENGE_METHOD=dns 34 | write_log "Using ACMEv1 protocol."; 35 | fi 36 | 37 | write_log "Renew task started at $(date '+%Y-%m-%d %H:%M:%S')"; 38 | 39 | # The path to list file of DNS record id 40 | export RECORD_ID_LIST_FILE=./dns-records 41 | 42 | rm -f $RECORD_ID_LIST_FILE 43 | 44 | mkdir ${LEALIDNS_ROOT}domains -p 45 | 46 | if [[ "$LEALIDNS_FORCE" == "1" ]]; then 47 | ARG_FORCE="--force-renew" 48 | fi 49 | 50 | if [[ "$LEALIDNS_DRY_RUN" != "1" ]] 51 | then 52 | CERTBOT_RESULT=$($CFG_CERTBOT_ROOT/$CFG_CERTBOT_CMD renew \ 53 | --manual \ 54 | --manual-public-ip-logging-ok \ 55 | $USE_CUSTOM_SERVER \ 56 | --preferred-challenges $CHALLENGE_METHOD \ 57 | $ARG_FORCE \ 58 | --agree-tos \ 59 | --email $CFG_EMAIL \ 60 | --rsa-key-size $CFG_RSA_KEY_SIZE \ 61 | $CFG_ON_NEW_CERT \ 62 | $ARG_NO_AUTO_UPGRADE \ 63 | --manual-auth-hook ${LEALIDNS_ROOT}actions/create-dns-record.sh) 64 | else 65 | echo $CFG_CERTBOT_ROOT/$CFG_CERTBOT_CMD renew \ 66 | --manual \ 67 | --manual-public-ip-logging-ok \ 68 | $USE_CUSTOM_SERVER \ 69 | --preferred-challenges $CHALLENGE_METHOD \ 70 | $ARG_FORCE \ 71 | --agree-tos \ 72 | --email $CFG_EMAIL \ 73 | --rsa-key-size $CFG_RSA_KEY_SIZE \ 74 | $CFG_ON_NEW_CERT \ 75 | $ARG_NO_AUTO_UPGRADE \ 76 | --manual-auth-hook ${LEALIDNS_ROOT}actions/create-dns-record.sh 77 | fi; 78 | 79 | write_log "Details: $CERTBOT_RESULT"; 80 | 81 | sh ${LEALIDNS_ROOT}actions/clean-dns-record.sh 82 | 83 | if [[ "$CFG_ON_END" != "" && -x $CFG_ON_END ]]; then 84 | write_log "Executing hook[after-cert] ${CFG_ON_END}..."; 85 | $CFG_ON_END 86 | fi; 87 | -------------------------------------------------------------------------------- /sign-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Initialize the path to root of LE-AliDNS 4 | export LEALIDNS_ACTION=sign-all 5 | export LEALIDNS_ROOT=$(cd `dirname $0`; pwd)/ 6 | 7 | # Load configuration 8 | source ${LEALIDNS_ROOT}actions/load-config.sh 9 | 10 | # The path to list file of DNS record id 11 | export RECORD_ID_LIST_FILE=./dns-records 12 | 13 | rm -f $RECORD_ID_LIST_FILE 14 | 15 | declare WRITE_LOG_TARGET=$CFG_LOG_FILE 16 | 17 | write_log() { 18 | 19 | echo $1; 20 | echo $1 >> $WRITE_LOG_TARGET; 21 | } 22 | 23 | if [[ "$CFG_ON_START" != "" && -x $CFG_ON_START ]]; then 24 | write_log "Executing hook[before-cert] ${CFG_ON_START}..."; 25 | $CFG_ON_START 26 | fi 27 | 28 | if [[ "$CFG_NO_AUTO_UPGRADE" == "on" ]]; then 29 | NO_AUTO_UPGRADE="--no-bootstrap --no-self-upgrade" 30 | write_log "Turned off certbot aoto-updates."; 31 | fi 32 | 33 | if [[ "$CFG_ACME_VERSION" == "v2" ]]; then 34 | USE_CUSTOM_SERVER="--server https://acme-v02.api.letsencrypt.org/directory" 35 | CHALLENGE_METHOD=dns-01 36 | write_log "Using ACMEv2 protocol."; 37 | else 38 | CHALLENGE_METHOD=dns 39 | write_log "Using ACMEv1 protocol."; 40 | fi 41 | 42 | write_log "Sign task started at $(date '+%Y-%m-%d %H:%M:%S')"; 43 | 44 | # Split domains by "," 45 | 46 | strsplitby() { 47 | local OLD_IFS="$IFS"; 48 | IFS="$1"; 49 | local STR_SPLIT_RESULT=("$2"); 50 | echo $STR_SPLIT_RESULT; 51 | IFS="$OLD_IFS"; 52 | } 53 | 54 | CFG_DOMAINS=("$CFG_DOMAINS") 55 | 56 | echo "Requesting certificates for domains..." 57 | echo "" 58 | 59 | CERTS_ROOT=/etc/letsencrypt/live/ 60 | 61 | for domain in ${CFG_DOMAINS[@]} 62 | do 63 | 64 | if [[ -f "${LEALIDNS_ROOT}domains/${domain}/lock" ]] 65 | then 66 | write_log "! Domain '${domain}' is alredy signed, ignored." 67 | write_log " Please use renew command to refresh it." 68 | write_log "" 69 | continue; 70 | fi; 71 | 72 | ARG_DOMAINS="" 73 | 74 | if [[ $domain =~ "," ]] 75 | then 76 | domains=$(strsplitby "," "$domain"); 77 | for item in ${domains[@]} 78 | do 79 | ARG_DOMAINS="$ARG_DOMAINS -d $domain" 80 | done 81 | 82 | if [[ "$ARG_DOMAINS" == "" ]]; then 83 | continue; 84 | fi 85 | 86 | write_log "Requesting certificate for domains '${domain}'..." 87 | else 88 | 89 | if [ -f ${CERTS_ROOT}${domain}/cert.pem ] 90 | then 91 | write_log "! Domain '${domain}' is alredy signed, ignored." 92 | write_log " Please use renew command to refresh it." 93 | write_log "" 94 | continue; 95 | fi; 96 | 97 | ARG_DOMAINS="-d $domain" 98 | 99 | write_log "Requesting certificate for domain '${domain}'..." 100 | fi 101 | 102 | if [[ "$LEALIDNS_DRY_RUN" != "1" ]] 103 | then 104 | CERTBOT_RESULT=$($CFG_CERTBOT_ROOT/$CFG_CERTBOT_CMD certonly \ 105 | --manual \ 106 | --manual-public-ip-logging-ok \ 107 | $USE_CUSTOM_SERVER \ 108 | --preferred-challenges $CHALLENGE_METHOD \ 109 | --agree-tos \ 110 | --email $CFG_EMAIL \ 111 | --rsa-key-size $CFG_RSA_KEY_SIZE \ 112 | $ARG_DOMAINS \ 113 | $CFG_ON_NEW_CERT \ 114 | $NO_AUTO_UPGRADE \ 115 | --manual-auth-hook ${LEALIDNS_ROOT}actions/create-dns-record.sh) 116 | else 117 | echo $CFG_CERTBOT_ROOT/$CFG_CERTBOT_CMD certonly \ 118 | --manual \ 119 | --manual-public-ip-logging-ok \ 120 | $USE_CUSTOM_SERVER \ 121 | --preferred-challenges $CHALLENGE_METHOD \ 122 | --agree-tos \ 123 | --email $CFG_EMAIL \ 124 | --rsa-key-size $CFG_RSA_KEY_SIZE \ 125 | $ARG_DOMAINS \ 126 | $CFG_ON_NEW_CERT \ 127 | $NO_AUTO_UPGRADE \ 128 | --manual-auth-hook ${LEALIDNS_ROOT}actions/create-dns-record.sh 129 | fi; 130 | 131 | if [[ ! $domain =~ "," ]]; then 132 | mkdir -p "${LEALIDNS_ROOT}domains/${domain}"; 133 | touch "${LEALIDNS_ROOT}domains/${domain}/lock"; 134 | fi 135 | 136 | write_log "Details: $CERTBOT_RESULT" 137 | done 138 | 139 | sh ${LEALIDNS_ROOT}actions/clean-dns-record.sh 140 | 141 | if [[ "$CFG_ON_END" != "" && -x $CFG_ON_END ]]; then 142 | write_log "Executing hook[after-cert] ${CFG_ON_END}..."; 143 | $CFG_ON_END 144 | fi; 145 | --------------------------------------------------------------------------------