]>
Commit | Line | Data |
---|---|---|
0a7c9364 | 1 | #!/usr/bin/env sh |
175c9dec | 2 | |
175c9dec | 3 | # |
4 | #CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" | |
5 | # | |
6 | #CF_Email="xxxx@sss.com" | |
7 | ||
55dea4ee | 8 | #CF_Token="xxxx" |
9 | #CF_Account_ID="xxxx" | |
719b6904 | 10 | #CF_Zone_ID="xxxx" |
55dea4ee | 11 | |
a4270efa | 12 | CF_Api="https://api.cloudflare.com/client/v4" |
175c9dec | 13 | |
638b9a05 | 14 | ######## Public functions ##################### |
15 | ||
16 | #Usage: add _acme-challenge.www.domain.com "XKrxpRBosdIKFzxW_CT3KLZNf6q0HG9i01zxXp5CPBs" | |
4c2a3841 | 17 | dns_cf_add() { |
175c9dec | 18 | fulldomain=$1 |
19 | txtvalue=$2 | |
4c2a3841 | 20 | |
55dea4ee | 21 | CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" |
22 | CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" | |
719b6904 | 23 | CF_Zone_ID="${CF_Zone_ID:-$(_readaccountconf_mutable CF_Zone_ID)}" |
eb0fc674 | 24 | CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" |
25 | CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" | |
4c2a3841 | 26 | |
55dea4ee | 27 | if [ "$CF_Token" ]; then |
2c2a43e1 | 28 | if [ "$CF_Zone_ID" ]; then |
29 | _savedomainconf CF_Token "$CF_Token" | |
30 | _savedomainconf CF_Account_ID "$CF_Account_ID" | |
31 | _savedomainconf CF_Zone_ID "$CF_Zone_ID" | |
32 | else | |
33 | _saveaccountconf_mutable CF_Token "$CF_Token" | |
34 | _saveaccountconf_mutable CF_Account_ID "$CF_Account_ID" | |
6ccf617d | 35 | _clearaccountconf_mutable CF_Zone_ID |
36 | _clearaccountconf CF_Zone_ID | |
2c2a43e1 | 37 | fi |
55dea4ee | 38 | else |
39 | if [ -z "$CF_Key" ] || [ -z "$CF_Email" ]; then | |
40 | CF_Key="" | |
41 | CF_Email="" | |
42 | _err "You didn't specify a Cloudflare api key and email yet." | |
43 | _err "You can get yours from here https://dash.cloudflare.com/profile." | |
44 | return 1 | |
45 | fi | |
ab45b778 | 46 | |
55dea4ee | 47 | if ! _contains "$CF_Email" "@"; then |
48 | _err "It seems that the CF_Email=$CF_Email is not a valid email address." | |
49 | _err "Please check and retry." | |
50 | return 1 | |
51 | fi | |
52 | #save the api key and email to the account conf file. | |
53 | _saveaccountconf_mutable CF_Key "$CF_Key" | |
54 | _saveaccountconf_mutable CF_Email "$CF_Email" | |
6ccf617d | 55 | |
56 | _clearaccountconf_mutable CF_Token | |
57 | _clearaccountconf_mutable CF_Account_ID | |
58 | _clearaccountconf_mutable CF_Zone_ID | |
59 | _clearaccountconf CF_Token | |
60 | _clearaccountconf CF_Account_ID | |
61 | _clearaccountconf CF_Zone_ID | |
62 | ||
55dea4ee | 63 | fi |
4c2a3841 | 64 | |
1b5bd0e0 | 65 | _debug "First detect the root zone" |
c7b16249 | 66 | if ! _get_root "$fulldomain"; then |
175c9dec | 67 | _err "invalid domain" |
68 | return 1 | |
69 | fi | |
e6d31b4e | 70 | _debug _domain_id "$_domain_id" |
71 | _debug _sub_domain "$_sub_domain" | |
72 | _debug _domain "$_domain" | |
4c2a3841 | 73 | |
1b5bd0e0 | 74 | _debug "Getting txt records" |
a4270efa | 75 | _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain" |
4c2a3841 | 76 | |
da957a3c | 77 | if ! echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then |
175c9dec | 78 | _err "Error" |
79 | return 1 | |
80 | fi | |
4c2a3841 | 81 | |
506c41cb | 82 | # For wildcard cert, the main root domain and the wildcard domain have the same txt subdomain name, so |
83 | # we can not use updating anymore. | |
84 | # count=$(printf "%s\n" "$response" | _egrep_o "\"count\":[^,]*" | cut -d : -f 2) | |
85 | # _debug count "$count" | |
86 | # if [ "$count" = "0" ]; then | |
72f54ca6 | 87 | _info "Adding record" |
88 | if _cf_rest POST "zones/$_domain_id/dns_records" "{\"type\":\"TXT\",\"name\":\"$fulldomain\",\"content\":\"$txtvalue\",\"ttl\":120}"; then | |
47ff768b | 89 | if _contains "$response" "$txtvalue"; then |
72f54ca6 | 90 | _info "Added, OK" |
4c2a3841 | 91 | return 0 |
7917aa2a | 92 | elif _contains "$response" "The record already exists"; then |
93 | _info "Already exists, OK" | |
94 | return 0 | |
72f54ca6 | 95 | else |
96 | _err "Add txt record error." | |
97 | return 1 | |
175c9dec | 98 | fi |
175c9dec | 99 | fi |
72f54ca6 | 100 | _err "Add txt record error." |
101 | return 1 | |
175c9dec | 102 | |
4c2a3841 | 103 | } |
175c9dec | 104 | |
21f201e3 | 105 | #fulldomain txtvalue |
5d6fd809 | 106 | dns_cf_rm() { |
107 | fulldomain=$1 | |
21f201e3 | 108 | txtvalue=$2 |
cd989510 | 109 | |
55dea4ee | 110 | CF_Token="${CF_Token:-$(_readaccountconf_mutable CF_Token)}" |
111 | CF_Account_ID="${CF_Account_ID:-$(_readaccountconf_mutable CF_Account_ID)}" | |
34cebe8c | 112 | CF_Zone_ID="${CF_Zone_ID:-$(_readaccountconf_mutable CF_Zone_ID)}" |
cd989510 | 113 | CF_Key="${CF_Key:-$(_readaccountconf_mutable CF_Key)}" |
114 | CF_Email="${CF_Email:-$(_readaccountconf_mutable CF_Email)}" | |
cd989510 | 115 | |
21f201e3 | 116 | _debug "First detect the root zone" |
117 | if ! _get_root "$fulldomain"; then | |
118 | _err "invalid domain" | |
119 | return 1 | |
120 | fi | |
121 | _debug _domain_id "$_domain_id" | |
122 | _debug _sub_domain "$_sub_domain" | |
123 | _debug _domain "$_domain" | |
124 | ||
125 | _debug "Getting txt records" | |
126 | _cf_rest GET "zones/${_domain_id}/dns_records?type=TXT&name=$fulldomain&content=$txtvalue" | |
127 | ||
1209b9b8 | 128 | if ! echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then |
52a16c91 | 129 | _err "Error: $response" |
21f201e3 | 130 | return 1 |
131 | fi | |
c0d0100c | 132 | |
ad9f488d | 133 | count=$(echo "$response" | _egrep_o "\"count\": *[^,]*" | cut -d : -f 2 | tr -d " ") |
21f201e3 | 134 | _debug count "$count" |
135 | if [ "$count" = "0" ]; then | |
136 | _info "Don't need to remove." | |
137 | else | |
ad9f488d | 138 | record_id=$(echo "$response" | _egrep_o "\"id\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") |
21f201e3 | 139 | _debug "record_id" "$record_id" |
140 | if [ -z "$record_id" ]; then | |
141 | _err "Can not get record id to remove." | |
142 | return 1 | |
143 | fi | |
144 | if ! _cf_rest DELETE "zones/$_domain_id/dns_records/$record_id"; then | |
145 | _err "Delete record error." | |
146 | return 1 | |
147 | fi | |
58c2c701 | 148 | echo "$response" | tr -d " " | grep \"success\":true >/dev/null |
21f201e3 | 149 | fi |
638b9a05 | 150 | |
5d6fd809 | 151 | } |
638b9a05 | 152 | |
329174b6 | 153 | #################### Private functions below ################################## |
175c9dec | 154 | #_acme-challenge.www.domain.com |
1b5bd0e0 | 155 | #returns |
175c9dec | 156 | # _sub_domain=_acme-challenge.www |
157 | # _domain=domain.com | |
158 | # _domain_id=sdjkglgdfewsdfg | |
159 | _get_root() { | |
160 | domain=$1 | |
c2d0d4d2 | 161 | i=1 |
175c9dec | 162 | p=1 |
719b6904 AW |
163 | |
164 | # Use Zone ID directly if provided | |
165 | if [ "$CF_Zone_ID" ]; then | |
166 | if ! _cf_rest GET "zones/$CF_Zone_ID"; then | |
167 | return 1 | |
168 | else | |
58c2c701 | 169 | if echo "$response" | tr -d " " | grep \"success\":true >/dev/null; then |
ad9f488d | 170 | _domain=$(echo "$response" | _egrep_o "\"name\": *\"[^\"]*\"" | cut -d : -f 2 | tr -d \" | _head_n 1 | tr -d " ") |
719b6904 | 171 | if [ "$_domain" ]; then |
d43227ed AW |
172 | _cutlength=$((${#domain} - ${#_domain} - 1)) |
173 | _sub_domain=$(printf "%s" "$domain" | cut -c "1-$_cutlength") | |
719b6904 AW |
174 | _domain_id=$CF_Zone_ID |
175 | return 0 | |
176 | else | |
177 | return 1 | |
178 | fi | |
179 | else | |
180 | return 1 | |
181 | fi | |
182 | fi | |
183 | fi | |
184 | ||
c7b16249 | 185 | while true; do |
186 | h=$(printf "%s" "$domain" | cut -d . -f $i-100) | |
15af89d5 | 187 | _debug h "$h" |
4c2a3841 | 188 | if [ -z "$h" ]; then |
175c9dec | 189 | #not valid |
4c2a3841 | 190 | return 1 |
175c9dec | 191 | fi |
4c2a3841 | 192 | |
55dea4ee | 193 | if [ "$CF_Account_ID" ]; then |
194 | if ! _cf_rest GET "zones?name=$h&account.id=$CF_Account_ID"; then | |
195 | return 1 | |
196 | fi | |
197 | else | |
198 | if ! _cf_rest GET "zones?name=$h"; then | |
199 | return 1 | |
200 | fi | |
7ba9a597 | 201 | fi |
202 | ||
11ecbd27 | 203 | if _contains "$response" "\"name\":\"$h\"" || _contains "$response" '"total_count":1'; then |
ad9f488d | 204 | _domain_id=$(echo "$response" | _egrep_o "\[.\"id\": *\"[^\"]*\"" | _head_n 1 | cut -d : -f 2 | tr -d \" | tr -d " ") |
4c2a3841 | 205 | if [ "$_domain_id" ]; then |
c7b16249 | 206 | _sub_domain=$(printf "%s" "$domain" | cut -d . -f 1-$p) |
175c9dec | 207 | _domain=$h |
208 | return 0 | |
209 | fi | |
210 | return 1 | |
211 | fi | |
212 | p=$i | |
c7b16249 | 213 | i=$(_math "$i" + 1) |
175c9dec | 214 | done |
215 | return 1 | |
216 | } | |
217 | ||
175c9dec | 218 | _cf_rest() { |
219 | m=$1 | |
220 | ep="$2" | |
a4270efa | 221 | data="$3" |
c7b16249 | 222 | _debug "$ep" |
4c2a3841 | 223 | |
55dea4ee | 224 | email_trimmed=$(echo "$CF_Email" | tr -d '"') |
225 | key_trimmed=$(echo "$CF_Key" | tr -d '"') | |
226 | token_trimmed=$(echo "$CF_Token" | tr -d '"') | |
6e917d15 | 227 | |
55dea4ee | 228 | export _H1="Content-Type: application/json" |
229 | if [ "$token_trimmed" ]; then | |
230 | export _H2="Authorization: Bearer $token_trimmed" | |
231 | else | |
232 | export _H2="X-Auth-Email: $email_trimmed" | |
233 | export _H3="X-Auth-Key: $key_trimmed" | |
234 | fi | |
4c2a3841 | 235 | |
21f201e3 | 236 | if [ "$m" != "GET" ]; then |
1b5bd0e0 | 237 | _debug data "$data" |
c7b16249 | 238 | response="$(_post "$data" "$CF_Api/$ep" "" "$m")" |
638b9a05 | 239 | else |
a4270efa | 240 | response="$(_get "$CF_Api/$ep")" |
175c9dec | 241 | fi |
4c2a3841 | 242 | |
243 | if [ "$?" != "0" ]; then | |
638b9a05 | 244 | _err "error $ep" |
175c9dec | 245 | return 1 |
246 | fi | |
a63b05a9 | 247 | _debug2 response "$response" |
175c9dec | 248 | return 0 |
249 | } |