From 890295bbfc0a1c29ebf171e1f15581f0ad1f6ade Mon Sep 17 00:00:00 2001 From: Carlos Date: Fri, 14 Nov 2025 07:10:17 +0000 Subject: [PATCH] Add DNS-01 challenge support with configuration files and scripts --- data/Dockerfiles/acme/Dockerfile | 1 + data/Dockerfiles/acme/load-dns-config.sh | 57 +++++++++++++++++++ .../acme/obtain-certificate-dns.sh | 15 +++++ data/conf/acme/dns-101.conf | 3 + docker-compose.yml | 1 + 5 files changed, 77 insertions(+) create mode 100755 data/Dockerfiles/acme/load-dns-config.sh create mode 100644 data/conf/acme/dns-101.conf diff --git a/data/Dockerfiles/acme/Dockerfile b/data/Dockerfiles/acme/Dockerfile index a8421bb0e..3dcfb874a 100644 --- a/data/Dockerfiles/acme/Dockerfile +++ b/data/Dockerfiles/acme/Dockerfile @@ -29,6 +29,7 @@ COPY acme.sh /srv/acme.sh COPY functions.sh /srv/functions.sh COPY obtain-certificate.sh /srv/obtain-certificate.sh COPY obtain-certificate-dns.sh /srv/obtain-certificate-dns.sh +COPY load-dns-config.sh /srv/load-dns-config.sh COPY reload-configurations.sh /srv/reload-configurations.sh COPY expand6.sh /srv/expand6.sh diff --git a/data/Dockerfiles/acme/load-dns-config.sh b/data/Dockerfiles/acme/load-dns-config.sh new file mode 100755 index 000000000..b48d36d3f --- /dev/null +++ b/data/Dockerfiles/acme/load-dns-config.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +SCRIPT_SOURCE="${BASH_SOURCE[0]:-${0}}" +if [[ "${SCRIPT_SOURCE}" == "${0}" ]]; then + __dns_loader_standalone=1 +else + __dns_loader_standalone=0 +fi + +CONFIG_PATH="${ACME_DNS_CONFIG_FILE:-/etc/acme/dns-101.conf}" + +if [[ ! -f "${CONFIG_PATH}" ]]; then + if [[ $__dns_loader_standalone -eq 1 ]]; then + exit 0 + else + return 0 + fi +fi + +source /srv/functions.sh + +log_f "Loading DNS-01 configuration from ${CONFIG_PATH}" + +LINE_NO=0 +while IFS= read -r line || [[ -n "${line}" ]]; do + LINE_NO=$((LINE_NO+1)) + line="${line%$'\r'}" + line_trimmed="$(printf '%s' "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + [[ -z "${line_trimmed}" ]] && continue + [[ "${line_trimmed:0:1}" == "#" ]] && continue + if [[ "${line_trimmed}" != *=* ]]; then + log_f "Skipping invalid DNS config line ${LINE_NO} (missing key=value)" + continue + fi + KEY="${line_trimmed%%=*}" + VALUE="${line_trimmed#*=}" + KEY="$(printf '%s' "${KEY}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + VALUE="$(printf '%s' "${VALUE}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" + if [[ -z "${KEY}" ]]; then + log_f "Skipping invalid DNS config line ${LINE_NO} (empty key)" + continue + fi + if [[ "${VALUE}" =~ ^\".*\"$ ]]; then + VALUE="${VALUE:1:-1}" + elif [[ "${VALUE}" =~ ^\'.*\'$ ]]; then + VALUE="${VALUE:1:-1}" + fi + export "${KEY}"="${VALUE}" + log_f "Exported DNS config key ${KEY}" + +done < "${CONFIG_PATH}" + +if [[ $__dns_loader_standalone -eq 1 ]]; then + exit 0 +else + return 0 +fi diff --git a/data/Dockerfiles/acme/obtain-certificate-dns.sh b/data/Dockerfiles/acme/obtain-certificate-dns.sh index 83fff6f7c..0be274d42 100644 --- a/data/Dockerfiles/acme/obtain-certificate-dns.sh +++ b/data/Dockerfiles/acme/obtain-certificate-dns.sh @@ -12,6 +12,14 @@ CERT_DOMAINS=(${DOMAINS[@]}) CERT_DOMAIN=${CERT_DOMAINS[0]} ACME_BASE=/var/lib/acme +# Load optional DNS provider secrets from /etc/acme/dns-101.conf +if [[ -f /srv/load-dns-config.sh ]]; then + source /srv/load-dns-config.sh + if declare -F log_f >/dev/null; then + log_f "ACME_DNS_CHALLENGE is enabled, DNS provider secrets loaded" + fi +fi + TYPE=${1} PREFIX="" # only support rsa certificates for now @@ -129,6 +137,13 @@ for domain in "${CERT_DOMAINS[@]}"; do done log_f "Using command ${ACME_CMD[*]}" +if [[ -n "${ACME_DNS_PROVIDER}" ]]; then + log_f "DNS provider: ${ACME_DNS_PROVIDER}" +fi +if compgen -A variable | grep -Eq "^DNS_|^ACME_"; then + LOG_KEYS=$(env | grep -E "^(DNS_|ACME_)" | cut -d= -f1 | tr '\n' ' ') + log_f "Available DNS/ACME env keys: ${LOG_KEYS}" redis_only +fi ACME_RESPONSE=$("${ACME_CMD[@]}" 2>&1 | tee /dev/fd/5; exit ${PIPESTATUS[0]}) SUCCESS="$?" ACME_RESPONSE_B64=$(echo "${ACME_RESPONSE}" | openssl enc -e -A -base64) diff --git a/data/conf/acme/dns-101.conf b/data/conf/acme/dns-101.conf new file mode 100644 index 000000000..095079ad0 --- /dev/null +++ b/data/conf/acme/dns-101.conf @@ -0,0 +1,3 @@ +# Add here your DNS-01 challenge configuration +# For more information, visit the acme.sh documentation: +# https://github.com/acmesh-official/acme.sh/wiki/dnsapi diff --git a/docker-compose.yml b/docker-compose.yml index 33fb20f1d..a3422ae2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -498,6 +498,7 @@ services: - ./data/assets/ssl:/var/lib/acme/:z - ./data/assets/ssl-example:/var/lib/ssl-example/:ro,Z - mysql-socket-vol-1:/var/run/mysqld/:z + - ./data/conf/acme:/etc/acme/:z restart: always networks: mailcow-network: