Skip to content

Instantly share code, notes, and snippets.

@mbierman
Last active April 7, 2020 01:46
Show Gist options
  • Select an option

  • Save mbierman/b77c2906cbbf37ed7d2173a474706053 to your computer and use it in GitHub Desktop.

Select an option

Save mbierman/b77c2906cbbf37ed7d2173a474706053 to your computer and use it in GitHub Desktop.
Updates IP for changeip.com's DDNS service
#!/bin/bash
###############################################################
## ChangeIP.com bash update script
###############################################################
## Written 3/18/09 by Tom Rinker, released to the Public Domain
## Re-write 09/15/2017 by Michael Bierman
## I replaced wget with curl so it can work on all macs.
###############################################################
## This is a simple bash script to preform a dDNS update with
## ChangeIP.com. It uses only bash and wget, and so should be
## compatible with virtually any UNIX/Linux based system with
## bash. It is intended to be executed as a cron job, and
## will only execute an update of dDNS records when the IP
## address changes. As ChangeIP.com dDNS records have a 5 min
## Time-To-Live, it is basically pointless and wasteful to
## execute it more often than every 5 minutes. This script
## supports logging all activity, in 3 available log levels,
## and supports simple management of log file size.
###############################################################
## To use this script:
## 1) set the variables in the script below
## 2) execute the script as a cron job
###############################################################
## WARNING: This script has two potential security holes.
## First, the username and password are stored plaintext in
## the script, so a system user who has read access to the
## script could read them. This risk can be mitigated with
## careful use of file permissions on the script.
## Second, the username and password will show briefly to other
## users of the system via ps, w, or top. This risk can be
## mitigated by moving the username and password to .wgetrc
## This level of security is acceptable for some installations
## including my own, but may be unacceptable for some users.
##
## You can now pass username and passowrd as parameters instead
## of storing them them in the file.
###############################################################
################ Script Variables #############################
BASE=$HOME/Downloads/changeip # Where to store all the related files
LASTIP=$(cat $BASE/IP 2> /dev/null) # IP address storage file
LOGPATH=$BASE/changeip.log # Log file
CIPUSER= # ChangeIP.com Username this can be passed via parm
CIPPASS= # ChangeIP.com Password this can be passed via parm
CIPSET=1 # ChangeIP.com recordset
LOGLEVEL=2 # 0=off, 1=medium, 2=high this can be passed via parm
LOGMAX=500 # Max log lines, 0=unlimited
UA="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"
###############################################################
# Make sure the required directories are in place...
if [ ! -d "$BASE" ]; then
mkdir $BASE
fi
function cInputs () {
# Sort out what the user asked for
for i in "$@" ; do
case $i in
-log=* | --log=*)
LOGLEVEL=$(echo $i | cut -f2 -d'=')
;;
-pass=* | --pass=*|-password=*)
CIPPASS=$(echo $i | cut -f2 -d'=')
;;
-user=* | --user=*)
CIPUSER=$(echo $i | cut -f2 -d'=')
;;
*)
echo -e "\n\n************************************************************\n \""$i"\" not a recognized input. This will be ignored.\n\n Valid options are:\n '-mode=silent (default is verbose)\n '-user=username'\n '-pass=password'\n************************************************************\n\n as in\n\n %$(basename $0) -user=fred -pass=hispassword -mode=silent\n\n\n"
;;
esac
done
}
function setup {
echo "--------------------------------" >> $LOGPATH
date >> $LOGPATH
}
# See if there are any commandline options passwed to the script.
cInputs "$@"
# get current IP from ip.changeip.com, and store in $CURRENTIP
CURRENTIP=$(curl --user-agent "$UA" --silent ip.changeip.com | grep IPADDR | cut -d= -s -f2 | cut -d- -s -f1)
# compare $LASTIP with $CURRENTPIP, and if different, execute update
if [ "$LASTIP" = "$CURRENTIP" ]
then # same IP, no update
if [ "$LOGLEVEL" -ge "1" ]
then # if verbose, log no change
setup
echo "No Change" | tee -a $LOGPATH
echo "IP: " $LASTIP >> $LOGPATH
fi
else # different IP
RESULT=$(curl --user-agent "$UA" --silent -u $CIPUSER:$CIPPASS https://nic.changeip.com/nic/update?cmd=update&set=$CIPSET)
if [ $LOGLEVEL -ne 0 ]
then # if logging, log update
setup
echo "Updating IP" | tee -a $LOGPATH
echo "NewIP: " $CURRENTIP >> $LOGPATH
fi
if [ $LOGLEVEL -ge 2 ]
then
echo "OldIP: " $LASTIP >> $LOGPATH
echo "Result: " $RESULT >> $LOGPATH
fi
echo $RESULT
if [ "$RESULT" != "200 Successful Update" ] # If there was an unsuccessful update (e.g. bad credentials), remove the last IP
then
rm $BASE/IP
fi
fi
echo $CURRENTIP | tee $BASE/IP # Store new IP
# if $LOGMAX not equal to 0 and we are logging, reduce log size to last $LOGMAX number of lines
if [ $LOGMAX -ne 0 -a $LOGLEVEL -ge 1 ]
then
echo "$(tail -n $LOGMAX $LOGPATH)" > $LOGPATH
fi
@mbierman
Copy link
Author

mbierman commented Sep 17, 2017

  • Rewrote this from wget to curl (because macOS doesn't have wget by default).
  • Added command line args so you don't have to store username/password if you don't want to.
  • Added command line arg for logging level.
  • Got rid writing some temp files that were unnecessary.
  • Improved handling of some corner cases.

#changeIP, #DDNS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment