forked from K0p1-Git/cloudflare-ddns-updater
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloudflare-template.sh
149 lines (131 loc) · 6.03 KB
/
cloudflare-template.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
#!/bin/bash
## change to "bin/sh" when necessary
auth_email="" # The email used to login 'https://dash.cloudflare.com'
auth_method="token" # Set to "global" for Global API Key or "token" for Scoped API Token
auth_key="" # Your API Token or Global API Key
zone_identifier="" # Can be found in the "Overview" tab of your domain
record_name="" # Which record you want to be synced
ttl="3600" # Set the DNS TTL (seconds)
proxy="false" # Set the proxy to true or false
sitename="" # Title of site "Example Site"
slackchannel="" # Slack Channel #example
slackuri="" # URI for Slack WebHook "https://hooks.slack.com/services/xxxxx"
discorduri="" # URI for Discord WebHook "https://discordapp.com/api/webhooks/xxxxx"
###########################################
## Check if we have a public IP
###########################################
ipv4_regex='([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])'
ip=$(curl -s -4 https://cloudflare.com/cdn-cgi/trace | grep -E '^ip'); ret=$?
if [[ ! $ret == 0 ]]; then # In the case that cloudflare failed to return an ip.
# Attempt to get the ip from other websites.
ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com)
else
# Extract just the ip from the ip line from cloudflare.
ip=$(echo $ip | sed -E "s/^ip=($ipv4_regex)$/\1/")
fi
# Use regex to check for proper IPv4 format.
if [[ ! $ip =~ ^$ipv4_regex$ ]]; then
logger -s "DDNS Updater: Failed to find a valid IP."
exit 2
fi
###########################################
## Check if the IP has changed
###########################################
current_ip_file="$(dirname "$(readlink -f "$0")")/current-ip.txt"
# Check if the "current-ip.txt" file exists
if [[ -f "$current_ip_file" ]]; then
stored_ip=$(cat "$current_ip_file")
if [[ "$stored_ip" = "$ip" ]]; then
logger "DDNS Updater: IP has not changed. No update needed."
echo "IP has not changed. No update needed."
exit 0
fi
else
logger "DDNS Updater: 'current-ip.txt' not found. Creating the file."
fi
# Log the current and new IP
logger "DDNS Updater: Current IP: $stored_ip, New IP: $ip"
# Update the "current-ip.txt" file with the new IP.
echo "$ip" > "$current_ip_file"
echo "IP has changed. Proceeding with update."
###########################################
## Check and set the proper auth header
###########################################
if [[ "${auth_method}" == "global" ]]; then
auth_header="X-Auth-Key:"
else
auth_header="Authorization: Bearer"
fi
###########################################
## Seek for the A record
###########################################
logger "DDNS Updater: Check Initiated"
record=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?type=A&name=$record_name" \
-H "X-Auth-Email: $auth_email" \
-H "$auth_header $auth_key" \
-H "Content-Type: application/json")
###########################################
## Check if the domain has an A record
###########################################
if [[ $record == *"\"count\":0"* ]]; then
logger -s "DDNS Updater: Record does not exist, perhaps create one first? (${ip} for ${record_name})"
exit 1
fi
###########################################
## Get existing IP
###########################################
old_ip=$(echo "$record" | sed -E 's/.*"content":"(([0-9]{1,3}\.){3}[0-9]{1,3})".*/\1/')
# Compare if they're the same
if [[ $ip == $old_ip ]]; then
logger "DDNS Updater: IP ($ip) for ${record_name} has not changed."
exit 0
fi
###########################################
## Set the record identifier from result
###########################################
record_identifier=$(echo "$record" | sed -E 's/.*"id":"(\w+)".*/\1/')
###########################################
## Change the IP@Cloudflare using the API
###########################################
update=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record_identifier" \
-H "X-Auth-Email: $auth_email" \
-H "$auth_header $auth_key" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$record_name\",\"content\":\"$ip\",\"ttl\":\"$ttl\",\"proxied\":${proxy}}")
###########################################
## Report the status
###########################################
case "$update" in
*"\"success\":false"*)
echo -e "DDNS Updater: $ip $record_name DDNS failed for $record_identifier ($ip). DUMPING RESULTS:\n$update" | logger -s
if [[ $slackuri != "" ]]; then
curl -L -X POST $slackuri \
--data-raw '{
"channel": "'$slackchannel'",
"text" : "'"$sitename"' DDNS Update Failed: '$record_name': '$record_identifier' ('$ip')."
}'
fi
if [[ $discorduri != "" ]]; then
curl -i -H "Accept: application/json" -H "Content-Type:application/json" -X POST \
--data-raw '{
"content" : "'"$sitename"' DDNS Update Failed: '$record_name': '$record_identifier' ('$ip')."
}' $discorduri
fi
exit 1;;
*)
logger "DDNS Updater: $ip $record_name DDNS updated."
if [[ $slackuri != "" ]]; then
curl -L -X POST $slackuri \
--data-raw '{
"channel": "'$slackchannel'",
"text" : "'"$sitename"' Updated: '$record_name''"'"'s'""' new IP Address is '$ip'"
}'
fi
if [[ $discorduri != "" ]]; then
curl -i -H "Accept: application/json" -H "Content-Type:application/json" -X POST \
--data-raw '{
"content" : "'"$sitename"' Updated: '$record_name''"'"'s'""' new IP Address is '$ip'"
}' $discorduri
fi
exit 0;;
esac