Re: dyndns with udhcpc mini-how to

Not to beat a dead horse, but I'll throw my hat into the ring with a script.  I'm still working on tweaking my OpenWrt config on my new router before replacing my old unit, and I was running something similar on my web server box here to keep my dynamic dhcp working.  One of the things that I hated about the old script was that I had to call an external server to check my local IP.  Now that I have a script running in the router itself, this is easy to determine, and the script is a lot cleaner.

#!/bin/sh

old_ip="0.0.0.0"
current_ip="0.0.0.0"

sleep_time=30 # time in seconds to wait between loops
user="user"
pass="pass"

max_days=10 # max number of days to go without forcing an update
last_update=`date +%s`

max_seconds=`expr $max_days*24*60*60`

while : ; do

        current_ip=$(ifconfig $(nvram get wan_ifname) | grep inet | cut -d B -f1 | sed s/[^0-9.]//g)

        if [ $(($last_update+$max_seconds)) -lt `date +%s` ]
        then
                # set old_ip to be different, forcing an update
                old_ip="0.0.0.0"
        fi

        if [ $old_ip != $current_ip ]
        then
                # current ip different from old ip
                old_ip=$current_ip
                 
                wget -q -O /dev/null "http://www.sitelutions.com/dnsup?id=xxx&user=$user&pass=$pass&ip=${current_ip}"
                last_update=$(date +%s)
        fi

        sleep $sleep_time
done &

The script above shouldn't need to much explanation.  The sleep_time is the number of seconds between checks on if the WAN IP has changed.  User/Password are what your particular service uses, max_days is the number of days that will pass before forcing an update, for those services that you have to tickle periodically to keep active.

The old IP isn't saved elsewhere, so when the script first runs, an update will occur, unless you're rebooting your router several times a day, this shouldn't be a problem.

Lastly, the wget line.  I'm using the service from sitelutions.com, and this is the general format for their updates.  If you use a different service, just change the URL there to fit your needs.  If you have multiple records that need updating, just duplicate that line as many times as you need for each record, assuming your service doesn't have a way to update all records at once (for sitelutions.com, you'd just include additional '?id=xxx' statements.

I hope some of you find this script useful.

27

Re: dyndns with udhcpc mini-how to

Jim, your script works fine provided that your router's WAN interface is connected directly to the internet. The reason previous scripts used an outside service was to accommodate routers that are behind another router (e.g. a DSL or cable modem).

28 (edited by bytesplit 2006-12-02 18:21:32)

Re: dyndns with udhcpc mini-how to

I just want to add that the script posted by mbm can easily be extended with more values. In my case I needed to add MX fields, as I use to play with that feature from time to time. For everyone interested here is where I found the server's syntax: http://www.dyndns.com/developers/specs/syntax.html

hope that helps those in the need

while ( no == yes ) {
     mute $wife
}

29

Re: dyndns with udhcpc mini-how to

mbm wrote:

Opps. I tossed it together as an example without actually testing it.

Anyways, here's the corrected version for cut&paste:

#!/bin/sh
USER="username"
PASS="password"
DOMAIN="example.com"

registered=$(nslookup $DOMAIN|sed s/[^0-9.]//g|tail -n1)

while :; do
  current=$(wget -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)
  [ "$current" != "$registered" ] && {                           
     wget -O /dev/null http://$USER:$PASS@members.dyndns.org/nic/update?hostname=$DOMAIN &&
     registered=$current
  }                     
  sleep 300             
done &

I modified this script to be run as a cronjob and for the FreeDNS service at afraid.org... also many portions of the above were broken, probably due to the commands changing over time, anyway here we are:

#!/bin/sh
#FreeDNS updater script

UPDATEURL="http://freedns.afraid.org/dynamic/update.php?JHGHgKhvJHgKKhjbkhBkjhKuhKug"
DOMAIN="my.domain.org"

registered=$(nslookup $DOMAIN|tail -n2|grep A|sed s/[^0-9.]//g)

  current=$(wget -q -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)
  [ "$current" != "$registered" ] && {                           
     wget -q -O /dev/null $UPDATEURL 
     echo "DNS updated on:"; date
  }

Re: dyndns with udhcpc mini-how to

After reading through this thread I was able to come up with a solution for my own ddns server that I needed to update.   This code below:

#!/bin/sh
#ddns Update Script

wan_config=$(ifconfig 2>&1 | grep -A 6 "`nvram get wan_ifname`")
wan_ip_addr=$(echo "$wan_config" | grep "inet addr" | cut -d: -f 2 | sed s/Bcast//g)

UPDATEURL="http://myddns:81/nic/update/rupdate.asp?hostname=user.mydds.com&uid=user@somewhebsite.com&pass=test&myip=wan_ip_addr"

registered=$(nslookup $DOMAIN|tail -n2|grep A|sed s/[^0-9.]//g)

  current=$(wget -q -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)
  [ "$current" != "$registered" ] && {                           
     wget -q -O /dev/null $UPDATEURL
     echo "DNS updated on:"; date
  }

Again, this worked great for white russian, but I a now trying to use KamiKaze,  Since Kamikaze doesn't use NVRAM, I need to figure out how to retrieve the public IP address. 

basically,  myip=wan_ip_addr  has to be the public IP.

Any help would be appricated.

Thanks
ScarEye

31 (edited by Weedy 2007-05-05 06:37:57)

Re: dyndns with udhcpc mini-how to

i have sympatico dsl.

# head -n20 /etc/firewall.user
#!/bin/sh
# Copyright (C) 2006 OpenWrt.org

[ "$WAN" != "ppp0" ] && exit
PPPUP=$(ifconfig $WAN 2>&1 |grep "Device not found")
[ -n "$PPPUP" ] && exit
IP=$(ifconfig $WAN | grep 'inet addr' | awk '{print $2}' | cut -d':' -f 2)
[ -z "$IP" ] && exit
logger -t firewallVars "PPPUP = $PPPUP, IP = $IP, LAN = $LAN, WAN = $WAN"

iptables -F input_rule
iptables -F output_rule
iptables -F forwarding_rule
iptables -t nat -F prerouting_rule
iptables -t nat -F postrouting_rule
# cat /etc/hotplug.d/iface/20-firewall-update
#!/bin/sh
[ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] && /etc/init.d/firewall restart && logger -t firewall "Updated successfuly"

Now this wont work for you because i use ez-ipupdate for DDNS and $IP is set for my snat rules. your  /etc/hotplug.d/iface/20-ddns script needs to be self-reliant because it doesnt get $WAN set by /etc/init.d/firewall.

# cat /etc/hotplug.d/iface/20-ddns
#!/bin/sh
[ "$ACTION" = "ifup" -a "$INTERFACE" = "wan" ] && {
         include /lib/network
         scan_interfaces
         config_get WAN wan ifname
         [ "$WAN" != "ppp0" ] && exit
         PPPUP=$(ifconfig $WAN 2>&1 |grep "Device not found")
         [ -n "$PPPUP" ] && exit
         IP=$(ifconfig $WAN | grep 'inet addr' | awk '{print $2}' | cut -d':' -f 2)
         [ -z "$IP" ] && exit

         UPDATEURL="http://myddns:81/nic/update/rupdate.asp?hostname=user.mydds.com&uid=user@somewhebsite.com&pass=test&myip=${IP}"

         registered=$(nslookup $DOMAIN|tail -n2|grep A|sed s/[^0-9.]//g)

         current=$(wget -q -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)
         [ "$current" != "$registered" ] && {
                  wget -q -O /dev/null $UPDATEURL
                  echo "DNS updated on:"; date
         }
}

Edit: FINE i'll do all the work for you

Re: dyndns with udhcpc mini-how to

You da man....


Thanks Weddy,

ScarEye

33 (edited by mbm 2007-05-05 11:09:14)

Re: dyndns with udhcpc mini-how to

Weedy wrote:

Edit: FINE i'll do all the work for you

Doesn't seem like you'd need most of those sanity checks

The only thing that you need to do is get your current ip ($current) and see if it's changed from the ip registered to the domain name ($registered) otherwise hit the refresh url -

# cat /etc/hotplug.d/iface/20-ddns
#!/bin/sh
UPDATEURL="http://myddns:81/nic/update/rupdate.asp?hostname=user.mydds.com&uid=user@somewhebsite.com&pass=test"

registered=$(nslookup $DOMAIN|tail -n2|grep A|sed s/[^0-9.]//g)
current=$(wget -q -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)
[ "$current" != "$registered" ] && {
         wget -q -O /dev/null "$UPDATEURL&myip=$current"
         echo "DNS updated on:"; date
}

EDIT - add myip to the url

34 (edited by ScarEye 2007-05-05 10:11:51)

Re: dyndns with udhcpc mini-how to

mbm,

   Without the myip= it will not work with this ddns server. 

UPDATEURL="http://myddns:81/nic/update/rupdate.asp?hostname=user.mydds.com&uid=user@somewhebsite.com&pass=test&myip=theupdatedip"  <----


I saw that you posted this somewhere and I tried it.  But it didn't work.

Re: dyndns with udhcpc mini-how to

OK, there's 49830761309849065439018609854 solutions posted in this thread and one wiki entry(which was helpfully deleted -- why?).

Which solution's the right one?

Re: dyndns with udhcpc mini-how to

Solution 49830761309849065439018609855:
I made a mashup of JimWright's date-checking stuff, and mbm's script for DynDNS. This forces an update every 10 days (well, it should, it hasn't been 10 days since I wrote it) or every time the address changes (that's been tested, start updater, power cycle DSL modem, check dyndns page, power cycle DSL modem, check dyndns page, do victory lap because you saw 3 different IP addresses on the dyndns page).

The elegant part of this is that you don't need updatedd or ez-ipupdate or any of the crunchy gooey sweet stuff that goes with them, you don't lose 12+ K of precious flash holding a service you don't need, and you just link to the script with something like 'ln /usr/bin/update S98dyndns' from inside /etc/init.d to make it permanent.

Here it is:

#!/bin/sh
USER="changeme"
PASS="changeme"
DOMAIN="changeme"

registered=$(nslookup $DOMAIN|sed s/[^0-9.]//g|tail -n1)

max_days=10 # max number of days to go without forcing an update
last_update=`date +%s`

max_seconds=`expr $max_days*24*60*60`

while :; do
  current=$(wget -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)
 
  if [ $(($last_update+$max_seconds)) -lt `date +%s` ]
  then
    # set old_ip to be different, forcing an update
        registered="0.0.0.0"
  fi
 
  [ "$current" != "$registered" ] && {                           
     wget -O /dev/null http://$USER:$PASS@members.dyndns.org/nic/update?hostname=$DOMAIN &&
     registered=$current
  }                     
  sleep 300             
done &

Re: dyndns with udhcpc mini-how to

I've been attempting to use johnnyjet's solution # 49830761309849065439018609855, but something seems to be giving me the following error:

Connecting to checkip.dyndns.org [204.13.249.51:80]
-                    100% |*****************************|   106    --:--:-- ETA
Connecting to members.dyndns.org [63.208.196.96:80]
wget: Segmentation fault

Any idea what might be wrong? Here is the script - I can't see anything wrong with it:

#!/bin/sh
USER="***"
PASS="***"
DOMAIN="***.dyndns.org"

registered=$(nslookup $DOMAIN|sed s/[^0-9.]//g|tail -n1)

max_days=10 # max number of days to go without forcing an update
last_update=`date +%s`

max_seconds=`expr $max_days*24*60*60`

while :; do
  current=$(wget -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)

  if [ $(($last_update+$max_seconds)) -lt `date +%s` ]
  then
    # set old_ip to be different, forcing an update
        registered="0.0.0.0"
  fi

  [ "$current" != "$registered" ] && {
     wget -O /dev/null http://$USER:$PASS@members.dyndns.org/nic/update?hostname=$DOMAIN &&
     registered=$current
  }
  sleep 300
done &

Re: dyndns with udhcpc mini-how to

Yah - you need to get a real (i.e., non-busybox) version of wget:

ipkg install wget

Then the script will work.

39

Re: dyndns with udhcpc mini-how to

Very useful, thanks to all who contributed. A few problems remain, so I suggest the following variation:

#!/bin/sh
USER="username"
PASS="password"
DOMAIN="domain"

registered=$(nslookup $DOMAIN|sed 's/Address: \([0-9.]*\).*/\1/g'|sed s/[^0-9.]//g|tail -n1)

max_days=28 # max number of days to go without forcing an update
last_update=`date +%s`

max_seconds=`expr $max_days \* 24 \* 60 \* 60`

while :; do
  current=$(wget -O - http://checkip.dyndns.org|sed s/[^0-9.]//g)

  if [ $(($last_update+$max_seconds)) -lt `date +%s` ]
  then
    # set old_ip to be different, forcing an update
     registered="0.0.0.0"
  fi

  [ "$current" != "$registered" ] && {
     wget -O /dev/null http://$USER:$PASS@members.dyndns.org/nic/update?hostname=$DOMAIN &&
     registered=$current
     last_update=`date +%s`
  }
  sleep 300
done &

In particular, the last version above does not have the correct syntax for expr (although this was hidden by the $(())), does not parse nslookup's output correctly, and most critically does not set $last_update after an update is performed.

Re: dyndns with udhcpc mini-how to

Every time I run the following in busybox on my router:
:~# nslookup www.google.com|sed 's/Address: \([0-9.]*\).*/\1/g'|sed s/[^0-9.]//g|tail -n1
(taken from the above script)

it returns a different value.  Also, the value that it is returning is not a standard IP address.  It is something like the following: 209.85.165.99209.85.165.147209.85.165.104209.85.165.103

Whenever I run the above command using my domain, it doesn't return anything.  Also, the script never updated my IP address according to my account on dyndns.org, even though I manipulated the script so that it should.  I think the line could possible by written incorrectly Any ideas from those more knowledgeable than me?

Re: dyndns with udhcpc mini-how to

Well, I'm running into a similar issue with the wget under White Russian 0.9. (Actually, I have the x-wrt version)

Anybody have a repository that has an updated version of wget?

PS: Stu, which script? If it's mine, I'm betting you are hitting the same issue with wget that I am.

42 (edited by iBooks 2007-11-21 02:56:23)

Re: dyndns with udhcpc mini-how to

Stu has the same problem that I did a few minutes ago, and only noticed now.

#!/bin/sh
#FreeDNS updater script

UPDATEURL="whatever"
DOMAIN="your domain"

registered=$(nslookup $DOMAIN|tail -n2|grep A|sed -r "s/.* ([0-9.]*) .*/\\1/")

current=$(whatsmyip ppp0)
         [ "$current" != "$registered" ] && {                           
                   wget -q -O /dev/null $UPDATEURL 
                   echo "DNS updated on:"; date
                 }

Basically, nslookup was returning something like this:

Address: 70.51.147.130 bas3-toronto01-1177785218.dsl.bell.ca

and when sed parsed it, you got

70.51.147.1303011177785218

because my hostname was showing up in the string that nslookup returns. So I changed my sed script to account for that.

Re: dyndns with udhcpc mini-how to

Ah, that's why I used the 'checkip.dyndns.org' route, seeing as how I would not know whether the wrt was immediately adjacent to the Internet-facing device or not. I think that going this way accounts for those kinds of variations more easily than trying to write scripts that are tailored to the installation. But, then agian, I'm using this to support multiple customers over varied sizes/topologies of networks.

ja

Re: dyndns with udhcpc mini-how to

http://forum.openwrt.org/viewtopic.php?id=14040 has a Kamikaze version with the script.  You can now check the IP from several sources, and it has better error handling.