Skip to content

Instantly share code, notes, and snippets.

@paderijk
Last active December 22, 2022 09:38
Show Gist options
  • Save paderijk/b265552137dd14f7e37ecf4f48e17223 to your computer and use it in GitHub Desktop.
Save paderijk/b265552137dd14f7e37ecf4f48e17223 to your computer and use it in GitHub Desktop.
BASH script to monitor external IP, send Slack alert and update in Cloudflare A record
#!/bin/bash
#
# Get External IP, if changed send out external IP and inform via Slack
#
# Run this preferably via a cronjob
#
# Cloudflare snippets taken from:
# https://gist.github.com/Tras2/cba88201b17d765ec065ccbedfb16d9a
#
# Log file to keep history of IPs
EXT_IP_LOG="$HOME/.external-ip.log"
EXTERNAL_IP=$(/usr/bin/curl https://ifconfig.me/ip 2> /dev/null | grep -o '^[0-9].*')
CURRENT_DATE=$(date +"%Y-%m-%d %H:%M:%S")
PREV_IP=$(cat $EXT_IP_LOG | tail -n1 | awk -F+ '{ print $NF }')
PREV_IP_DATE=$(cat $EXT_IP_LOG | tail -n1 | awk -F+ '{ print $1 }')
# Slack info
WEBHOOK_URL="https://hooks.slack.com/services/XXXXXXXXXXXXXx/XXXXXXXXXXXXX"
# Cloufdlare data
# Cloudflare zone is the zone which holds the record
zone=example.com
# dnsrecord is the A record which will be updated
dnsrecord=host.example.com
## Cloudflare authentication details
## keep these private
cloudflare_auth_key=XXXXXXXXXXXXXXXXXXXXXXX
if [ -z "$EXTERNAL_IP" ];
then
# Failed to get external IP
sleep $[ ( $RANDOM % 600 ) + 60 ]s
if [ -z $1 ];
then
$(realpath "$0") --retry &
fi
exit
fi
if [ "$EXTERNAL_IP" == "$PREV_IP" ];
then
logger "IP not Changed - Current IP is $EXTERNAL_IP and previous was $PREV_IP"
echo "$CURRENT_DATE+$EXTERNAL_IP" >> $EXT_IP_LOG
exit
fi
logger "IP IS CHANGED - Current IP is $EXTERNAL_IP and previous was $PREV_IP on $PREV_IP_DATE"
# Updating Cloudflare
# get the zone id for the requested zone
zoneid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$zone&status=active" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')
# get the dns record id
dnsrecordid=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records?type=A&name=$dnsrecord" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" | jq -r '{"result"}[] | .[0] | .id')
# update the record
curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zoneid/dns_records/$dnsrecordid" \
-H "Authorization: Bearer $cloudflare_auth_key" \
-H "Content-Type: application/json" \
--data "{\"type\":\"A\",\"name\":\"$dnsrecord\",\"content\":\"$EXTERNAL_IP\",\"ttl\":1,\"proxied\":false}" > /dev/null 2> /dev/null
# Inform via Slack
/usr/bin/curl -X POST --data-urlencode "payload={\"channel\": \"#general\", \"username\": \"IP BOT\", \"mrkdwn\": true, \"text\": \"*Ziggo changed IP* - Current is "$EXTERNAL_IP" previous was "$PREV_IP" on "$PREV_IP_DATE" - Updated Cloudflare DNS ID "$dnsrecordid" ("$dnsrecord") in zone "$zoneid" ("$zone")\", \"icon_emoji\": \":earth_africa:\"}" $WEBHOOK_URL 2> /dev/null > /dev/null
echo "$CURRENT_DATE+$EXTERNAL_IP" >> $EXT_IP_LOG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment