#!/bin/bash # updateip - very simple script for dyndns.org # copyright (C) 2004 jc@jcomeau.com # GPL licensed, see http://www.gnu.org/licenses/gpl.txt # if script disables cronjob, simply delete /tmp/updateip.disabled # and it will be restarted # but only AFTER fixing whatever the problem is! # read www.dyndns.org/developers/ stuff to understand everything # if more than one host, separate with commas: "www.bim.bo,www.dis.dat" # make sure to make a root cronjob like this: # * * * * * run-parts /etc/cron.constantly USERNAME=$1 PASSWORD=$2 FQDN=$3 TESTING=$4 URL=http://members.dyndns.org/nic/update CACHE=/tmp/updateip/last_known.txt TMPCACHE=/tmp/updateip/current.txt CRONJOB=/etc/cron.constantly/updateip # add any more dyndns domains you need to the following list DYNDNS_DOMAINS="dyndns.org kicks-ass.net dynalias.org isa-geek.com" DISABLED=/tmp/updateip.disabled MINUTE=60 # seconds DAY=86400 # seconds FORCE= # only force after 30 days (after 35, zone deleted by dyndns.org) #TESTING="true" # comment this out, it can always be enabled from commandline function loaduserinfo { [ "$USERNAME" ] && return USERNAME=`awk '$2 ~ "members.dyndns.org" {print $4}' $HOME/.netrc` PASSWORD=`awk '$2 ~ "members.dyndns.org" {print $6}' $HOME/.netrc` } function die { [ "$@" ] && echo "$@" >&2 exit 1 } [ -w / ] || die "Must be root" mkdir -p $(dirname $CACHE) || die "Cannot create $(dirname $CACHE)" mkdir -p $(dirname $CRONJOB) || die "Cannot create $(dirname $CRONJOB)" loaduserinfo [ "$TESTING" ] && echo USERNAME=$USERNAME function loadfqdn { [ "$FQDN" ] && return for domain in $DYNDNS_DOMAINS; do fqdn=`awk "\\$2 ~ \"$domain$\" {print \\$2}" $HOME/.netrc` for host in $fqdn; do if [ "$host" != "members.dyndns.org" ]; then if [ "$FQDN" ]; then FQDN="$FQDN,$host" else FQDN=$host fi fi done done } loadfqdn if [ "$TESTING" ]; then echo FQDN=$FQDN; fi function log () { logger $@ } function error () { echo $@ >&2 } function logerror () { log -ist updateip $@ } if [ -z "$USERNAME" -o -z "$PASSWORD" -o -z "$FQDN" ]; then error "Usage: $0 USERNAME PASSWORD FQDN [TESTMODE]" exit fi if [ -f $CRONJOB ]; then if [ -f $DISABLED ]; then logerror "Cron job has been disabled watch for bad return code!" if [ "$0" == "$CRONJOB" ]; then exit 1; fi fi fi if [ ! -f $CRONJOB -o $0 -nt $CRONJOB ]; then # can't use ln because this might be a softlink if cp -f $0 $CRONJOB; then logerror "NOTE: cron job has been created for this: $CRONJOB" else logerror "Failed creating cron job, exiting" exit 1 fi fi lastrun=`python -c "import os; print os.stat(\"$TMPCACHE\")[8]"` lastupdate=`python -c "import os; print os.stat(\"$CACHE\")[8]"` thisrun=`date +%s` if [ $((thisrun - lastupdate)) -gt $((29 * DAY)) ]; then FORCE=1; fi [ "$TESTING" ] && echo "thisrun=$thisrun, lastrun=$lastrun" delta=$((thisrun - lastrun)) if [ $delta -lt $((10 * MINUTE)) ]; then if [ "$0" == "$CRONJOB" ]; then # no need to log this 9 out of 10 runs is there? #logerror "Cannot run less than 10 minutes from previous run" exit else error "Should not run less than 10 minutes from previous run" error "Giving you 3 seconds to abort, hit control-C" sleep 3 fi fi CURRENTIP=`lynx --dump http://checkip.dyndns.org:8245 \ | awk '/Current IP Address: / {print $4}'` if [ -z "$CURRENTIP" ]; then logerror Could not determine current IP exit 1 fi echo $CURRENTIP > $TMPCACHE # cache it [ "$TESTING" ] && error CURRENTIP=$CURRENTIP LASTIP=`cat $CACHE` if [ -z "$LASTIP" -o "$FORCE" ]; then logerror Last known IP "$LASTIP": skipping this run echo 0.0.0.0 > $CACHE if [ "$FORCE" ]; then echo 255.255.255.255 > $CACHE; fi exit fi [ "$TESTING" ] && error LASTIP=$LASTIP # build the string that we'll need to compare with what DYNDNS returns good="good $CURRENTIP" count=`echo $FQDN | grep -c ','` while [ "$count" != "0" ]; do good=`printf "%s\n%s" "$good" "good $CURRENTIP"` count=$((count - 1)) done [ "$TESTING" ] && error "expecting: $good" if [ "$CURRENTIP" != "$LASTIP" ]; then RETURNCODE=`lynx -auth $USERNAME:$PASSWORD -dump \ "$URL?system=dyndns&hostname=$FQDN&myip=$CURRENTIP"` [ "$TESTING" ] && error "received: $RETURNCODE" if [ "$LASTIP" == "255.255.255.255" ]; then # means forced update logerror "Forced update of IP after 30 days; return code $RETURNCODE" echo $CURRENTIP > $CACHE elif [ "$RETURNCODE" != "$good" ]; then logerror "Bad return code from DYNDNS.ORG: $RETURNCODE; updates disabled" echo $RETURNCODE > $DISABLED logerror "Updating IP cache anyway: check before restarting!" echo $CURRENTIP > $CACHE else # good return, so cache the new IP echo $CURRENTIP > $CACHE fi else if [ "$TESTING" ]; then error "IPs are the same, skipping update" fi fi