-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcfddns.sh
182 lines (141 loc) · 5.69 KB
/
cfddns.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
182
#!/bin/bash
#the aim of this script is to periodicall update the external IP address by calling the cloudflare api
ZONE_ID=
DNS_NAME=
X_Auth_Email=
X_Auth_Key=
API_TOKEN=
PRINT_LOGFILE=false #for debugging purposes: set to true to print the log file to console after script exits
############################
##### Logging #####
############################
# Logging (#chose between DEBUG, INFO or OFF)
LOG_LEVEL="INFO"
LOG_FILE="cfddns.log"
#create logfile in case it does not yet exist
if ! [ -f "cfddns.log" ]; then
touch cfddns.log
if [ $LOG_LEVEL == "DEBUG" ]; then
LOG_MESSAGE="New logfile created."
echo "$(date +"%Y-%m-%d %H:%M:%S") - $LOG_MESSAGE" >> "$LOG_FILE"
fi
fi
# Function to write to the log file
write_log() {
local MESSAGE_LEVEL=$1
local LOG_MESSAGE=$2
case $LOG_LEVEL in
"OFF")
#do nothing
;;
"INFO")
if [[ $MESSAGE_LEVEL = "INFO" ]]; then
echo "$(date +"%Y-%m-%d %H:%M:%S") - $LOG_MESSAGE" >> "$LOG_FILE"
fi
;;
"DEBUG")
echo "$(date +"%Y-%m-%d %H:%M:%S") - $LOG_MESSAGE" >> "$LOG_FILE"
;;
esac
}
# function to print logile to the console
print_log() {
if [ $PRINT_LOGFILE == true ]; then
local logfile="./cfddns.log"
cat "$logfile"
fi
}
############################
##### Functions #####
############################
# Function to validate IPv4 address using regex
validate_ipv4() {
local ipv4_pattern="^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
if [[ $1 =~ $ipv4_pattern ]]; then
echo "$1 is a valid IPv4 address"
else
echo "$1 is NOT a valid IPv4 address"
fi
}
# Function to test API token
validate_api_token() {
local api_token=$1
# Make the curl request and store the response in a variable
local response=$(curl -s "https://api.cloudflare.com/client/v4/user/tokens/verify" \
-H "Authorization: Bearer $api_token")
# Check if the response contains any errors
local errors_empty=$(echo "$json" | jq '.errors | length == 0')
if [ "$errors_empty" = false ]; then
echo "Error occurred while validating API token: $response"
exit 1 # Exit with a non-zero status to indicate an error
fi
# Echo the response
local message=$(echo "$response" | jq -r '.messages[0].message')
echo "$message"
}
# Function to update DNS records using the Cloudflare API
update_ip_address(){
local DNS_RECORD_ID=$1
local external_ip=$2
local UPDATE_URL="https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID"
# Make the API call
update_response=$(curl -s -X PUT \
-H "Content-Type: application/json" \
-H "X-Auth-Email: $X_Auth_Email" \
-H "X-Auth-Key: $X_Auth_Key" \
-d '{"content": "'"$external_ip"'",
"name": "'"$DNS_NAME"'",
"proxied": false,
"type": "A",
"ttl": 3600
}' \
$UPDATE_URL)
write_log "DEBUG" " $update_response"
# Check if the API call was successful (HTTP status code 200)
if [ $? -eq 0 ]; then
write_log "INFO" "The IP address was successfully updated!"
print_log
exit 0
else
write_log "DEBUG" "ERROR calling the API!"
write_log "DEBUG" "$update_response"
print_log
exit 1
fi
}
############################
#### Gather Information ####
############################
# Validate API token
if [ -z "$API_TOKEN" ]; then
validation_result=$(validate_api_token "$API_TOKEN")
write_log "DEBUG" "$validation_result"
fi
# Get current external IP
external_ip=$(curl -s https://ifconfig.co/ip)
write_log "DEBUG" "Retrieved current external IP address: $external_ip"
#validate IP format
ip_validation=$(validate_ipv4 "$external_ip")
write_log "DEBUG" "$ip_validation"
# Get dns_record and parse record id and ip address
RECORDS_URL="https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records"
RECORDS=$(curl -s -X GET \
-H "Content-Type: application/json" \
-H "X-Auth-Email: $X_Auth_Email" \
-H "X-Auth-Key: $X_Auth_Key" \
"$RECORDS_URL")
#extract the record id from the api response
record_id=$(echo "$RECORDS" | jq -r --arg DNS_NAME "$DNS_NAME" '.result[] | select(.name == $DNS_NAME) | .id')
#extract the ip address from the api response
record_ip=$(echo "$RECORDS" | jq -r --arg DNS_NAME "$DNS_NAME" '.result[] | select(.name == $DNS_NAME) | .content')
write_log "DEBUG" "Successfully retrieved record ID for $DNS_NAME: $record_id"
write_log "DEBUG" "Successfully retrieved record IP address for $DNS_NAME: $record_ip"
#compare record ip (from Cloudflare) with current external ip (from https://ifconfig.co/ip)
if [ "$external_ip" = "$record_ip" ]; then
write_log "INFO" "The IP address retrieved from Cloudflare is still up to date: No records were updated!"
print_log
exit 0
else
write_log "DEBUG" "The IP address retrieved from Cloudflare is different from the current external IP address"
update_ip_address $record_id $external_ip
fi