Skip to content

Commit 48b40d4

Browse files
buchdagdaweedm
andcommitted
feat: support for DNS-01 challenge w/ acme.sh DNS API
Co-authored-by: Nicolas Duchon <[email protected]> Co-authored-by: David Michaluk <[email protected]>
1 parent 7178f07 commit 48b40d4

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

app/letsencrypt_service

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,41 @@ function update_cert {
151151

152152
# CLI parameters array used for --issue
153153
local -a params_issue_arr
154-
params_issue_arr+=(--webroot /usr/share/nginx/html)
154+
155+
# ACME challenge type
156+
local -n acme_challenge="ACME_${cid}_CHALLENGE"
157+
if [[ -z "${acme_challenge}" ]]; then
158+
acme_challenge="${ACME_CHALLENGE:-HTTP-01}"
159+
fi
160+
161+
if [[ "$acme_challenge" == "HTTP-01" ]]; then
162+
# HTTP-01 challenge
163+
params_issue_arr+=(--webroot /usr/share/nginx/html)
164+
elif [[ "$acme_challenge" == "DNS-01" ]]; then
165+
# DNS-01 challenge
166+
local -n acmesh_dns_config="ACMESH_${cid}_DNS_API_CONFIG"
167+
168+
local acmesh_dns_api="${acmesh_dns_config[DNS_API]}"
169+
if [[ -z "$acmesh_dns_api" ]]; then
170+
echo "Error: missing acme.sh DNS API for DNS challenge"
171+
return 1
172+
fi
173+
params_issue_arr+=(--dns "$acmesh_dns_api")
174+
175+
# Loop over defined variable for acme.sh DNS api config
176+
local -a dns_api_keys
177+
for key in "${!acmesh_dns_config[@]}"; do
178+
[[ "$key" == "DNS_API" ]] && continue
179+
dns_api_keys+=("$key")
180+
local value="${acmesh_dns_config[$key]}"
181+
declare -x "$key"="$value"
182+
done
183+
184+
echo "Info: DNS challenge using $acmesh_dns_api DNS API with the following keys: ${dns_api_keys[*]}"
185+
else
186+
echo "Error: unknown ACME challenge method: $acme_challenge"
187+
return 1
188+
fi
155189

156190
local -n cert_keysize="LETSENCRYPT_${cid}_KEYSIZE"
157191
if [[ -z "$cert_keysize" ]] || \
@@ -349,7 +383,7 @@ function update_cert {
349383
# Add all the domains to certificate
350384
params_issue_arr+=(--domain "$domain")
351385
# If enabled, add location configuration for the domain
352-
if parse_true "${ACME_HTTP_CHALLENGE_LOCATION:=false}"; then
386+
if [[ "$acme_challenge" == "HTTP-01" ]] && parse_true "${ACME_HTTP_CHALLENGE_LOCATION:=false}"; then
353387
add_location_configuration "$domain" || reload_nginx
354388
fi
355389
done
@@ -361,6 +395,16 @@ function update_cert {
361395

362396
local acmesh_return=$?
363397

398+
# DNS challenge: clean environment variables
399+
if [[ "$acme_challenge" == "DNS-01" ]]; then
400+
local -n acmesh_dns_config="ACMESH_${cid}_DNS_API_CONFIG"
401+
# Loop over defined variable for acme.sh DNS api config
402+
for key in "${!acmesh_dns_config[@]}"; do
403+
[[ "$key" == "DNS_API" ]] && continue
404+
unset "$key"
405+
done
406+
fi
407+
364408
# 0 = success, 2 = RENEW_SKIP
365409
if [[ $acmesh_return == 0 || $acmesh_return == 2 ]]; then
366410
for domain in "${hosts_array[@]}"; do

app/letsencrypt_service_data.tmpl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ LETSENCRYPT_CONTAINERS=(
2626
{{ $STAGING := trim (coalesce $container.Env.LETSENCRYPT_TEST "") }}
2727
{{ $EMAIL := trim (coalesce $container.Env.LETSENCRYPT_EMAIL "") }}
2828
{{ $CA_URI := trim (coalesce $container.Env.ACME_CA_URI "") }}
29+
{{ $ACME_CHALLENGE := trim (coalesce $container.Env.ACME_CHALLENGE "") }}
30+
{{ $ACMESH_DNS_API_CONFIG := fromYaml (coalesce $container.Env.ACMESH_DNS_API_CONFIG "") }}
2931
{{ $PREFERRED_CHAIN := trim (coalesce $container.Env.ACME_PREFERRED_CHAIN "") }}
3032
{{ $OCSP := trim (coalesce $container.Env.ACME_OCSP "") }}
3133
{{ $EAB_KID := trim (coalesce $container.Env.ACME_EAB_KID "") }}
@@ -47,6 +49,14 @@ LETSENCRYPT_CONTAINERS=(
4749
{{- "\n" }}LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_TEST="{{ $STAGING }}"
4850
{{- "\n" }}LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_EMAIL="{{ $EMAIL }}"
4951
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_CA_URI="{{ $CA_URI }}"
52+
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_CHALLENGE="{{ $ACME_CHALLENGE }}"
53+
{{- if $ACMESH_DNS_API_CONFIG }}
54+
{{- "\n" }}declare -A ACMESH_{{ $cid }}_{{ $hostHash }}_DNS_API_CONFIG=(
55+
{{- range $key, $value := $ACMESH_DNS_API_CONFIG }}
56+
{{- "\n\t" }}['{{ $key }}']='{{ $value }}'
57+
{{- end }}
58+
{{- "\n" }})
59+
{{- end }}
5060
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_PREFERRED_CHAIN="{{ $PREFERRED_CHAIN }}"
5161
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_OCSP="{{ $OCSP }}"
5262
{{- "\n" }}ACME_{{ $cid }}_{{ $hostHash }}_EAB_KID="{{ $EAB_KID }}"
@@ -69,6 +79,14 @@ LETSENCRYPT_CONTAINERS=(
6979
{{- "\n" }}LETSENCRYPT_{{ $cid }}_TEST="{{ $STAGING }}"
7080
{{- "\n" }}LETSENCRYPT_{{ $cid }}_EMAIL="{{ $EMAIL }}"
7181
{{- "\n" }}ACME_{{ $cid }}_CA_URI="{{ $CA_URI }}"
82+
{{- "\n" }}ACME_{{ $cid }}_CHALLENGE="{{ $ACME_CHALLENGE }}"
83+
{{- if $ACMESH_DNS_API_CONFIG }}
84+
{{- "\n" }}declare -A ACMESH_{{ $cid }}_DNS_API_CONFIG=(
85+
{{- range $key, $value := $ACMESH_DNS_API_CONFIG }}
86+
{{- "\n\t" }}['{{ $key }}']='{{ $value }}'
87+
{{- end }}
88+
{{- "\n" }})
89+
{{- end }}
7290
{{- "\n" }}ACME_{{ $cid }}_PREFERRED_CHAIN="{{ $PREFERRED_CHAIN }}"
7391
{{- "\n" }}ACME_{{ $cid }}_OCSP="{{ $OCSP }}"
7492
{{- "\n" }}ACME_{{ $cid }}_EAB_KID="{{ $EAB_KID }}"

app/start.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ term_handler() {
77

88
# shellcheck source=functions.sh
99
source /app/functions.sh
10-
remove_all_location_configurations
10+
if parse_true "${ACME_HTTP_CHALLENGE_LOCATION:=false}"; then
11+
remove_all_location_configurations
12+
fi
1113
remove_all_standalone_configurations
1214

1315
exit 0

0 commit comments

Comments
 (0)