Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: DNS-01 challenge support #1137

Merged
merged 13 commits into from
Jul 29, 2024
Prev Previous commit
Next Next commit
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>
  • Loading branch information
buchdag and daweedm committed Jul 15, 2024
commit 48b40d401f7fd1420eb57e139fbf6daa9075a540
48 changes: 46 additions & 2 deletions app/letsencrypt_service
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]] || \
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
18 changes: 18 additions & 0 deletions app/letsencrypt_service_data.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -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 "") }}
Expand All @@ -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 }}"
Expand All @@ -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 }}"
Expand Down
4 changes: 3 additions & 1 deletion app/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
buchdag marked this conversation as resolved.
Show resolved Hide resolved
remove_all_standalone_configurations

exit 0
Expand Down