forked from jirutka/muacme
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnsupdate-challenge-hook.sh
executable file
·130 lines (103 loc) · 2.88 KB
/
nsupdate-challenge-hook.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/bin/sh
# This is a uacme hook script for the challenge type dns-01 that utilizes
# (k)nsupdate to add/delete _acme-challenge.<domain> TXT record for the
# requested domain name. See muacme.conf for configuration options.
#
# This file is part of muacme.
set -eu
readonly PROGNAME=$(basename "$0")
if ( set -o pipefail 2>/dev/null ); then
set -o pipefail
else
echo "$PROGNAME: ERROR: your shell does not support option pipefail!" >&2
exit 1
fi
die() {
echo "$*" >&2
exit 1
}
_dig() {
$DNS01_DIG ${DNS01_DEBUG:+-d} +nocomments +nomultiline "$@"
}
lookup_soa_for() {
_dig +noall +authority +answer "$1" SOA | grep 'IN\s*SOA\s'
}
lookup_txt_rdata() {
local fqdn=$1
local nameserver=$2
local out
out=$(_dig +short "$fqdn" TXT "@$nameserver")
out=${out%\"}
out=${out#\"}
printf %s "$out"
}
wait_for_txt_match() {
local fqdn=$1
local expected=$2
local nameserver=$3
local start_time=$(date +%s)
local actual
while [ $(date +%s) -lt $(($start_time + $DNS01_WAIT_MAX)) ]; do
actual=$(lookup_txt_rdata "$fqdn" "$nameserver")
[ "$actual" = "$expected" ] && return 0
sleep 1
done
return 1
}
update_record() {
local zone=$1; shift
local keyopt
case "$DNS01_DDNS_KEY" in
/*) keyopt="-k $DNS01_DDNS_KEY";; # file path
*) keyopt="-y $DNS01_DDNS_KEY";; # [<alg>:]<name>:<key>
esac
$DNS01_NSUPDATE ${DNS01_DEBUG:+-d} $keyopt <<-EOF
server $DNS01_DDNS_SERVER
zone $zone
update $*
send
EOF
}
if [ $# -ne 5 ]; then
echo "Usage: $PROGNAME (begin | done | failed) dns-01 <ident> <token> <auth>" >&2
exit 85 # copied from uacme.sh
fi
readonly METHOD=$1
readonly TYPE=$2
readonly IDENT=$3
readonly AUTH=$5
{
[ "$TYPE" = 'dns-01' ] \
|| die "unsupported type: $TYPE"
: ${MUACME_CONFIG:="/etc/muacme/muacme.conf"}
[ -r "$MUACME_CONFIG" ] \
|| die "config '$MUACME_CONFIG' does not exist or is not readable!"
. "$MUACME_CONFIG" \
|| die "failed to source config $MUACME_CONFIG!"
: ${DNS01_DDNS_KEY:=${dns01_ddns_key}}
: ${DNS01_DIG:=${dns01_dig:-"kdig +timeout=5 +retry=3"}}
: ${DNS01_NSUPDATE:=${dns01_nsupdate:-"knsupdate -t 5 -r 3 -v"}}
: ${DNS01_WAIT_MAX:=${dns01_wait_max:-10}}
: ${DNS01_DEBUG:=${dns01_debug:-}}
fqdn="_acme-challenge.$IDENT"
soa=$(lookup_soa_for "$fqdn") \
|| die "failed to resolve SOA for $fqdn"
nameserver=$(set -- $soa; echo $5)
zone=$(set -- $soa; echo $1)
: ${DNS01_DDNS_SERVER:=${dns01_ddns_server:-$nameserver}}
case "$METHOD" in
begin)
update_record "$zone" add "$fqdn." TXT "$AUTH" \
|| die "failed to add record $fqdn via $DNS01_DDNS_SERVER"
wait_for_txt_match "$fqdn" "$AUTH" "$nameserver" \
|| die "record update for $fqdn sent to $DNS01_DDNS_SERVER, but with no effect on $nameserver"
;;
done | failed)
update_record "$zone" delete "$fqdn." TXT \
|| die "failed to delete $fqdn record via $DNS01_DDNS_SERVER"
;;
*)
die "invalid method: $METHOD"
;;
esac
} 2>&1 | sed "s/^;; //;s/^/$PROGNAME: /" >&2