]>
Commit | Line | Data |
---|---|---|
a00046f9 LB |
1 | #!/usr/bin/env sh |
2 | ||
58a89eda | 3 | # Supports IONOS DNS API v1.0.1 |
a00046f9 LB |
4 | # |
5 | # Usage: | |
6 | # Export IONOS_PREFIX and IONOS_SECRET before calling acme.sh: | |
7 | # | |
8 | # $ export IONOS_PREFIX="..." | |
9 | # $ export IONOS_SECRET="..." | |
10 | # | |
11 | # $ acme.sh --issue --dns dns_ionos ... | |
12 | ||
13 | IONOS_API="https://api.hosting.ionos.com/dns" | |
14 | IONOS_ROUTE_ZONES="/v1/zones" | |
15 | ||
22f7ac22 | 16 | IONOS_TXT_TTL=60 # minimum accepted by API |
a00046f9 LB |
17 | IONOS_TXT_PRIO=10 |
18 | ||
19 | dns_ionos_add() { | |
20 | fulldomain=$1 | |
21 | txtvalue=$2 | |
22 | ||
d21e6235 LB |
23 | if ! _ionos_init; then |
24 | return 1 | |
25 | fi | |
26 | ||
5eb1469d | 27 | _body="[{\"name\":\"$_sub_domain.$_domain\",\"type\":\"TXT\",\"content\":\"$txtvalue\",\"ttl\":$IONOS_TXT_TTL,\"prio\":$IONOS_TXT_PRIO,\"disabled\":false}]" |
d21e6235 | 28 | |
58a89eda | 29 | if _ionos_rest POST "$IONOS_ROUTE_ZONES/$_zone_id/records" "$_body" && [ "$_code" = "201" ]; then |
22f7ac22 | 30 | _info "TXT record has been created successfully." |
a00046f9 LB |
31 | return 0 |
32 | fi | |
33 | ||
34 | return 1 | |
35 | } | |
36 | ||
37 | dns_ionos_rm() { | |
38 | fulldomain=$1 | |
39 | txtvalue=$2 | |
40 | ||
d21e6235 LB |
41 | if ! _ionos_init; then |
42 | return 1 | |
43 | fi | |
a00046f9 | 44 | |
d21e6235 | 45 | if ! _ionos_get_record "$fulldomain" "$_zone_id" "$txtvalue"; then |
a00046f9 LB |
46 | _err "Could not find _acme-challenge TXT record." |
47 | return 1 | |
48 | fi | |
49 | ||
58a89eda | 50 | if _ionos_rest DELETE "$IONOS_ROUTE_ZONES/$_zone_id/records/$_record_id" && [ "$_code" = "200" ]; then |
22f7ac22 | 51 | _info "TXT record has been deleted successfully." |
a00046f9 LB |
52 | return 0 |
53 | fi | |
54 | ||
55 | return 1 | |
56 | } | |
57 | ||
58 | _ionos_init() { | |
59 | IONOS_PREFIX="${IONOS_PREFIX:-$(_readaccountconf_mutable IONOS_PREFIX)}" | |
60 | IONOS_SECRET="${IONOS_SECRET:-$(_readaccountconf_mutable IONOS_SECRET)}" | |
22f7ac22 | 61 | |
a00046f9 LB |
62 | if [ -z "$IONOS_PREFIX" ] || [ -z "$IONOS_SECRET" ]; then |
63 | _err "You didn't specify an IONOS api prefix and secret yet." | |
64 | _err "Read https://beta.developer.hosting.ionos.de/docs/getstarted to learn how to get a prefix and secret." | |
65 | _err "" | |
66 | _err "Then set them before calling acme.sh:" | |
67 | _err "\$ export IONOS_PREFIX=\"...\"" | |
68 | _err "\$ export IONOS_SECRET=\"...\"" | |
69 | _err "\$ acme.sh --issue -d ... --dns dns_ionos" | |
70 | return 1 | |
71 | fi | |
72 | ||
73 | _saveaccountconf_mutable IONOS_PREFIX "$IONOS_PREFIX" | |
74 | _saveaccountconf_mutable IONOS_SECRET "$IONOS_SECRET" | |
75 | ||
76 | if ! _get_root "$fulldomain"; then | |
77 | _err "Cannot find this domain in your IONOS account." | |
78 | return 1 | |
79 | fi | |
80 | } | |
81 | ||
82 | _get_root() { | |
83 | domain=$1 | |
f06aee21 | 84 | i=1 |
a00046f9 LB |
85 | p=1 |
86 | ||
87 | if _ionos_rest GET "$IONOS_ROUTE_ZONES"; then | |
58a89eda | 88 | _response="$(echo "$_response" | tr -d "\n")" |
a00046f9 LB |
89 | |
90 | while true; do | |
91 | h=$(printf "%s" "$domain" | cut -d . -f $i-100) | |
92 | if [ -z "$h" ]; then | |
93 | return 1 | |
94 | fi | |
95 | ||
58a89eda | 96 | _zone="$(echo "$_response" | _egrep_o "\"name\":\"$h\".*\}")" |
a00046f9 | 97 | if [ "$_zone" ]; then |
a9d88301 | 98 | _zone_id=$(printf "%s\n" "$_zone" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') |
a00046f9 LB |
99 | if [ "$_zone_id" ]; then |
100 | _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) | |
101 | _domain=$h | |
102 | ||
103 | return 0 | |
104 | fi | |
105 | ||
106 | return 1 | |
107 | fi | |
108 | ||
109 | p=$i | |
110 | i=$(_math "$i" + 1) | |
111 | done | |
112 | fi | |
113 | ||
114 | return 1 | |
115 | } | |
116 | ||
117 | _ionos_get_record() { | |
118 | fulldomain=$1 | |
119 | zone_id=$2 | |
d21e6235 | 120 | txtrecord=$3 |
a00046f9 LB |
121 | |
122 | if _ionos_rest GET "$IONOS_ROUTE_ZONES/$zone_id?recordName=$fulldomain&recordType=TXT"; then | |
58a89eda | 123 | _response="$(echo "$_response" | tr -d "\n")" |
a00046f9 | 124 | |
58a89eda | 125 | _record="$(echo "$_response" | _egrep_o "\"name\":\"$fulldomain\"[^\}]*\"type\":\"TXT\"[^\}]*\"content\":\"\\\\\"$txtrecord\\\\\"\".*\}")" |
a00046f9 | 126 | if [ "$_record" ]; then |
a9d88301 | 127 | _record_id=$(printf "%s\n" "$_record" | _egrep_o "\"id\":\"[a-fA-F0-9\-]*\"" | _head_n 1 | cut -d : -f 2 | tr -d '\"') |
22f7ac22 LB |
128 | |
129 | return 0 | |
a00046f9 LB |
130 | fi |
131 | fi | |
132 | ||
133 | return 1 | |
134 | } | |
135 | ||
136 | _ionos_rest() { | |
137 | method="$1" | |
138 | route="$2" | |
139 | data="$3" | |
140 | ||
141 | IONOS_API_KEY="$(printf "%s.%s" "$IONOS_PREFIX" "$IONOS_SECRET")" | |
142 | ||
143 | export _H1="X-API-Key: $IONOS_API_KEY" | |
144 | ||
58a89eda LB |
145 | # clear headers |
146 | : >"$HTTP_HEADER" | |
147 | ||
a00046f9 LB |
148 | if [ "$method" != "GET" ]; then |
149 | export _H2="Accept: application/json" | |
150 | export _H3="Content-Type: application/json" | |
151 | ||
58a89eda | 152 | _response="$(_post "$data" "$IONOS_API$route" "" "$method" "application/json")" |
a00046f9 LB |
153 | else |
154 | export _H2="Accept: */*" | |
7909273a | 155 | export _H3= |
58a89eda LB |
156 | |
157 | _response="$(_get "$IONOS_API$route")" | |
a00046f9 LB |
158 | fi |
159 | ||
58a89eda LB |
160 | _code="$(grep "^HTTP" "$HTTP_HEADER" | _tail_n 1 | cut -d " " -f 2 | tr -d "\\r\\n")" |
161 | ||
a00046f9 | 162 | if [ "$?" != "0" ]; then |
58a89eda | 163 | _err "Error $route: $_response" |
a00046f9 LB |
164 | return 1 |
165 | fi | |
58a89eda LB |
166 | |
167 | _debug2 "_response" "$_response" | |
168 | _debug2 "_code" "$_code" | |
a00046f9 LB |
169 | |
170 | return 0 | |
171 | } |