Self use only!
#!/bin/bash
# define your own variables here
API_TOKEN="cloudflare-api-token" # replace with your own Cloudflare API Token
ZONE_ID="cloudflare-zone-id" # replace with your own Cloudflare Zone ID
DNS_NAME="yourdomain" # replace with your own domain name you want to update
die() {
echo $1
exit 1
}
date
# check if jq is installed
if ! command -v jq &> /dev/null; then
die "jq is not installed"
fi
# check if curl is installed
if ! command -v curl &> /dev/null; then
die "curl is not installed"
fi
# login to the modem
COOKIE=$(curl --request POST \
--url http://192.168.1.1/cgi-bin/luci \
--header 'content-type: application/x-www-form-urlencoded' \
--header 'user-agent: vscode-restclient' \
--data username=useradmin \
--data psd=123321 \
-i -s | grep -i 'Set-Cookie')
# parse cookie
COOKIE=${COOKIE#*Set-Cookie: }
# check if cookie is empty
[ -z "$COOKIE" ] && die "Failed to get cookie"
# get gateway info from modem
gwinfo=$(curl --request GET \
--url 'http://192.168.1.1/cgi-bin/luci/admin/settings/gwinfo?get=part' \
--header 'content-type: application/json' \
--header "cookie: $COOKIE" \
--header 'user-agent: vscode-restclient' \
--cookie "$COOKIE" -s
)
# check if gwinfo is empty
[ -z "$gwinfo" ] && die "Failed to get gwinfo"
# extract current ip
CURRENT_IP=$(echo $gwinfo | jq -r '.WANIP')
# check if current ip is empty
[ -z "$CURRENT_IP" ] && die "Failed to get IP"
echo " Current IP: $CURRENT_IP"
# query the DNS record ID
RECORD_INFO=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$DNS_NAME" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json")
# extract the DNS record ID and the existing IP
DNS_RECORD_ID=$(echo "$RECORD_INFO" | jq -r '.result[0].id')
EXISTING_IP=$(echo "$RECORD_INFO" | jq -r '.result[0].content')
# check if DNS record ID is empty
( [ -z "$DNS_RECORD_ID" ] || [ "$DNS_RECORD_ID" == "null" ] ) && die "Failed to get DNS record ID"
echo "Found DNS record ID: $DNS_RECORD_ID, existing IP: $EXISTING_IP"
# check if the current IP is the same as the existing IP
[ "$CURRENT_IP" == "$EXISTING_IP" ] && die "IP has not changed"
# update the DNS record
RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$DNS_RECORD_ID" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"type": "A",
"name": "'"$DNS_NAME"'",
"content": "'"$CURRENT_IP"'",
"ttl": 60,
"proxied": false
}')
# check if the DNS record was updated successfully
if echo "$RESPONSE" | grep -q '"success":true'; then
echo "DNS record updated successfully: $CURRENT_IP"
else
die "Failed to update DNS record"
fi
# add a cron job to run this script every 5 minutes
# chmod +x ddns.sh
# crontab -e
# */5 * * * * sh /home/username/ddns.sh > /home/username/ddns.log 2>&1 &