NSLU2-Linux
view · edit · print · history

ddclient, updatedd, inadyn are in optware feed. Please test.

  • ddclient works perfectly with dyndns.com - ipkg install ddclient ( i did mess first with the scripts below but no success) - BR oct07

ddclient worked after creating ddclient.conf

vi /opt/etc/ddclient/ddclient.conf

Paste there your data:

 # /opt/etc/ddclient/ddclient.conf
 #
 protocol=dyndns2
 use=web
 login=mylogin
 password=mypassword
 myhost.dyndns.org

more ddclient usage info: http://ddclient.wiki.sourceforge.net/

Roga, dec07


Would you please post instuctionson how to get ddclient working, including
how to make it automaticaly start when I power up the slug. The above info
has not worked yet. I'm shure there is something missing. thanks


I have added a workaround to update the dyndns.org service, as my DSL-Router has no option to do this.

Install wget: ipkg install wget nb if you have already upgraded BusyBox then the above might fail- see HowTo.InstallWgetAfterUpgradingBusyBox


if /var/tmp does not exist create it: mkdir /var/tmp
Add dnsupd script: vi /opt/bin/dnsupd

 #!/bin/ash
 wget -q http://checkip.dyndns.com/index.html --output-document=/var/tmp/new.ip
 if [ "`cat /var/tmp/new.ip`" = "`cat /var/tmp/old.ip`" ]
 then echo "No new IP";
 else wget -q http://''username'':''password''@members.dyndns.org/nic/update?hostname=''domainname''.dyndns.org --output-document=/var/tmp/upd.ip
 echo "New IP";
 cat /var/tmp/upd.ip;
 rm /var/tmp/upd.ip;
 fi
 rm -f /var/tmp/old.ip
 mv /var/tmp/new.ip /var/tmp/old.ip


replace the following with your datas:
username = your DynDNS.org username
password = your DynDNS.org password
domainname = your registered domainname (i.e. whatever.dyndns.org)

make dnsupd executable: chmod 755 /opt/bin/dnsupd

The script should start once after reboot:
create S60dnsupd (or use an other number if S60xxx exists...):
vi /opt/etc/init.d/S60dnsupd

 
 #!/bin/sh
 if [ -n "`pidof dnsupd`" ]; then
    /bin/killall dnsupd 2>/dev/null
 fi
 umask 077
 /opt/bin/dnsupd


make S60dnsupd executable:
chmod 755 /opt/etc/init.d/S60dnsupd

Now the script should run every 15 min
vi /etc/crontab

add the following line:
*/15 * * * * root /opt/bin/dnsupd &>/dev/null

I offer no warranty of this information!

For your information i use the build UNSLUNG-1.11-beta-V23R25.bin
Please, feel free to edit every error or add new information about optimizing or any else...
P.S.: sorry for my bad english.. i'am still learning...

Otte


If you are using DynDNS for a custom domain (like mydomain.com), then you'll have to use a different wget string to update the IP address. It is as follows:

http://USERNAME:PASSWORD@members.dyndns.org/nic/update?system=custom&hostname=DOMAINNAME.COM

Just change USERNAME, PASSWORD, and DOMAINNAME.COM for it to work.

Mookie


My dyndns provider OVH (ovh.com) is not providing an auto check of the ip address, it means that I need the ip address to be given in the wget string to update the IP address. The provider is also not providing a page to "see" my ip, so I modified the /opt/bin/dnsupd script the following way:

 
 #!/bin/ash
 #Get the current ip and put it into /var/tmp/tmp.ip
 wget -q http://checkip.dyndns.com/index.html --output-document=/var/tmp/tmp.ip
 #Parse the answer to get only the ip and put it into /var/tmp/new.ip
 sed -e 's/^.*Address: //' -e 's/<.*$//' /var/tmp/tmp.ip > /var/tmp/new.ip
 if [ "`cat /var/tmp/new.ip`" = "`cat /var/tmp/old.ip`" ]
 then echo "No new IP";
 else wget -q http://LOGIN:PASSWORD@www.ovh.com/nic/update?myip=`cat /var/tmp/new.ip`\&hostname=DOMAIN\&system=dyndns --output-document=/var/tmp/upd.ip
 echo "New IP";
 cat /var/tmp/upd.ip;
 rm /var/tmp/upd.ip;
 fi
 rm -f /var/tmp/old.ip
 rm /var/tmp/tmp.ip
 mv /var/tmp/new.ip /var/tmp/old.ip

Note the backslash (\) before & in the wget string.

For info: http://www.dyndns.org/developers/specs/syntax.html

--titoo

If you use DynDNS wildcards, you should include \&wildcard=NOCHG in the update line.

This script still doesn't meet the requirements. One must send an update after 28 days even if the ip address hasn't changed. DynDNS will disable your account for abuse if you update too often, and for inactivity if you're lucky enough to have a stable IP address for 30 days. They allow a refresh at 28 days.

I don't have a solution for this within the constraints of a script and the standard shell.

Hint: with bash, one could set an expiration with touch -d 28days /var/tmp/exp.ip, and use && ! /var/tmp/new.ip -nt /var/tmp/exp.ip in the update decision...

There are a number of perl & similar scripts at DynDNS.org that seem to do the right things.

--tlhackque



Find a complete solution below, to run only every 28 days: - tested on unslung V2.3R25-uNSLUng-standard-3.18-beta - 2005-04-01 -

 
#!/bin/ash
 if [ ! -e /var/tmp/exp.ip ]; then touch -d -28days` /var/tmp/exp.ip; fi
 if [ "`ls -l --time-style=+%Y-%m-%d /var/tmp/exp.ip |cut -b32-36`" = "`date --date="-28 days" +'%m-%d'`" ]
 then wget -q http://checkip.dyndns.com/index.html --output-document=/var/tmp/new.ip
 if [ "`cat /var/tmp/new.ip`" = "`cat /var/tmp/old.ip`" ]; then echo "No new IP";
 else wget -q http://''username'':''password''@members.dyndns.org/nic/update?hostname=''yourname.dyndns.org'' --output-document=/var/tmp/upd.ip\\
 echo "New IP";
 cat /var/tmp/upd.ip; 
 rm /var/tmp/upd.ip; 
 fi 
 rm -f /var/tmp/old.ip
 mv /var/tmp/new.ip /var/tmp/old.ip
 touch /var/tmp/exp.ip 
 else echo "Skipped"
 fi


NOTE: for less use of CPU, modify the /etc/crontab entry,to run just once per day :-) 5 17 * * * root /opt/bin/dnsupd &> /dev/null

--matrix69


If your NSLU2 is behind a transparent proxy, http://checkip.dyndns.com and http://members.dyndns.org may return/update with your proxy server's IP address instead of your NSLU2's.

DynDns recommend the use of port 8245 so I have updated my scripts to use

http://checkip.dyndns.com:8245/index.html

http//<login>:<password>@members.dyndns.org:8245/nic/update?hostname=<yourDynHostName>

and I always get the right IP.

Ming Kiat 14 Apr 2005


The copied-pasted 28-day complete solution script above didn't work for me on Unslung 4 beta, perhaps because of plain old vanilla non-upgraded ls built-into BusyBox v0.60.4. It gave error "EOF: back quote parsing error" and complained about --time-style option being invalid option for ls. I changed the output of date command to match output of ls. Also, matrix69's script will update IP only once every 28 days, as opposed to

 1) Checking IP (once an hour or so) and updating IP if it changes

and

 2) Updating IP every 28 days even if IP has not changed yet


Here is modified script that does the above and works with limited ls from BusyBox that comes with Unslung 4 beta binary.
Of course, the script needs to be scheduled to run on regular intervals in crontab to fulfill its purposes. DynDNS website does not allow/recommend checking IP with them more often than every 10 minutes.

 
 #!/bin/ash

 if [ ! -e /var/tmp/exp.ip ]; then touch -d -28days /var/tmp/exp.ip;
 fi

 if [ "`ls -l /var/tmp/exp.ip |cut -b44-49`" = "`date --date="-28 days" +'%b %e'`" ]
 then
   wget -q http://user:password@members.dyndns.org:8245/nic/update?hostname=www.yourdomain.com\&wildcard=NOCHG --output-document=/var/tmp/upd.ip
   echo "28-th day - Mandatory update. Refreshed IP:";
   cat /var/tmp/upd.ip; 
   rm /var/tmp/upd.ip;  
   rm -f /var/tmp/old.ip
   mv /var/tmp/new.ip /var/tmp/old.ip
   touch /var/tmp/exp.ip 
 else
  echo "Checking IP ..."
  wget -q http://checkip.dyndns.com:8245/index.html --output-document=/var/tmp/new.ip
   if [ "`cat /var/tmp/new.ip`" = "`cat /var/tmp/old.ip`" ]; then
     echo "No new IP";
   else wget -q http://user:password@members.dyndns.org:8245/nic/update?hostname=www.yourdomain.com\&wildcard=NOCHG --output-document=/var/tmp/upd.ip
  echo "New IP:";
     cat /var/tmp/upd.ip; 
     rm /var/tmp/upd.ip; 
   fi 
   rm -f /var/tmp/old.ip
   mv /var/tmp/new.ip /var/tmp/old.ip
   touch /var/tmp/exp.ip 
 fi


It is important to note that this script will work ONLY if NSLU2 is up and running on the 28-th day so it can detect the condition when current date is equal to current date minus 28 days.

Andrei Volkov

June 13, 2005


Now, why couldn't the 28-day refreshment be made simply by a second "forced" crontab entry, like:

59 23 14,28 * * root /opt/bin/dnsupd-force &> /dev/null

Sure, that would run on 14th and 28th, is that too often?

Also, what's the purpose of "*/15" in the beginning of original crontab line, why not just "15".

Asko Kauppi Nov 24th 2005


The above scripts could trigger an update if, for any reason, the initial wget of checkip.dyndns.org failed. So it probably doesn't do any harm to surround the update with a check to ensure that the files containing the old.ip and new.ip look as though they contain valid data. My update script looks like this:

 
 #!/bin/sh
 wget -q http://checkip.dyndns.com/index.html --output-document=/var/tmp/new.ip
 if [ "`cat /var/tmp/new.ip`" = "`cat /var/tmp/old.ip`" ]
 then
        echo "No new IP"
 else
        PAT='Current IP Address:.*[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'
        if grep -q "$PAT" /var/tmp/new.ip && grep -q "$PAT" /var/tmp/old.ip; then
                wget -q 'http://MYNAME:MYPASSWORD@members.dyndns.org/nic/update?system=custom&hostname=MYHOST.MYDOMAIN.co.uk' -O /var/tmp/upd.ip
                echo "New IP"
                mv /var/tmp/new.ip /var/tmp/old.ip
                rm -f /var/tmp/upd.ip
        fi
 fi

The two greps ensure that the files contain the expected pattern before trusting their content.

John Bates - 4th Feb 2006


This is my litle dirty solution. A read-only-method. (tested on openslug 2.7)

 
#!/bin/sh
domain=example.dnydns.org
user=username
pass=password

oldip=`ping -c 1 $domain | grep "PING" | tr -d "(" | tr -d ")" | sed 's/\(^.* \)\([0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}\)\(.*\)/\2/g'`
newip=`wget -q -O - http://checkip.dyndns.com/index.html | tr "<" " " | tr ">" " " | sed 's/\(^.* \)\([0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}\)\(.*\)/\2/g'`

if [ $oldip = $newip ]; then 
	echo "No new IP ($newip)";
	exit 0
else
	echo "Old IP ($oldip) - New IP ($newip)";
	result=`wget -q http://$user:$pass@members.dyndns.org/nic/update?hostname=$domain -q -O -`
	echo $result;
	echo $result | grep -q "good"
	if [ $result -ne 0 ]; then exit 1; fi
	exit 0
fi

SPoner March 06, 2006, at 05:31 PM

Don't work on Unslug 5.5 if oldip don't reply to ping! :(


from the crontab man page:
"Steps are also permitted after an asterisk, so if you want to say ``every two hours, just use ``*/2."
*/15 every 15 minutes


Update: 7/23/2006
Try this script! It replaces dnsupd found at the beginning of this article, and
it incorporates some of the good ideas posted here.
It works great with uNSLUng 6.8 and wget-ssl.
Uses slick file find and logic to refresh the DynDNS Account if there is
no IP Address change for 28 days. Works well even if the slug was off
for a while. Echo commands are in there so you can see how it works,
but you can remove them.

#!/bin/ash
echo "Checking my current IP Address...";
/opt/bin/wget --quiet http://checkip.dyndns.com/ --output-document=/var/tmp/now.ip;
echo "Verifying received data...";
PAT='Current IP Address: *[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'
  if grep -q "$PAT" /var/tmp/now.ip;
  then echo "Current IP Address verified.";
    echo "Looking for IP Address history...";
      if [ -f /var/tmp/old.ip ]
      then echo "History Found.";
        echo "Comparing IP Address history with the present...";
          if [ "`cat /var/tmp/now.ip`" = "`cat /var/tmp/old.ip`" ]
          then echo "I still have the same IP Address.";
            echo "Checking the status of your DynDNS Account...";
            /opt/bin/find /var/tmp/ -name old.ip -mtime +27 -exec rm {} \;
              if  [ ! -f /var/tmp/old.ip ]
              then echo "It has been 28 Days with no IP Address Change!";
                echo "Refreshing your DynDNS Account...";
                /opt/bin/wget --quiet http://user:pass@members.dyndns.org/nic/update?hostname=user.selfip.com --output-document=/var/tmp/upd.ip;
                echo "Recording my IP Address...";
                cp /var/tmp/now.ip /var/tmp/old.ip;
              else echo "Your DynDNS Account is in good standing.";
              fi
            echo "My IP Address matches DynDNS's records.";
            cat /var/tmp/upd.ip;
            echo " is my IP Address.";
          else echo "I have a new IP Address!";
            echo "Updating DynDNS with my new IP Address...";
            /opt/bin/wget --quiet http://user:pass@members.dyndns.org/nic/update?hostname=user.selfip.com --output-document=/var/tmp/upd.ip;
            rm -f /var/tmp/old.ip;
            echo "Recording my new IP Address...";
            cp /var/tmp/now.ip /var/tmp/old.ip;
            cat /var/tmp/upd.ip;
            echo " is my new IP Address.";
          fi
      else echo "First time run!";
        echo "Setting up DynDNS with my current IP Address...";
        /opt/bin/wget --quiet http://user:pass@members.dyndns.org/nic/update?hostname=user.selfip.com --output-document=/var/tmp/upd.ip;
        echo "Recording my current IP Address...";
        cp /var/tmp/now.ip /var/tmp/old.ip;
        cat /var/tmp/upd.ip;
        echo " is my current IP Address.";
      fi
  else echo "Something is wrong!";
    echo "I could not obtain the correct information from the DynDNS Service.";
    echo "Check your network connections.";
  fi
echo "I will check my IP Address again in 15 minutes."


Enjoy!

Mo


Thanks Mo, here it is again with added common variables and a wildcard flag:

#!/bin/ash

USER=<dnsuser>
PASSWD=<dnspasswd>
DOMAIN=<domain.name.org>
WILDCARD=[ON|OFF]

echo "Checking my current IP Address...";
/opt/bin/wget --quiet http://checkip.dyndns.com/ --output-document=/var/tmp/now.ip;
echo "Verifying received data...";
PAT='Current IP Address: *[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'
  if grep -q "$PAT" /var/tmp/now.ip;
  then echo "Current IP Address verified.";
    echo "Looking for IP Address history...";
      if [ -f /var/tmp/old.ip ]
      then echo "History Found.";
        echo "Comparing IP Address history with the present...";
          if [ "`cat /var/tmp/now.ip`" = "`cat /var/tmp/old.ip`" ]
          then echo "I still have the same IP Address.";
            echo "Checking the status of your DynDNS Account...";
            /opt/bin/find /var/tmp/ -name old.ip -mtime +27 -exec rm {} \;
              if  [ ! -f /var/tmp/old.ip ]
              then echo "It has been 28 Days with no IP Address Change!";
                echo "Refreshing your DynDNS Account...";
                /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/tmp/upd.ip;
                echo "Recording my IP Address...";
                cp /var/tmp/now.ip /var/tmp/old.ip;
              else echo "Your DynDNS Account is in good standing.";
              fi
            echo "My IP Address matches DynDNS's records.";
            cat /var/tmp/upd.ip;
            echo " is my IP Address.";
          else echo "I have a new IP Address!";
            echo "Updating DynDNS with my new IP Address...";
            /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/tmp/upd.ip;
            rm -f /var/tmp/old.ip;
            echo "Recording my new IP Address...";
            cp /var/tmp/now.ip /var/tmp/old.ip;
            cat /var/tmp/upd.ip;
            echo " is my new IP Address.";
          fi
      else echo "First time run!";
        echo "Setting up DynDNS with my current IP Address...";
        /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/tmp/upd.ip;
        echo "Recording my current IP Address...";
        cp /var/tmp/now.ip /var/tmp/old.ip;
        cat /var/tmp/upd.ip;
        echo " is my current IP Address.";
      fi
  else echo "Something is wrong!";
    echo "I could not obtain the correct information from the DynDNS Service.";
    echo "Check your network connections.";
  fi
echo "I will check my IP Address again in 15 minutes."


Neil


Based on Mo and Neil's excellent script, adds logging of changes and just
one daily log entry if no change:

#!/bin/sh

USER=<dnsuser>
PASSWD=<dnspasswd>
DOMAIN=<domain.name.org>
WILDCARD=[ON|OFF]

/opt/bin/wget --quiet http://checkip.dyndns.com/ --output-document=/var/log/router_ip;

PAT='Current IP Address: *[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'

if grep -q "$PAT" /var/log/router_ip;
then
   if [ -f /var/log/router_ip_old ]
   then
      if [ "`cat /var/log/router_ip`" = "`cat /var/log/router_ip_old`" ]
      then
         find /var/log/ -name router_ip_old -mtime +27 -exec rm {} \;
         if  [ ! -f /var/log/router_ip_old ]
         then
            /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/log/upd.ip;
            cp /var/log/router_ip /var/log/router_ip_old;
            echo "`date +%Y%m%d.%H%M%S` - `cat /var/log/router_ip` - refreshed - `cat /var/log/upd.ip`" >> /var/log/ip_hist.log
            Set_Led beep1
            Set_Led beep1
            Set_Led beep1
            Set_Led beep1
            Set_Led beep1
         else
            if [ "`cat /var/log/ip_checked`" = "`date +%w`" ]
            then
               # do nothing
            else
               echo "`date +%Y%m%d.%H%M%S` - `cat /var/log/router_ip` not updated" >> /var/log/ip_hist.log
            fi
            echo "`date +%w`" > /var/log/ip_checked
         fi
      else
         /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/log/upd.ip;
         echo "`date +%Y%m%d.%H%M%S` - `cat /var/log/router_ip` - updated from `cat /var/log/router_ip_old` - `cat /var/log/upd.ip`" >> /var/log/ip_hist.log
         Set_Led beep1
         Set_Led beep1
         Set_Led beep1
         rm -f /var/log/router_ip_old;
         cp /var/log/router_ip /var/log/router_ip_old;
      fi
   else
      /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/log/upd.ip;
      echo "`date +%Y%m%d.%H%M%S` - `cat /var/log/router_ip` - initialized - `cat /var/log/upd.ip`" >> /var/log/ip_hist.log
      cp /var/log/router_ip /var/log/router_ip_old;
   fi
else
   echo "`date +%Y%m%d.%H%M%S` - `cat /var/log/router_ip` - not updated: read error on ip fetch" >> /var/log/ip_hist.log
   Set_Led beep2
fi


I figured that a log file might be helpful to assess what was happening and when....

Thanks to my log file, I was able to see roughly how long my slug was out
of contact with the web when the AC power blipped and made my hub lose its
mind earlier this week during a thunderstorm. (even with my UPS, it's
sensitive to power blips!) It will also allow me to get rough timings of
network outages on the part of my ISP, as well as info about frequency of IP
changes. I also chose to have it write one log entry per day indicating that
the IP was static, on the first check after midnight. Change to a different
argument for the date command, and you can use a different time interval for\\ this entry.... :^)

HTH!

Dutch


Update: 7/30/2006
Thank you, both Neil and Dutch for the improvements. I consider this
script to be a wonderful example of what people can accomplish when
they give without asking anything in return. I am reposting my
script and incorporating Neil's common variables and Dutch's logging.
This improved script passed my test of each feature. I am pleased
with it, but if anyone wants to throw in a kitchen sink... Great!

#!/bin/ash

USER=<dnsuser>
PASSWD=<dnspasswd>
DOMAIN=<domain.name.org,domain2.name.org,domain3.name.org>
WILDCARD=[ON|OFF]

# DynDNS Update Client for the Slug
# Version: 08/03/2006
# Look for err.ip
if [ ! -f /var/tmp/err.ip ]
then
# On err.ip not found.
  # Set up err.ip for error logging.
  echo "off" > /var/tmp/err.ip
fi
# Fetch current IP Address.
/opt/bin/wget --quiet http://checkip.dyndns.com/ --output-document=/var/tmp/now.ip;
# Verify the data is good.
PAT='Current IP Address: *[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'
if grep -q "$PAT" /var/tmp/now.ip;
then
# On good IP data.
  # Check for IP history.
  if [ -f /var/tmp/old.ip ]
  then
  # On history found.
    if [ "`cat /var/tmp/err.ip`" = "on" ]
    then
      echo "`date +%Y%m%d.%H%M%S` - not updated: Network connection restored." >> /var/log/ip_hist.log;
      # Turn err.ip Off
      echo "off" > /var/tmp/err.ip
    fi
    # Check for IP Change
    if [ "`cat /var/tmp/now.ip`" = "`cat /var/tmp/old.ip`" ]
    then
    # On no IP change
      # Check if 28 day refresh is needed.
      /opt/bin/find /var/tmp/ -name old.ip -mtime +27 -exec rm {} \;
      if  [ -f /var/tmp/old.ip ]
      then
      # On no refresh needed.
        # Check for Next day. 
        if [ ! "`cat /var/tmp/day.ip`" = "`date +%x`" ]
        then
        # On day change
          # Log entry
          echo "`date +%Y%m%d.%H%M%S` - No update - `cat /var/tmp/upd.ip`" >> /var/log/ip_hist.log;
          echo "`date +%x`" > /var/tmp/day.ip;
        fi
      else
      # On refresh needed.
        # Do a 28 Day refresh and Notify user with a distinguishable beep.
        /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/tmp/upd.ip;
        echo "`date +%Y%m%d.%H%M%S` - Refresh - `cat /var/tmp/upd.ip`" >> /var/log/ip_hist.log;
        echo "`date +%x`" > /var/tmp/day.ip;
        cp /var/tmp/now.ip /var/tmp/old.ip;
        Set_Led beep1
        Set_Led beep1
        Set_Led beep1
        Set_Led beep1
        Set_Led beep1
      fi
    else
    # On IP change
      # Update DynDNS with new IP Address. 
      /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/tmp/upd.ip;
      # Log the IP change and notify user.
      echo "`date +%Y%m%d.%H%M%S` - update - `cat /var/tmp/upd.ip`" >> /var/log/ip_hist.log;
      echo "`date +%x`" > /var/tmp/day.ip;
      rm -f /var/tmp/old.ip;
      cp /var/tmp/now.ip /var/tmp/old.ip;
      Set_Led beep1
      Set_Led beep1
      Set_Led beep1
    fi
  else
  # On No History
    # Initialize client and Update DynDNS.
    # Check err.ip status
    if [ "`cat /var/tmp/err.ip`" = "on" ]
    then
    # Log Service Restoral.
      echo "`date +%Y%m%d.%H%M%S` - not updated: Network connection restored." >> /var/log/ip_hist.log;
    fi
    # Set err.ip off
    echo "off" > /var/tmp/err.ip
    /opt/bin/wget --quiet "http://${USER}:${PASSWD}@members.dyndns.org/nic/update?hostname=${DOMAIN}&wildcard=${WILDCARD}" --output-document=/var/tmp/upd.ip;
    echo "`date +%Y%m%d.%H%M%S` - initialization - `cat /var/tmp/upd.ip`" >> /var/log/ip_hist.log;
    echo "`date +%x`" > /var/tmp/day.ip;
    cp /var/tmp/now.ip /var/tmp/old.ip;
  fi
else
# On IP read error
  # Check err.ip status
  if [ ! "`cat /var/tmp/err.ip`" = "on" ]
  then
  # On err.ip = off - Log read error. 
    echo "`date +%Y%m%d.%H%M%S` - not updated: read error on ip fetch" >> /var/log/ip_hist.log;
  fi
  # Set err.ip = On to allow only one error log on next run.
  echo "on" > /var/tmp/err.ip
  # Notify user.
  Set_Led beep2
fi
# end
# Set the interval of the next IP check using a crontab entry.
# Once every 15 minutes is good for a home server.


The log file is extremely helpful! But, unlike Dutch's script, I put only
the actual log file: ip_hist.log into the directory /var/log/.
I think all the .ip files belong in /var/tmp/.
I changed date +%w to date +%x, just in case the slug
experiences a T.K.O. for exactly 1 week, and I also made a couple
of other minor adjustments in logic flow.
Thanks guys!

Mo


Hi,

great little script - very usefull. Thank you very much for this one!

Under some rare circumstances it is possible that the slug wont be able to resolve the correct IP for the dyndns servers and the script gets stuck. This could be prevent by two simple lines at the start of the script:

/opt/bin/ping -c 1 checkip.dyndns.org\\
/opt/bin/ping -c 1 members.dyndns.org\\


Hope this helps a bit.

JuergenS


https works for members.dyndns.org/nic/update and protects your password.

Dimitris


Users who have configured there /var folder to be stored on a ram
disk should modify the relevant parts of the scripts above so that the
various files are saved to the alternative folders /opt/var/log and
/opt/var/tmp. These two folders may need to be created by the user
and flagged with chmod 755.

Note that for user written scripts such as these, the recommended folder
tree to use with Unslung firmware is /opt/var.

RobHam


RobHam, if I modify the paths as you propose this prevents the harddisk from spinning down, which is the main reason for using a ramdisk. Shouldn't it be the other way round?

DavidH


I have unSlung 6.8 my slug and have tried most of the above but i keep geting 401 Authorization Error, i have tested my members.dyndns.org url in fire fox and it works ok. Any ideas any one?

--EDIT-- Fixed it, the default PATH statement needs to be modified if using the ash shell (i.e. from Optware bash or busybox). There are two work arounds to this :-

1. Change the script to use the default sh shell (but do note that the default sh shell on the NSLU2 has limited functionality and has not been tested with some of the scripts).

2. Create a profile file /etc/profile and add the following line

export PATH=/opt/sbin:/opt/bin:${PATH}

Hutchweb - modified by RobHam


Update: Feb 2007
Another version of MO's excellent script above expanded so
that the script should comply with the DynDns Developers
specification for an update client.

Functionality added: -

1. Script will update when a Users DynDns setting are change.

2. A formatted User-Agent string now included.

3. Script will detect fatal errors returned from DynDns, detection
of a fatal error will disable the script.

There are a number of other minor changes mainly to try and make it
backward compatible with early versions of the command programs that
are used. Note that the script is not fully tested with a full set of
base firmware command programs from all firmware versions.
Users should consider upgrading the command programs to the latest
versions from the ipkg to guarantee the correct functionality.

I have also used variables in place of program call paths to make it
easier for the script to be changed for different Linux distro’s.

Suggest that any potential users of this script version should first
check the functionality on there system using one of the DynDns
test accounts before committing there own account details.

DynDns recommend the use of https so that user details and password
are encrypted, to use https users would need to install the Optware
packages openssl and wget-ssl.

If a user corrects any errors with the script then they should also bump
the User-Agent script version to reflect these changes.

#!/bin/sh
# DynDNS Update Client for the Linux NSLU2
#
# Script version - (used for user-agent)
VER=NSLU2-Linux-DNSUPD-0.9.4beta

# User configurable Section
#
# USER=<dnsuser>
# PASSWD=<dnspasswd>
# DOMAIN=<domain.name.org,domain2.name.org,domain3.name.org>
# SYSTEM=[dyndns|statdns|custom]
# WILDCARD=[ON|OFF|NOCHG]
# MX=[mailexchanger.name.org|NOCHG]
# BACKMX=[YES|NO|NOCHG]
# OFFLINE=[YES|NO] or leave blank

USER=test
PASSWD=test
DOMAIN=test.dyndns.org
SYSTEM=dyndns
WILDCARD=ON
MX=NOCHG
BACKMX=NOCHG
OFFLINE=

# Var folder, Set VAR to either '/var' or '/opt/var', '/opt/var' recommended for Unslung users
VAR=/opt/var

# Update using either 'http' or 'https' (openssl and wget-ssl are needed for https)
HTTP=http
# For https set SSL=--no-check-certificate
SSL=

# Paths to program files
WGET=/opt/bin/wget
FIND=/opt/bin/find
CHMOD=/bin/chmod
MKDIR=/bin/mkdir
GREP=/bin/grep
ECHO=/bin/echo
DATE=/bin/date
CAT=/bin/cat
SED=/bin/sed
CP=/bin/cp
RM=/bin/rm
# A beep command equivalent to 'printf "\a"'
BEEP='Set_Led beep1'

# Dyndns script update section
# 
# Check and create folders
if [ ! -d ${VAR}/log ]; then
${MKDIR} -p ${VAR}/log
${CHMOD} 755 ${VAR}/log
fi
if [ ! -d ${VAR}/tmp ]; then
${MKDIR} -p ${VAR}/tmp
${CHMOD} 755 ${VAR}/tmp
fi

# Check and create err.ip
if [ ! -f ${VAR}/tmp/err.ip ]
then
  ${ECHO} "off" > ${VAR}/tmp/err.ip
fi

# Check for Fatal error file,  disable script and error beep if file exists
if [ -f ${VAR}/log/dyndns.fatal.error ]
then
  ${BEEP}
  ${BEEP}
  exit 0
fi

# Fetch current IP Address.
${WGET} -q -t 1 -T 30 -U ${VER} -O ${VAR}/tmp/now.ip http://checkip.dyndns.com:8245/
# Verify the data is good.
PAT='Current IP Address: *[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'
if ${GREP} "$PAT" ${VAR}/tmp/now.ip >/dev/null;
then
  MYIP="`${SED} -e 's|.*Address: ||; s|</body>.*||' ${VAR}/tmp/now.ip`"
  # On good IP data.
  # Check for IP history.
  if [ -f ${VAR}/tmp/old.ip ]
  then
    # On history found.
    if [ "`${CAT} ${VAR}/tmp/err.ip`" = "on" ]
    then
      ${ECHO} "`${DATE} +%Y%m%d.%H%M%S` - not updated: Network connection restored." >> ${VAR}/log/ip_hist.log;
      # Turn err.ip Off
      ${ECHO} "off" > ${VAR}/tmp/err.ip
    fi
    # Check for settings change
    if [ ! "`${CAT} ${VAR}/tmp/update.para`" = "${USER}:${PASSWD}:${DOMAIN}:${SYSTEM}:${WILDCARD}:${MX}:${BACKMX}:${OFFLINE}:" ]
    then 
      ${WGET} -q -t 1 -T 30 -U ${VER} -O ${VAR}/tmp/upd.ip ${SSL} "${HTTP}://${USER}:${PASSWD}@members.dyndns.org/nic/update?system=${SYSTEM}&hostname=${DOMAIN}&myip=${MYIP}&wildcard=${WILDCARD}&mx=${MX}&backmx=${BACKMX}&offline=${OFFLINE}";
      # Log the settings change and notify user.
      ${ECHO} "`${DATE} +%Y%m%d.%H%M%S` - Settings - `${CAT} ${VAR}/tmp/upd.ip`" >> ${VAR}/log/ip_hist.log;
      ${ECHO} "`${DATE} +%x`" > ${VAR}/tmp/day.ip;
      ${RM} -f ${VAR}/tmp/old.ip;
      ${CP} ${VAR}/tmp/now.ip ${VAR}/tmp/old.ip;
      ${ECHO} "${USER}:${PASSWD}:${DOMAIN}:${SYSTEM}:${WILDCARD}:${MX}:${BACKMX}:${OFFLINE}:" > ${VAR}/tmp/update.para;
      ${BEEP}
    fi
    # Check for IP Change
    if [ "`${CAT} ${VAR}/tmp/now.ip`" = "`${CAT} ${VAR}/tmp/old.ip`" ]
    then
      # On no IP change
      # Check if 28 day refresh is needed.
      # you must enter the appropriate paths for the find command
      # but do not use variables in the string or it may not work correctly 
      /opt/bin/find /opt/var/tmp/ -name old.ip -mtime +27 -exec rm {} \;
      if  [ -f ${VAR}/tmp/old.ip ]
      then
        # On no refresh needed.
        # Check for Next day. 
        if [ ! "`${CAT} ${VAR}/tmp/day.ip`" = "`${DATE} +%x`" ]
        then
          # On day change
          # Log entry
          ${ECHO} "`${DATE} +%Y%m%d.%H%M%S` - No update - `${CAT} ${VAR}/tmp/upd.ip`" >> ${VAR}/log/ip_hist.log;
          ${ECHO} "`${DATE} +%x`" > ${VAR}/tmp/day.ip;
        fi
      else
        # On refresh needed.
        # Do a 28 Day refresh and Notify user with a distinguishable beep.
        ${WGET} -q -t 1 -T 30 -U ${VER} -O ${VAR}/tmp/upd.ip ${SSL} "${HTTP}://${USER}:${PASSWD}@members.dyndns.org/nic/update?system=${SYSTEM}&hostname=${DOMAIN}&myip=${MYIP}&wildcard=${WILDCARD}&mx=${MX}&backmx=${BACKMX}&offline=${OFFLINE}";
        echo "`${DATE} +%Y%m%d.%H%M%S` - Refresh - `${CAT} ${VAR}/tmp/upd.ip`" >> ${VAR}/log/ip_hist.log;
        echo "`${DATE} +%x`" > ${VAR}/tmp/day.ip;
        ${CP} ${VAR}/tmp/now.ip ${VAR}/tmp/old.ip;
        ${BEEP}
      fi
    else
      # On IP change
      # Update DynDNS with new IP Address. 
      ${WGET} -q -t 1 -T 30 -U ${VER} -O ${VAR}/tmp/upd.ip ${SSL} "${HTTP}://${USER}:${PASSWD}@members.dyndns.org/nic/update?system=${SYSTEM}&hostname=${DOMAIN}&myip=${MYIP}&wildcard=${WILDCARD}&mx=${MX}&backmx=${BACKMX}&offline=${OFFLINE}";
      # Log the IP change and notify user.
      ${ECHO} "`${DATE} +%Y%m%d.%H%M%S` - Update - `${CAT} ${VAR}/tmp/upd.ip`" >> ${VAR}/log/ip_hist.log;
      ${ECHO} "`${DATE} +%x`" > ${VAR}/tmp/day.ip;
      ${RM} -f ${VAR}/tmp/old.ip;
      ${CP} ${VAR}/tmp/now.ip ${VAR}/tmp/old.ip;
      ${BEEP}
    fi
  else
    # On No History
    # Initialize client and Update DynDNS.
    # Check err.ip status
    if [ "`${CAT} ${VAR}/tmp/err.ip`" = "on" ]
    then
      # Log Service Restoral.
      ${ECHO} "`${DATE} +%Y%m%d.%H%M%S` - not updated: Network connection restored." >> ${VAR}/log/ip_hist.log;
    fi
    # Set err.ip off
    ${ECHO} "off" > ${VAR}/tmp/err.ip
    ${WGET} -q -t 1 -T 30 -U ${VER} -O ${VAR}/tmp/upd.ip ${SSL} "${HTTP}://${USER}:${PASSWD}@members.dyndns.org/nic/update?system=${SYSTEM}&hostname=${DOMAIN}&myip=${MYIP}&wildcard=${WILDCARD}&mx=${MX}&backmx=${BACKMX}&offline=${OFFLINE}";
    ${ECHO} "`${DATE} +%Y%m%d.%H%M%S` - Initialise - `${CAT} ${VAR}/tmp/upd.ip`" >> ${VAR}/log/ip_hist.log;
    ${ECHO} "`${DATE} +%x`" > ${VAR}/tmp/day.ip;
    ${CP} ${VAR}/tmp/now.ip ${VAR}/tmp/old.ip;
    ${ECHO} "${USER}:${PASSWD}:${DOMAIN}:${SYSTEM}:${WILDCARD}:${MX}:${BACKMX}:${OFFLINE}:" > ${VAR}/tmp/update.para
    ${BEEP}
  fi
  # Analyse and report any Fatal error return strings
  if ${GREP} "\!yours\|notfqdn\|abuse\|nohost\|badagent\|badauth\|badsys\|dnserr\|numhost\|911\|\!donator" ${VAR}/tmp/upd.ip >/dev/null
  then
    ${ECHO} "`${DATE} +%x` - Fatal Error Returned from Dyndns - `${CAT} ${VAR}/tmp/upd.ip` - Correct the error then delete this file to re-enable" > ${VAR}/log/dyndns.fatal.error;
    ${BEEP}
    ${BEEP}
    #
    # Place holder - for example - to send fatal error report by email
    #
  fi
else
  # On IP read error
  # Check err.ip status
  if [ ! "`${CAT} ${VAR}/tmp/err.ip`" = "on" ]
  then
    # On err.ip = off - Log read error. 
    ${ECHO} "`${DATE} +%Y%m%d.%H%M%S` - not updated: read error on ip fetch" >> ${VAR}/log/ip_hist.log;
  fi
  # Set err.ip = On to allow only one error log on next run.
  ${ECHO} "on" > ${VAR}/tmp/err.ip
  # Notify user.
  ${BEEP}
  ${BEEP}
fi
# end
# Set the interval of the next IP check using a crontab entry.
# Once every 15 minutes is good for a home server.
# */15 * * * * root /opt/bin/dnsupd &>/dev/null
#

RobHam


If this script has not run before, and the directories /var/tmp and /var/log do not exist,
then the script can not create them.
A "can't make directory error". I addded the "-p" option to mkdir.
This is on a very new unmodified box.

# Check and create folders
if [ ! -d ${VAR}/log ]; then
${MKDIR} -p ${VAR}/log
${CHMOD} 755 ${VAR}/log
fi@@
if [ ! -d ${VAR}/tmp ]; then
${MKDIR} -p ${VAR}/tmp
${CHMOD} 755 ${VAR}/tmp
fi

RobertSlater


Changed MYIP="${SED} -e 's|.*Address: ||; s|</body>.*||' ${VAR}/tmp/now.ip" to MYIP="`${SED} -e 's|.*Address: ||; s|</body>.*||' ${VAR}/tmp/now.ip`" so it actually gets executed.

Matt Horsfall


The following paragraph are comments received from a
Certification Technician from Dynamic Network Services.
His suggestions regarding the error return string
are included in the above script, script bumped up
to version 0.9.3beta.

I've tested out the script, and I have a few suggestions.
In the return code parsing section, you have:

 
# Analyse and report any Fatal error return strings
if ${GREP} "\!yours\|notfqdn\|abuse\|nohost\|nochg\|badagent\|badauth\|badsys"
 

You can remove nochg from this list, as if this is the first time
the client updates and your IP is the same, it will receive
a nochg error which is fine. There are, however, four other error
codes you should add in:

 
!donator
dnserr
911
numhost

Also, does NSLU2 include sendmail or something similar?
If so, I think it would be a good idea to have the script
send an E-mail notification on a failed update, though it's
not a requirement of ours.

Aside from that, I believe that script is fine, and we certainly
appreciate it when developers follow our specifications.

Certification Technician
Dynamic Network Services, Inc.

RobHam


I am not exactly sure why, but testing proves that the find command does
not seem to function with variables in the string. Thus previous script versions
will fail to do a refresh. refresh seems only to work in the script if it is as it
would be typed from the command line.
My suggested change for the script is as follows:

# you must enter the appropriate paths for the find command
# but do not use variables in the string or it may not work correctly 
/opt/bin/find /opt/var/tmp/ -name old.ip -mtime +27 -exec rm {} \;


Script bumped to Version 0.9.4

Wonderful work guys!

Mo

Follow up - I can replicate this. I tried all combinations
of available 'find' (two versions) and 'rm' (three versions)
with my Unslung NSLU2. The script with variables seems to
work OK when using the default 'find' version 4.1.20 or
Optware 'find' version 4.2.30 together with either the
default 'rm' from Busybox version 0.60.4 or 'rm' from the
Optware Coreutils version 6.7. For reasons not fully
understood there seems to be a problem using variables
when using 'rm' from the later Optware Busybox version 1.5.0.

There is a work around. The later Optware version of
'find' 4.2.30 allows you to use -delete rather than
-exec rm {} \; so with this version the script line
can be re-written using variables as follows.

${FIND} ${VAR}/tmp/ -name old.ip -mtime +27 -delete

Have not committed this to the script, to allow others to test first.

RobHam


07/06/2008

For a variation that will send your dynamic ip address as a html web page to a web server

at a static address (of your choice) see the page at

SetUpYourOwnStaticLinkToYourSiteAtADynamicIP

( http://www.nslu2-linux.org/wiki/HowTo/SetUpYourOwnStaticLinkToYourSiteAtADynamicIP )

SRS 07/06/2008