-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathotc-certbot-hook.sh
executable file
·181 lines (158 loc) · 5.59 KB
/
otc-certbot-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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/usr/bin/env bash
# https://docs.otc.t-systems.com/dns/index.html
(
[[ ! $CERTBOT_AUTH_OUTPUT =~ "$CERTBOT_VALIDATION" ]] && CERTBOT_AUTH_OUTPUT=''
BASE="$(cd "$(dirname "$(readlink -e "${BASH_SOURCE[0]}")")" && pwd)" || \
{ echo "Couldn't determine the script's running directory." >&2; exit 1; }
OTCAUTH=$(pwd)/.otc-certbot-hook.auth
if [ ! -f "$OTCAUTH" ]; then
OTCAUTH=${BASE}/.otc-certbot-hook.auth
fi
if [ ! -f "$OTCAUTH" ]; then
>&2 echo "File $OTCAUTH not found."
exit 2
fi
source "$OTCAUTH"
if [ ! "$(type -P curl)" ]; then
>&2 echo "Install curl."
exit 3
fi
if [ ! "$(type -P jq)" ]; then
>&2 echo "Install jq."
exit 4
fi
if [[ -z "$OTC_REGION" || -z "$OTC_USER" || -z "$OTC_PASSWORD" || \
-z "$OTC_DOMAIN" || -z "$OTC_ROOT_ZONE" || -z "$OTC_IAM" || -z "$OTC_DNS" ]]; then
>&2 echo "Variable missing. Check your $OTCAUTH settings."
exit 5
fi
if [ -z "$CERTBOT_DOMAIN" ]; then
[ -n "$CERTBOT_AUTH_OUTPUT" ] \
&& >&2 echo "Running through certbot? Call via: certbot --manual-cleanup-hook" \
|| >&2 echo "Running through certbot? Call via: certbot --manual-auth-hook"
exit 6
fi
[ -n "$CERTBOT_AUTH_OUTPUT" ] \
&& echo "Deleting challenge ${CERTBOT_VALIDATION} ..." \
|| echo "Setting challenge ${CERTBOT_VALIDATION} ..."
# Strip off any leading wildcard and prepend "_acme-challenge."
domain="_acme-challenge.${CERTBOT_DOMAIN#\*.}"
if [ "${domain}" = "${OTC_ROOT_ZONE}" ]; then
subname=""
else
subname="${domain%.$OTC_ROOT_ZONE}"
fi
# TODO: make {OTC_ROOT_ZONE} an array {OTC_ROOT_ZONES}
echo $domain | grep -e ${OTC_ROOT_ZONE}$ >/dev/null
if [[ $? == 0 ]]; then
: # echo "${CERTBOT_DOMAIN} matches ${OTC_ROOT_ZONE}"
else
>&2 echo "${CERTBOT_DOMAIN} mismatches ${OTC_ROOT_ZONE}. Check your $OTCAUTH settings."
exit 7
fi
# Request OTC access token
ACCESS_TOKEN=$(
cat <<EOT | jq -c . | \
curl -is -X POST -H 'content-type: application/json' -d @- ${OTC_IAM}/auth/tokens | \
grep '^X-Subject-Token:' | cut -f2 -d: | tr -d ' '
{ "auth": {
"identity": {
"password": {
"user": {
"name": "${OTC_USER}",
"password": "${OTC_PASSWORD}",
"domain": { "name": "${OTC_DOMAIN}" } } },
"methods": [ "password" ] },
"scope": { "project": { "name": "${OTC_REGION}" } } } }
EOT
)
if [ -z "${ACCESS_TOKEN}" ]; then
>&2 echo "Unable to claim access to OTC. Check your $OTCAUTH settings."
exit 10
fi
### echo ${ACCESS_TOKEN}
# Release OTC access token
function release_token {
curl -Ss -X DELETE \
-H "X-Auth-Token: ${ACCESS_TOKEN}" \
-H "X-Subject-Token: ${ACCESS_TOKEN}" \
${OTC_IAM}/auth/tokens
}
# Querying {OTC_ROOT_ZONE}
ZONE_ID=$(curl -Ss -X GET -H "X-Auth-Token: ${ACCESS_TOKEN}" ${OTC_DNS}/zones | \
jq -r '.zones[] | select(.name == "'${OTC_ROOT_ZONE}.'").id')
if [ -z "${ZONE_ID}" ]; then
>&2 echo "Zone $OTC_ROOT_ZONE not found. Check your $OTCAUTH settings."
release_token
exit 11
fi
### echo ${ZONE_ID}
# Querying ACME validation token(s) in {OTC_ROOT_ZONE}
JSON=$(curl -Ss -X GET -H "X-Auth-Token: ${ACCESS_TOKEN}" \
${OTC_DNS}/zones/${ZONE_ID}/recordsets?type=TXT\&name=${domain}. | jq -c .)
### echo ${JSON}
RRSET_ID=
ACME_TOKEN=
COUNT=$(echo $JSON | jq -r .metadata.total_count)
if [[ "$COUNT" == "0" ]]; then
: # echo "No ACME validation token(s) found"
else
RRSET_ID=$(echo $JSON | jq -r .recordsets[0].id)
ACME_TOKEN=$(echo $JSON | jq -r .recordsets[0].records[])
fi
acme_tokens=()
for t in ${ACME_TOKEN}; do
echo $t | grep -e ^\"${CERTBOT_VALIDATION}\"\$ >/dev/null
if [[ $? == 0 ]]; then
: # echo "ACME validation token found. Strip."
else
acme_tokens+=($t)
fi
done
function json_request {
echo '{"name":"'${domain}'","type":"TXT","ttl":300,"records":'$(echo $(IFS=, ; echo "${acme_tokens[*]}") | jq -cRn '(input | split(",")) as $t | [$t] | flatten')'}'
}
if [ -n "$CERTBOT_AUTH_OUTPUT" ]; then
# Delete all occurrences of the current {CERTBOT_VALIDATION} from the rrset...
# ...by delete the rrset or republish the remaining challenges.
### echo "DELETE validation ${CERTBOT_VALIDATION}:"
if [[ ${#acme_tokens[@]} == 0 ]]; then
if [ -z "${RRSET_ID}" ]; then
>&2 echo "Ooops. There was no validation token(s) for ${domain}."
else
curl -Ss -X DELETE -H "X-Auth-Token: ${ACCESS_TOKEN}" \
${OTC_DNS}/zones/${ZONE_ID}/recordsets/${RRSET_ID} >/dev/null
fi
else
json_request | curl -Ss -X PUT -d @- \
-H 'content-type: application/json' -H "X-Auth-Token: ${ACCESS_TOKEN}" \
${OTC_DNS}/zones/${ZONE_ID}/recordsets >/dev/null
fi
else
# Add the current {CERTBOT_VALIDATION} to the rrset...
# ...by add the rrset if empty or update the existing rrset.
### echo "ADD validation ${CERTBOT_VALIDATION}:"
if [[ ${#acme_tokens[@]} == 0 ]]; then
if [ -n "${RRSET_ID}" ]; then
>&2 echo "Ooops. There was a validation token(s) for ${domain}."
else
acme_tokens+=(\"${CERTBOT_VALIDATION}\")
json_request | curl -Ss -X POST -d @- \
-H 'content-type: application/json' -H "X-Auth-Token: ${ACCESS_TOKEN}" \
${OTC_DNS}/zones/${ZONE_ID}/recordsets >/dev/null
fi
else
acme_tokens+=(\"${CERTBOT_VALIDATION}\")
json_request | curl -Ss -X PUT -d @- \
-H 'content-type: application/json' -H "X-Auth-Token: ${ACCESS_TOKEN}" \
${OTC_DNS}/zones/${ZONE_ID}/recordsets >/dev/null
fi
fi
release_token
sleep=${OTC_DNS_DELAY:-10}
[ -n "$CERTBOT_AUTH_OUTPUT" ] \
|| (echo "Waiting ${sleep}s for changes be published..."; date; sleep ${sleep})
[ -n "$CERTBOT_AUTH_OUTPUT" ] \
&& echo -e '\e[32mChallenge deleted. Returning to certbot.\e[0m' \
|| echo -e '\e[32mChallenge published. Returning to certbot.\e[0m'
)