1
0

feat: support for DNS-01 challenge w/ acme.sh DNS API

Co-authored-by: Nicolas Duchon <nicolas.duchon@gmail.com>
Co-authored-by: David Michaluk <d@michal.uk>
This commit is contained in:
Nicolas Duchon 2024-07-15 22:48:12 +02:00
parent 7178f0790b
commit 48b40d401f
3 changed files with 67 additions and 3 deletions

@ -151,7 +151,41 @@ function update_cert {
# CLI parameters array used for --issue
local -a params_issue_arr
params_issue_arr+=(--webroot /usr/share/nginx/html)
# ACME challenge type
local -n acme_challenge="ACME_${cid}_CHALLENGE"
if [[ -z "${acme_challenge}" ]]; then
acme_challenge="${ACME_CHALLENGE:-HTTP-01}"
fi
if [[ "$acme_challenge" == "HTTP-01" ]]; then
# HTTP-01 challenge
params_issue_arr+=(--webroot /usr/share/nginx/html)
elif [[ "$acme_challenge" == "DNS-01" ]]; then
# DNS-01 challenge
local -n acmesh_dns_config="ACMESH_${cid}_DNS_API_CONFIG"
local acmesh_dns_api="${acmesh_dns_config[DNS_API]}"
if [[ -z "$acmesh_dns_api" ]]; then
echo "Error: missing acme.sh DNS API for DNS challenge"
return 1
fi
params_issue_arr+=(--dns "$acmesh_dns_api")
# Loop over defined variable for acme.sh DNS api config
local -a dns_api_keys
for key in "${!acmesh_dns_config[@]}"; do
[[ "$key" == "DNS_API" ]] && continue
dns_api_keys+=("$key")
local value="${acmesh_dns_config[$key]}"
declare -x "$key"="$value"
done
echo "Info: DNS challenge using $acmesh_dns_api DNS API with the following keys: ${dns_api_keys[*]}"
else
echo "Error: unknown ACME challenge method: $acme_challenge"
return 1
fi
local -n cert_keysize="LETSENCRYPT_${cid}_KEYSIZE"
if [[ -z "$cert_keysize" ]] || \
@ -349,7 +383,7 @@ function update_cert {
# Add all the domains to certificate
params_issue_arr+=(--domain "$domain")
# If enabled, add location configuration for the domain
if parse_true "${ACME_HTTP_CHALLENGE_LOCATION:=false}"; then
if [[ "$acme_challenge" == "HTTP-01" ]] && parse_true "${ACME_HTTP_CHALLENGE_LOCATION:=false}"; then
add_location_configuration "$domain" || reload_nginx
fi
done
@ -361,6 +395,16 @@ function update_cert {
local acmesh_return=$?
# DNS challenge: clean environment variables
if [[ "$acme_challenge" == "DNS-01" ]]; then
local -n acmesh_dns_config="ACMESH_${cid}_DNS_API_CONFIG"
# Loop over defined variable for acme.sh DNS api config
for key in "${!acmesh_dns_config[@]}"; do
[[ "$key" == "DNS_API" ]] && continue
unset "$key"
done
fi
# 0 = success, 2 = RENEW_SKIP
if [[ $acmesh_return == 0 || $acmesh_return == 2 ]]; then
for domain in "${hosts_array[@]}"; do

@ -26,6 +26,8 @@ LETSENCRYPT_CONTAINERS=(
{{ $STAGING := trim (coalesce $container.Env.LETSENCRYPT_TEST "") }}
{{ $EMAIL := trim (coalesce $container.Env.LETSENCRYPT_EMAIL "") }}
{{ $CA_URI := trim (coalesce $container.Env.ACME_CA_URI "") }}
{{ $ACME_CHALLENGE := trim (coalesce $container.Env.ACME_CHALLENGE "") }}
{{ $ACMESH_DNS_API_CONFIG := fromYaml (coalesce $container.Env.ACMESH_DNS_API_CONFIG "") }}
{{ $PREFERRED_CHAIN := trim (coalesce $container.Env.ACME_PREFERRED_CHAIN "") }}
{{ $OCSP := trim (coalesce $container.Env.ACME_OCSP "") }}
{{ $EAB_KID := trim (coalesce $container.Env.ACME_EAB_KID "") }}
@ -47,6 +49,14 @@ LETSENCRYPT_CONTAINERS=(
{{- "\n" }}LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_TEST="{{ $STAGING }}"
{{- "\n" }}LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_EMAIL="{{ $EMAIL }}"
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_CA_URI="{{ $CA_URI }}"
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_CHALLENGE="{{ $ACME_CHALLENGE }}"
{{- if $ACMESH_DNS_API_CONFIG }}
{{- "\n" }}declare -A ACMESH_{{ $cid }}_{{ $hostHash }}_DNS_API_CONFIG=(
{{- range $key, $value := $ACMESH_DNS_API_CONFIG }}
{{- "\n\t" }}['{{ $key }}']='{{ $value }}'
{{- end }}
{{- "\n" }})
{{- end }}
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_PREFERRED_CHAIN="{{ $PREFERRED_CHAIN }}"
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_OCSP="{{ $OCSP }}"
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_EAB_KID="{{ $EAB_KID }}"
@ -69,6 +79,14 @@ LETSENCRYPT_CONTAINERS=(
{{- "\n" }}LETSENCRYPT_{{ $cid }}_TEST="{{ $STAGING }}"
{{- "\n" }}LETSENCRYPT_{{ $cid }}_EMAIL="{{ $EMAIL }}"
{{- "\n" }}ACME_{{ $cid }}_CA_URI="{{ $CA_URI }}"
{{- "\n" }}ACME_{{ $cid }}_CHALLENGE="{{ $ACME_CHALLENGE }}"
{{- if $ACMESH_DNS_API_CONFIG }}
{{- "\n" }}declare -A ACMESH_{{ $cid }}_DNS_API_CONFIG=(
{{- range $key, $value := $ACMESH_DNS_API_CONFIG }}
{{- "\n\t" }}['{{ $key }}']='{{ $value }}'
{{- end }}
{{- "\n" }})
{{- end }}
{{- "\n" }}ACME_{{ $cid }}_PREFERRED_CHAIN="{{ $PREFERRED_CHAIN }}"
{{- "\n" }}ACME_{{ $cid }}_OCSP="{{ $OCSP }}"
{{- "\n" }}ACME_{{ $cid }}_EAB_KID="{{ $EAB_KID }}"

@ -7,7 +7,9 @@ term_handler() {
# shellcheck source=functions.sh
source /app/functions.sh
remove_all_location_configurations
if parse_true "${ACME_HTTP_CHALLENGE_LOCATION:=false}"; then
remove_all_location_configurations
fi
remove_all_standalone_configurations
exit 0