I’ve been using Route53 and aws-cli to dynamically update DNS for my home server for a long time. This time I tried Cloudflare with dynamic DNS support.
First install cloudflare-cli:
$ npm install -g cloudflare-cli
Configure your bash script:
#!/bin/bash
# Setup envrionment
export PATH=/usr/local/bin:/usr/local/sbin:$PATH
# First install cloudflare-cli on OS X:
# npm install -g cloudflare-cli
# Add this script to cron, run it every 10 mins:
# */10 * * * * bash ~/Dropbox/Mac/Backups/Scripts/server-update-cloudflare.sh
# Cloudflare API key
TOKEN="your_token_here"
# Cloudflare account
ACCOUNT="[email protected]"
# Domain name
DOMAIN="example.com"
# The record you want to update e.g. hello, use the bare domain if you want to update root (@) record
RECORD="example.com"
# cfcli location
CFCLI=`which cfcli`
# Log file location
LOGFILE="/tmp/update-cloudflare.log"
# Get the external IP address
IP=`dig +short myip.opendns.com @resolver1.opendns.com`
IPOLD=`$CFCLI listrecords | pcregrep -o1 -e '.+?A.+?example\.com.+?([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).+'`
IPVPN=`ifconfig | grep -o ppp`
# Valid IP
function valid_ip() {
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
# Compare IPs
if ! valid_ip $IP; then
echo "[`date`] ERROR: Invalid IP '$IP'" >> "$LOGFILE"
exit 1
fi
# Check if the IP has changed
if [ "$IP" == "$IPOLD" ] || [[ $IPVPN ]]; then
echo "[`date`] SAME: $IP $IPVPN" >> "$LOGFILE"
exit 0
else
echo "[`date`] UPDATE: $IPOLD >>> $IP" >> "$LOGFILE"
$CFCLI -k $TOKEN -e $ACCOUNT -d $DOMAIN editrecord $RECORD $IP
fi
Run it with cron:
*/10 * * * * bash ~/Dropbox/Mac/Backups/Scripts/server-update-cloudflare.sh