From b528ec5e79aa9d38c3a7dc2785718d3448540b5a Mon Sep 17 00:00:00 2001 From: Zhong Jianxin Date: Wed, 11 Apr 2018 12:05:59 +0800 Subject: [PATCH] acme: Support DNS mode Tested with dynu.com ddns. Install acme-dnsapi: # opkg install acme-dnsapi Example `/etc/config/acme`: config acme option state_dir '/etc/acme' option account_email email@example.org' option debug '0' config cert 'foo' option enabled '1' option use_staging '1' option keylength '2048' option update_uhttpd '0' option dns 'dns_dynu' list domains 'foo.dynu.com' list domains '*.foo.dynu.com' list credentials 'Dynu_ClientId="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"' list credentials 'Dynu_Secret="yyyyyyyyyyyyyyyyyyyyyyyyy"' Run: # /etc/init.d/acme start Signed-off-by: Zhong Jianxin --- net/acme/files/acme-cbi.lua | 14 ++++++++++++++ net/acme/files/run.sh | 15 +++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/net/acme/files/acme-cbi.lua b/net/acme/files/acme-cbi.lua index c20cba2034..264d335315 100644 --- a/net/acme/files/acme-cbi.lua +++ b/net/acme/files/acme-cbi.lua @@ -69,4 +69,18 @@ dom = cs:option(DynamicList, "domains", translate("Domain names"), "Note that all domain names must point at the router in the global DNS.")) dom.datatype = "list(string)" +dns = cs:option(Value, "dns", translate("DNS API"), + translate("To use DNS mode to issue certificates, set this to the name of a DNS API supported by acme.sh. " .. + "See https://github.com/Neilpang/acme.sh/tree/master/dnsapi for the list of available APIs. " .. + "In DNS mode, the domain name does not have to resolve to the router IP. " .. + "DNS mode is also the only mode that supports wildcard certificates. " .. + "Using this mode requires the acme-dnsapi package to be installed.")) +dns.rmempty = false + +cred = cs:option(DynamicList, "credentials", translate("DNS API credentials"), + translate("The credentials for the DNS API mode selected above. " .. + "See https://github.com/Neilpang/acme.sh/tree/master/dnsapi#how-to-use-dns-api for the format of credentials required by each API. " .. + "Add multiple entries here in KEY=VAL shell variable format to supply multiple credential variables.")) +cred.datatype = "list(string)" + return m diff --git a/net/acme/files/run.sh b/net/acme/files/run.sh index 50c5f9cd07..a3a89ab97a 100644 --- a/net/acme/files/run.sh +++ b/net/acme/files/run.sh @@ -143,6 +143,7 @@ issue_cert() local moved_staging=0 local failed_dir local webroot + local dns config_get_bool enabled "$section" enabled 0 config_get_bool use_staging "$section" use_staging @@ -150,6 +151,7 @@ issue_cert() config_get domains "$section" domains config_get keylength "$section" keylength config_get webroot "$section" webroot + config_get dns "$section" dns [ "$enabled" -eq "1" ] || return @@ -158,7 +160,7 @@ issue_cert() set -- $domains main_domain=$1 - [ -n "$webroot" ] || pre_checks "$main_domain" || return 1 + [ -n "$webroot" ] || [ -n "$dns" ] || pre_checks "$main_domain" || return 1 log "Running ACME for $main_domain" @@ -180,7 +182,10 @@ issue_cert() [ -n "$ACCOUNT_EMAIL" ] && acme_args="$acme_args --accountemail $ACCOUNT_EMAIL" [ "$use_staging" -eq "1" ] && acme_args="$acme_args --staging" - if [ -z "$webroot" ]; then + if [ -n "$dns" ]; then + log "Using dns mode" + acme_args="$acme_args --dns $dns" + elif [ -z "$webroot" ]; then log "Using standalone mode" acme_args="$acme_args --standalone" else @@ -192,6 +197,12 @@ issue_cert() acme_args="$acme_args --webroot $webroot" fi + handle_credentials() { + local credential="$1" + eval export $credential + } + config_list_foreach "$section" credentials handle_credentials + if ! $ACME --home "$STATE_DIR" --issue $acme_args; then failed_dir="$STATE_DIR/${main_domain}.failed-$(date +%s)" err "Issuing cert for $main_domain failed. Moving state to $failed_dir"