Merge pull request #6912 from cjlapao/feat-acme-dns
acme: add DNS challenges
This commit is contained in:
commit
b695936273
@ -57,6 +57,9 @@ adapt_new_options() {
|
|||||||
"DISABLE_NETFILTER_ISOLATION_RULE"
|
"DISABLE_NETFILTER_ISOLATION_RULE"
|
||||||
"HTTP_REDIRECT"
|
"HTTP_REDIRECT"
|
||||||
"ENABLE_IPV6"
|
"ENABLE_IPV6"
|
||||||
|
"ACME_DNS_CHALLENGE"
|
||||||
|
"ACME_DNS_PROVIDER"
|
||||||
|
"ACME_ACCOUNT_EMAIL"
|
||||||
)
|
)
|
||||||
|
|
||||||
sed -i --follow-symlinks '$a\' mailcow.conf
|
sed -i --follow-symlinks '$a\' mailcow.conf
|
||||||
@ -292,6 +295,20 @@ adapt_new_options() {
|
|||||||
echo '# This key is used to encrypt email addresses within SOGo URLs' >> mailcow.conf
|
echo '# This key is used to encrypt email addresses within SOGo URLs' >> mailcow.conf
|
||||||
echo "SOGO_URL_ENCRYPTION_KEY=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2>/dev/null | head -c 16)" >> mailcow.conf
|
echo "SOGO_URL_ENCRYPTION_KEY=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2>/dev/null | head -c 16)" >> mailcow.conf
|
||||||
;;
|
;;
|
||||||
|
ACME_DNS_CHALLENGE)
|
||||||
|
echo '# Enable DNS-01 challenge for ACME (acme-mailcow) - y/n' >> mailcow.conf
|
||||||
|
echo '# This requires you to set ACME_DNS_PROVIDER and ACME_ACCOUNT_EMAIL below' >> mailcow.conf
|
||||||
|
echo 'ACME_DNS_CHALLENGE=n' >> mailcow.conf
|
||||||
|
;;
|
||||||
|
ACME_DNS_PROVIDER)
|
||||||
|
echo '# DNS provider for DNS-01 challenge (e.g. dns_cf, dns_azure, dns_gd, etc.)' >> mailcow.conf
|
||||||
|
echo '# See the dns-101 provider documentation for more information.' >> mailcow.conf
|
||||||
|
echo 'ACME_DNS_PROVIDER=dns_xxx' >> mailcow.conf
|
||||||
|
;;
|
||||||
|
ACME_ACCOUNT_EMAIL)
|
||||||
|
echo '# Account email for ACME DNS-01 challenge registration' >> mailcow.conf
|
||||||
|
echo 'ACME_ACCOUNT_EMAIL=me@example.com' >> mailcow.conf
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "${option}=" >> mailcow.conf
|
echo "${option}=" >> mailcow.conf
|
||||||
;;
|
;;
|
||||||
|
|||||||
@ -14,11 +14,22 @@ RUN apk upgrade --no-cache \
|
|||||||
tini \
|
tini \
|
||||||
tzdata \
|
tzdata \
|
||||||
python3 \
|
python3 \
|
||||||
acme-tiny
|
acme-tiny \
|
||||||
|
git \
|
||||||
|
socat \
|
||||||
|
&& git clone --depth 1 https://github.com/acmesh-official/acme.sh.git /opt/acme.sh \
|
||||||
|
&& chmod +x /opt/acme.sh/acme.sh \
|
||||||
|
&& mkdir -p /var/lib/acme/acme-sh
|
||||||
|
|
||||||
|
ENV ACME_SH_BIN=/opt/acme.sh/acme.sh \
|
||||||
|
ACME_SH_HOME=/opt/acme.sh \
|
||||||
|
ACME_SH_CONFIG_HOME=/var/lib/acme/acme-sh
|
||||||
|
|
||||||
COPY acme.sh /srv/acme.sh
|
COPY acme.sh /srv/acme.sh
|
||||||
COPY functions.sh /srv/functions.sh
|
COPY functions.sh /srv/functions.sh
|
||||||
COPY obtain-certificate.sh /srv/obtain-certificate.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 reload-configurations.sh /srv/reload-configurations.sh
|
||||||
COPY expand6.sh /srv/expand6.sh
|
COPY expand6.sh /srv/expand6.sh
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,10 @@ if [[ "${ENABLE_SSL_SNI}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
|||||||
ENABLE_SSL_SNI=y
|
ENABLE_SSL_SNI=y
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${ACME_DNS_CHALLENGE}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
|
ACME_DNS_CHALLENGE=y
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ "${SKIP_LETS_ENCRYPT}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
if [[ "${SKIP_LETS_ENCRYPT}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
log_f "SKIP_LETS_ENCRYPT=y, skipping Let's Encrypt..."
|
log_f "SKIP_LETS_ENCRYPT=y, skipping Let's Encrypt..."
|
||||||
sleep 365d
|
sleep 365d
|
||||||
|
|||||||
@ -80,6 +80,11 @@ check_domain(){
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ ${ACME_DNS_CHALLENGE} == "y" ]]; then
|
||||||
|
log_f "ACME_DNS_CHALLENGE=y - skipping IP and HTTP validation for ${DOMAIN}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
# Check if CNAME without v6 enabled target
|
# Check if CNAME without v6 enabled target
|
||||||
if [[ ! -z ${AAAA_DOMAIN} ]] && [[ -z $(echo ${AAAA_DOMAIN} | grep "^\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}$") ]]; then
|
if [[ ! -z ${AAAA_DOMAIN} ]] && [[ -z $(echo ${AAAA_DOMAIN} | grep "^\([0-9a-fA-F]\{0,4\}:\)\{1,7\}[0-9a-fA-F]\{0,4\}$") ]]; then
|
||||||
AAAA_DOMAIN=
|
AAAA_DOMAIN=
|
||||||
|
|||||||
57
data/Dockerfiles/acme/load-dns-config.sh
Executable file
57
data/Dockerfiles/acme/load-dns-config.sh
Executable file
@ -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
|
||||||
177
data/Dockerfiles/acme/obtain-certificate-dns.sh
Normal file
177
data/Dockerfiles/acme/obtain-certificate-dns.sh
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Return values / exit codes
|
||||||
|
# 0 = cert created successfully
|
||||||
|
# 1 = cert renewed successfully
|
||||||
|
# 2 = cert not due for renewal
|
||||||
|
# * = errors
|
||||||
|
|
||||||
|
source /srv/functions.sh
|
||||||
|
|
||||||
|
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
|
||||||
|
if [[ "${TYPE}" != "rsa" ]]; then
|
||||||
|
log_f "Unknown certificate type '${TYPE}' requested"
|
||||||
|
exit 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "${ACME_DNS_PROVIDER}" ]]; then
|
||||||
|
log_f "ACME_DNS_PROVIDER is required when ACME_DNS_CHALLENGE is enabled"
|
||||||
|
exit 6
|
||||||
|
fi
|
||||||
|
|
||||||
|
DOMAINS_FILE=${ACME_BASE}/${CERT_DOMAIN}/domains
|
||||||
|
CERT=${ACME_BASE}/${CERT_DOMAIN}/${PREFIX}cert.pem
|
||||||
|
SHARED_KEY=${ACME_BASE}/acme/${PREFIX}key.pem # must already exist
|
||||||
|
KEY=${ACME_BASE}/${CERT_DOMAIN}/${PREFIX}key.pem
|
||||||
|
CSR=${ACME_BASE}/${CERT_DOMAIN}/${PREFIX}acme.csr
|
||||||
|
|
||||||
|
if [[ -z ${CERT_DOMAINS[*]} ]]; then
|
||||||
|
log_f "Missing CERT_DOMAINS to obtain a certificate"
|
||||||
|
exit 3
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${LE_STAGING}" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
|
||||||
|
if [[ ! -z "${DIRECTORY_URL}" ]]; then
|
||||||
|
log_f "Cannot use DIRECTORY_URL with LE_STAGING=y - ignoring DIRECTORY_URL"
|
||||||
|
fi
|
||||||
|
log_f "Using Let's Encrypt staging servers"
|
||||||
|
ACME_SH_SERVER_ARGS=("--staging")
|
||||||
|
elif [[ ! -z "${DIRECTORY_URL}" ]]; then
|
||||||
|
log_f "Using custom directory URL ${DIRECTORY_URL}"
|
||||||
|
ACME_SH_SERVER_ARGS=("--server" "${DIRECTORY_URL}")
|
||||||
|
else
|
||||||
|
log_f "Using Let's Encrypt production servers"
|
||||||
|
ACME_SH_SERVER_ARGS=("--server" "letsencrypt")
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f ${DOMAINS_FILE} && "$(cat ${DOMAINS_FILE})" == "${CERT_DOMAINS[*]}" ]]; then
|
||||||
|
if [[ ! -f ${CERT} || ! -f "${KEY}" || -f "${ACME_BASE}/force_renew" ]]; then
|
||||||
|
log_f "Certificate ${CERT} doesn't exist yet or forced renewal - start obtaining"
|
||||||
|
elif ! openssl x509 -checkend 2592000 -noout -in ${CERT} > /dev/null; then
|
||||||
|
log_f "Certificate ${CERT} is due for renewal (< 30 days) - start renewing"
|
||||||
|
else
|
||||||
|
log_f "Certificate ${CERT} validation done, neither changed nor due for renewal."
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_f "Certificate ${CERT} missing or changed domains '${CERT_DOMAINS[*]}' - start obtaining"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make backup
|
||||||
|
if [[ -f ${CERT} ]]; then
|
||||||
|
DATE=$(date +%Y-%m-%d_%H_%M_%S)
|
||||||
|
BACKUP_DIR=${ACME_BASE}/backups/${CERT_DOMAIN}/${PREFIX}${DATE}
|
||||||
|
log_f "Creating backups in ${BACKUP_DIR} ..."
|
||||||
|
mkdir -p ${BACKUP_DIR}/
|
||||||
|
[[ -f ${DOMAINS_FILE} ]] && cp ${DOMAINS_FILE} ${BACKUP_DIR}/
|
||||||
|
[[ -f ${CERT} ]] && cp ${CERT} ${BACKUP_DIR}/
|
||||||
|
[[ -f ${KEY} ]] && cp ${KEY} ${BACKUP_DIR}/
|
||||||
|
[[ -f ${CSR} ]] && cp ${CSR} ${BACKUP_DIR}/
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p ${ACME_BASE}/${CERT_DOMAIN}
|
||||||
|
if [[ ! -f ${KEY} ]]; then
|
||||||
|
log_f "Copying shared private key for this certificate..."
|
||||||
|
cp ${SHARED_KEY} ${KEY}
|
||||||
|
chmod 600 ${KEY}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generating CSR to keep layout parity with HTTP challenge flow
|
||||||
|
printf "[SAN]\nsubjectAltName=" > /tmp/_SAN
|
||||||
|
printf "DNS:%s," "${CERT_DOMAINS[@]}" >> /tmp/_SAN
|
||||||
|
sed -i '$s/,$//' /tmp/_SAN
|
||||||
|
openssl req -new -sha256 -key ${KEY} -subj "/" -reqexts SAN -config <(cat "$(openssl version -d | sed 's/.*\"\(.*\)\"/\1/g')/openssl.cnf" /tmp/_SAN) > ${CSR}
|
||||||
|
|
||||||
|
log_f "Checking resolver..."
|
||||||
|
until dig letsencrypt.org +time=3 +tries=1 @unbound > /dev/null; do
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
log_f "Resolver OK"
|
||||||
|
|
||||||
|
ACME_SH_BIN_PATH=${ACME_SH_BIN:-/opt/acme.sh/acme.sh}
|
||||||
|
ACME_SH_WORK_HOME=${ACME_SH_CONFIG_HOME:-/var/lib/acme/acme-sh}
|
||||||
|
mkdir -p ${ACME_SH_WORK_HOME}
|
||||||
|
|
||||||
|
if [[ ! -x ${ACME_SH_BIN_PATH} ]]; then
|
||||||
|
log_f "acme.sh binary not found at ${ACME_SH_BIN_PATH}"
|
||||||
|
exit 7
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f ${ACME_SH_WORK_HOME}/account.conf ]]; then
|
||||||
|
if [[ -z "${ACME_ACCOUNT_EMAIL}" ]]; then
|
||||||
|
log_f "ACME_ACCOUNT_EMAIL is required to register a new acme.sh account"
|
||||||
|
exit 8
|
||||||
|
fi
|
||||||
|
log_f "Registering acme.sh account for ${ACME_ACCOUNT_EMAIL}"
|
||||||
|
REGISTER_CMD=("${ACME_SH_BIN_PATH}" "--home" "${ACME_SH_WORK_HOME}" "--config-home" "${ACME_SH_WORK_HOME}" "--cert-home" "${ACME_SH_WORK_HOME}" "--register-account" "-m" "${ACME_ACCOUNT_EMAIL}")
|
||||||
|
REGISTER_CMD+=("${ACME_SH_SERVER_ARGS[@]}")
|
||||||
|
REGISTER_RESPONSE=$("${REGISTER_CMD[@]}" 2>&1)
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
log_f "Failed to register acme.sh account: ${REGISTER_RESPONSE}"
|
||||||
|
exit 9
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
TMP_CERT=$(mktemp /tmp/acme-cert.XXXXXX)
|
||||||
|
TMP_FULLCHAIN=$(mktemp /tmp/acme-fullchain.XXXXXX)
|
||||||
|
|
||||||
|
ACME_CMD=("${ACME_SH_BIN_PATH}" "--home" "${ACME_SH_WORK_HOME}" "--config-home" "${ACME_SH_WORK_HOME}" "--cert-home" "${ACME_SH_WORK_HOME}")
|
||||||
|
ACME_CMD+=("${ACME_SH_SERVER_ARGS[@]}")
|
||||||
|
ACME_CMD+=("--issue" "--dns" "${ACME_DNS_PROVIDER}" "--key-file" "${KEY}" "--cert-file" "${TMP_CERT}" "--fullchain-file" "${TMP_FULLCHAIN}" "--force")
|
||||||
|
for domain in "${CERT_DOMAINS[@]}"; do
|
||||||
|
ACME_CMD+=("-d" "${domain}")
|
||||||
|
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)
|
||||||
|
log_f "${ACME_RESPONSE_B64}" redis_only b64
|
||||||
|
|
||||||
|
case "$SUCCESS" in
|
||||||
|
0)
|
||||||
|
log_f "Deploying certificate ${CERT}..."
|
||||||
|
if verify_hash_match ${TMP_FULLCHAIN} ${KEY}; then
|
||||||
|
RETURN=0
|
||||||
|
if [[ -f ${CERT} ]]; then
|
||||||
|
RETURN=1
|
||||||
|
fi
|
||||||
|
mv -f ${TMP_FULLCHAIN} ${CERT}
|
||||||
|
rm -f ${TMP_CERT}
|
||||||
|
echo -n ${CERT_DOMAINS[*]} > ${DOMAINS_FILE}
|
||||||
|
log_f "Certificate successfully obtained via DNS challenge"
|
||||||
|
exit ${RETURN}
|
||||||
|
else
|
||||||
|
log_f "Certificate was requested, but key and certificate hashes do not match"
|
||||||
|
rm -f ${TMP_CERT} ${TMP_FULLCHAIN}
|
||||||
|
exit 4
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log_f "Failed to obtain certificate ${CERT} for domains '${CERT_DOMAINS[*]}' via DNS challenge"
|
||||||
|
redis-cli -h redis -a ${REDISPASS} --no-auth-warning SET ACME_FAIL_TIME "$(date +%s)"
|
||||||
|
rm -f ${TMP_CERT} ${TMP_FULLCHAIN}
|
||||||
|
exit 100${SUCCESS}
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@ -20,6 +20,10 @@ if [[ "${TYPE}" != "rsa" ]]; then
|
|||||||
log_f "Unknown certificate type '${TYPE}' requested"
|
log_f "Unknown certificate type '${TYPE}' requested"
|
||||||
exit 5
|
exit 5
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ "${ACME_DNS_CHALLENGE}" == "y" ]]; then
|
||||||
|
exec /srv/obtain-certificate-dns.sh "$@"
|
||||||
|
fi
|
||||||
DOMAINS_FILE=${ACME_BASE}/${CERT_DOMAIN}/domains
|
DOMAINS_FILE=${ACME_BASE}/${CERT_DOMAIN}/domains
|
||||||
CERT=${ACME_BASE}/${CERT_DOMAIN}/${PREFIX}cert.pem
|
CERT=${ACME_BASE}/${CERT_DOMAIN}/${PREFIX}cert.pem
|
||||||
SHARED_KEY=${ACME_BASE}/acme/${PREFIX}key.pem # must already exist
|
SHARED_KEY=${ACME_BASE}/acme/${PREFIX}key.pem # must already exist
|
||||||
|
|||||||
3
data/conf/acme/dns-101.conf
Normal file
3
data/conf/acme/dns-101.conf
Normal file
@ -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
|
||||||
@ -490,11 +490,15 @@ services:
|
|||||||
- REDISPASS=${REDISPASS}
|
- REDISPASS=${REDISPASS}
|
||||||
- SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
|
- SNAT_TO_SOURCE=${SNAT_TO_SOURCE:-n}
|
||||||
- SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
|
- SNAT6_TO_SOURCE=${SNAT6_TO_SOURCE:-n}
|
||||||
|
- ACME_DNS_CHALLENGE=${ACME_DNS_CHALLENGE:-n}
|
||||||
|
- ACME_DNS_PROVIDER=${ACME_DNS_PROVIDER:-dns_xxx}
|
||||||
|
- ACME_ACCOUNT_EMAIL=${ACME_ACCOUNT_EMAIL:-me@example.com}
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/web/.well-known/acme-challenge:/var/www/acme:z
|
- ./data/web/.well-known/acme-challenge:/var/www/acme:z
|
||||||
- ./data/assets/ssl:/var/lib/acme/:z
|
- ./data/assets/ssl:/var/lib/acme/:z
|
||||||
- ./data/assets/ssl-example:/var/lib/ssl-example/:ro,Z
|
- ./data/assets/ssl-example:/var/lib/ssl-example/:ro,Z
|
||||||
- mysql-socket-vol-1:/var/run/mysqld/:z
|
- mysql-socket-vol-1:/var/run/mysqld/:z
|
||||||
|
- ./data/conf/acme:/etc/acme/:z
|
||||||
restart: always
|
restart: always
|
||||||
networks:
|
networks:
|
||||||
mailcow-network:
|
mailcow-network:
|
||||||
|
|||||||
@ -293,6 +293,21 @@ ADDITIONAL_SERVER_NAMES=
|
|||||||
# Skip running ACME (acme-mailcow, Let's Encrypt certs) - y/n
|
# Skip running ACME (acme-mailcow, Let's Encrypt certs) - y/n
|
||||||
SKIP_LETS_ENCRYPT=n
|
SKIP_LETS_ENCRYPT=n
|
||||||
|
|
||||||
|
# Enable DNS-01 challenge for ACME (acme-mailcow) - y/n
|
||||||
|
# This requires you to set ACME_DNS_PROVIDER and ACME_ACCOUNT_EMAIL below
|
||||||
|
ACME_DNS_CHALLENGE=n
|
||||||
|
ACME_DNS_PROVIDER=dns_xxx
|
||||||
|
ACME_ACCOUNT_EMAIL=me@example.com
|
||||||
|
# You will need to pass provider-specific environment variables to the acme-mailcow container.
|
||||||
|
# See the dns-101 provider documentation for more information.
|
||||||
|
# for example for Azure DNS:
|
||||||
|
#AZUREDNS_SUBSCRIPTIONID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
#AZUREDNS_TENANTID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
#AZUREDNS_APPID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
#AZUREDNS_CLIENTSECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||||
|
#AZUREDNS_RESOURCEGROUP="your-resource-group"
|
||||||
|
#AZUREDNS_ZONE="your-zone-name"
|
||||||
|
|
||||||
# Create separate certificates for all domains - y/n
|
# Create separate certificates for all domains - y/n
|
||||||
# this will allow adding more than 100 domains, but some email clients will not be able to connect with alternative hostnames
|
# this will allow adding more than 100 domains, but some email clients will not be able to connect with alternative hostnames
|
||||||
# see https://doc.dovecot.org/admin_manual/ssl/sni_support
|
# see https://doc.dovecot.org/admin_manual/ssl/sni_support
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user