OpenDNS Dynamic IP Update Script through Linux

I recently read a blog post on the How-To Geek about setting up OpenDNS and the options it gives you to secure your internet browsing. They have quite a few filtering options including Phishing sites, along with blocking adult-related sites, and about 50 other categories along with a fully redundant DNS nameserver resolving. I decided to try it and set it up on my home network. The problem is that if you have an internet provider that provides you with a dynamic IP (IP address changes occasionally, if you aren’t sure what you have you probably have a dynamic address), you need to update the IP with OpenDNS. They have a lot of clients out there to do it, but as far as I found there were no linux clients. So I created a short linux script to do just that.

[lang=’bash’]#!/bin/bash

# Copyright (C) 2006 Jeremy Brent Hansen
#
# These are for your OpenDNS username and password. At this time, I do
# not know how to hide this info, so you will need to make sure you have the
# correct file permissions.
username=your_opendns_username
passwd=your_opendns_password

# This is where the log file will be stored. Currently it only logs the current IP
# and the response back from OpenDNS. The log will keep one backup. I
# just used a folder in my home directory (make sure the folder exists).
log_dir=~/.opendns

# Revolves the log file. Keeps one backup.
mv $log_dir/log $log_dir/log.1

while [ 1 ]
do

date >> $log_dir/log
/usr/bin/curl -i -m 60 -k -u $username:$passwd ‘https://updates.opendns.com/account/ddns.php?’ -silent >> $log_dir/log
echo -e “\n” >> $log_dir/log

# Resends the info after 5 minutes. Eventually I plan on changing it,

# so it only updates when your IP changes.
sleep 600

done[/lang]

So, there you have it. No root permissions are required, so I just have it in my .profile for my normal user. Just run it with the & at the end, so it will background the process.

31 thoughts on “OpenDNS Dynamic IP Update Script through Linux

  1. This looks great! I was thinking it would be really nice to get this script to work under DD-WRT, but I noticed that /usr/bin/curl doesn’t exist (in v23 SP2 std). So I tried a little google and found this nice info from the DD-WRT folks:

    http://www.dd-wrt.com/wiki/index.php/OpenDNS

    It also discusses the port 53 blocking required to prevent intelligent users from using another DNS, which is slightly different from your description in that it blocks both TCP and UDP, and instead of “Run Commands” they state you should use “Save Firewall” from within the web GUI.

    Of course none of this should prevent someone from just typing in the IP address of a site they want to visit, which isn’t too hard to find, so this doesn’t really block access to those sites.

    -Brian

  2. That is some great information. Thanks Brian.

    As far as blocking port 53, the command I used in the other post blocks both TCP and UDP. They are two separate commands separated but a semi-colon. In linux this allows you to run two commands one after the other. And as far as running the commands vs saving the firewall, I am not too sure what the difference is. I know that once you run my command it puts it into the firewall list, but I am not positive that list is persistent. I will need to look into that. Also I will have to check on the difference between the commands that opendns uses vs the ones I put up.

  3. Great work. If I didn’t find this I’d have to mess with ODNS API. Thanx alot.

    What I don’t understand is the way you feed new IP. I guess the URL we talk just check our IP and update if it’s any different with previous one. But in ODNS API it was quite a bit of stuff to be done. Hope this is a clever hack. I’m planning to change the script to update IP everytime I log in to network (I use HSDPA broadband).

  4. I have been using this since I posted it without any issues.

    As far as passing the IP, I don’t. The page will get it automagically (really easy in PHP). Then it just uses your username and password to login.

    @Brian, I don’t realize why I didn’t notice this the first time you wrote it, but this script should not be run on the router. Which is why you couldn’t find /usr/bin/curl, it is supposed to be run on a linux based computer. AFAIK curl is a pretty standard library that most distros should include.

  5. when I run the script I get this error:

    bash: ./odp: /bin/bash^M: bad interpreter: No such file or directory

  6. Hello, I was looking around for a while searching for linux scripts and I happened upon this site and your post regarding Dynamic IP Update Script through Linux | bassmadrigal’s blog, I will definitely this to my linux scripts bookmarks!

  7. OK, I found out this might be because I typed up the script in windows. So it is using the windows carriage return. Depending on your distro you should be able to run a program that will switch the carriage return.

    On most distros it is

    dos2unix filename #(where you replace filename with odp)

    but slackware calls the file fromdos, so the command for Slackware would be

    fromdos odp

    I am going to re paste the script later today, so hopefully future people won’t run into the same problem as you.

  8. I installed dos2unix package and
    I did like you said

    dos2unix odp

    I don’t think it is working
    how we can say it’s working or not without checking any restricted web site by opendns.

    “# Resends the info after 5 minutes. Eventually I plan on changing it,

    # so it only updates when your IP changes.
    sleep 600”

    you say 5 minutes isn’t “sleep 600” means 10 minutes.

    and how we can stop the script or restart

    and can we change sleep value to anything we wish?

  9. In your log file it should show the current date, then on a new line it should show good followed by your IP address.

    So it should show

    Sun Dec 14 07:05:38 CET 2008
    good 80.148.100.200
    

    To determine that things are setup properly just head to http://welcome.opendns.com/ and make sure it says you are using opendns.

    And yes, I guess I should have proof read my script better, 600 is actually 10 minutes. I also could have worked more functionality into the script, but currently the only way to stop the script is to kill it specifically. If you didn’t run it in the background you would just Ctrl+C. If you put the & after it, you would actually have to kill the process. Currently the script is very basic. I have thought of other things to add to the script, but I currently haven’t found the time to work through them.

  10. no, it doesnt show that date and ip lines, it just shows that:

    [brk@localhost ~]$ dos2unix odp
    [brk@localhost ~]$

    but when I just run this commnad line:

    /usr/bin/curl -m 60 -k -u : ‘https://updates.opendns.com/account/ddns.php?’

    I got this:

    good 88.107.177.48[brk@localhost ~]$

    so this command line is working but not your script for me.

    one other thing.you say:

    “To determine that things are setup properly just head to http://welcome.opendns.com/ and make sure it says you are using opendns”

    I thought it just says we use opendns. it doesn’t say we updated our new ip.

  11. That dos2unix is just to convert the carriage returns from a windows style to linux style. And you only need to do that once.

    You will still need to run the script separately. Then you should check the log file to make sure that it is working properly.

    And with the http://welcome.opendns.com I believe it should show you the correct ip on the top right, although the network I am using doesn’t have opendns setup and I won’t be home until the end of the week to verify it.

  12. Hey Jeremy, Thanks for this…Works Brilliant!

    As a tip for some users, you could remove the while loop, and keep the script in /etc/cron.hourly 🙂

    Smaller Script….

    #!/bin/bash
    username=username
    passwd=password
    log_dir=/home/some_user/.opendns
    mv $log_dir/log $log_dir/log.1
    date >> $log_dir/log
    /usr/bin/curl -i -m 60 -k -u $username:$passwd 'https://updates.opendns.com/account/ddns.php?' -silent >> $log_dir/log
    echo -e "\n" >> $log_dir/log

  13. @Nick Yes, you can cut out the while loop, but the problem that I see is that if your IP changes at 1 minute past the hour mark, then you have to wait 59 minutes for it to be updated through opendns. I actually planned on working on this again to have it check to see if the external ip changes and only then have it contact opendns, but my current project is taking too much time as it is. Hopefully I can get to it in the near future.

  14. Pingback: links for 2009-02-09 - [LINICKX].com

  15. Hi Jeremy…. Something like this ok?

    #!/bin/bash
    IPFILEPATH="/home/me"
    # Do we have a record of our IP address
    if [ -e $IPFILEPATH/myip.txt ]
    then
    
            # Get our Old IP
            OLDIP=`cat $IPFILEPATH/myip.txt`
            # What is our IP Now?
            wget -q -O $IPFILEPATH/myip_new.txt http://nst.sourceforge.net/nst/tools/ip.php
            NEWIP=`cat $IPFILEPATH/myip_new.txt`
    
            if [ $OLDIP != $NEWIP ]
            then
                    echo "different"
                    rm -f $IPFILEPATH/myip.txt
                    mv $IPFILEPATH/myip_new.txt $IPFILEPATH/myip.txt
                    # INSERT OpenDNS Stuff here.....
            else
                    rm -f $IPFILEPATH/myip_new.txt
            fi
    
    
    else
    # No record of IP... grab it
            wget -q -O $IPFILEPATH/myip.txt http://nst.sourceforge.net/nst/tools/ip.php
    fi
    
    
  16. I was thinking more with variables. I hate using temp files. I still want to figure out something for the logfile because it will get extremely long depending on how long your computer stays running.

    So I was thinking more like this (I omitted the logfile portion).

    #!/bin/bash
    
    username=your_opendns_username
    passwd=your_opendns_password
    
    while [1]
    do
      if [ -z $oldip ]
      then
      oldip=`/usr/bin/curl http://nst.sourceforge.net/nst/tools/ip.php -silent -i`
      fi
      
      newip=`/usr/bin/curl http://nst.sourceforge.net/nst/tools/ip.php -silent -i`
      
      if [ $oldip != $newip ]
      then
        /usr/bin/curl -i -m 60 -k -u $username:$passwd 'https://updates.opendns.com/account/ddns.php?' -silent
      fi
      
      sleep 500
    done
    
  17. Nick and Jeremy,

    I have a question, I want to put a script in the cron.hourly location, will the script with the While loop work there??

    What about File permissions? How must those be set up?

    Thanks for your help.

  18. The while loop will work, but then it would be pointless to put it in the cron, because it will run automatically every 500 seconds (or different if you change the sleep).

    In Nick’s example it will use temporary files, which I personally try to shy away from. But this script does not need root permission, so you should be able to just run it as a normal user.

  19. Just a pair of corrections in the script (commented):

    #!/bin/bash
     
    username=your_opendns_username
    passwd=your_opendns_password
     
    while [1]
    do
      if [ -z $oldip ] # spaces inside the brackets
      then
      oldip=`/usr/bin/curl http://nst.sourceforge.net/nst/tools/ip.php -silent -i`
      fi
     
      newip=`/usr/bin/curl http://nst.sourceforge.net/nst/tools/ip.php -silent -i` # no $ sign before newip
     
      if [ $oldip != $newip ]
      then
        /usr/bin/curl -i -m 60 -k -u $username:$passwd 'https://updates.opendns.com/account/ddns.php?' -silent >> $log_dir/log
      fi
     
      sleep 500
    done
    
  20. Thanks Sergi, it had been a while since I did bash programming, and I had PHP stuck in my mind. I went and edited my last post.

  21. Responding to this thread a little late, but wanted to post a message regarding the bash script above.. Seems to me that Sergi has the best approach, but unless we put the new IP in the ‘$oldip’ variable when the IP changes, ‘$oldip != $newip’ will always be true and will send an update on every loop. I have updated the code and re-added the log for anyone interested.

    #!/bin/bash
    
    username=your_opendns_username
    passwd=your_opendns_password
    log_dir=/home/some_user_dir/.opendns
    
    if [ ! -d $log_dir ]; then
      mkdir $log_dir
    fi
    
    if [ -e $log_dir/log ]; then
      mv $log_dir/log $log_dir/log.1
    fi
    
    date >> $log_dir/log
    
    oldip=`/usr/bin/curl http://nst.sourceforge.net/nst/tools/ip.php -silent -i`
    
    while [ 1 ]
    do
    
      newip=`/usr/bin/curl http://nst.sourceforge.net/nst/tools/ip.php -silent -i`
     
      if [ $oldip != $newip ]
      then
        /usr/bin/curl -i -m 60 -k -u $username:$passwd 'https://updates.opendns.com/account/ddns.php?' -silent >> $log_dir/log
        echo -e "\n" >> $log_dir/log
        $oldip = $newip
      fi
     
      sleep 60
    
    done
    
    
    

    -Beach

  22. That is a really good point. I didn’t think about it after the IP had changed. And I edited your post to reflect the greater than symbols. Sometimes I hate the whole WYSIWYG, but I haven’t found anything better for displaying code in wordpress.

  23. Hey, folks! Wow, this is great, thanks for your contributions! Especially since openDNS doesn’t have anything of the sort (which, like how really simple is this).

    A couple of thoughts … I do like having a “current status” file (maybe in /tmp, /var/tmp, or even /dev/shm which is in RAM.) As far as an ongoing log file, I’m not a fan of that, unless I’m trying to track exactly how often my IP changes.

    Without posting code, all I did was to grab my public IP from sourceforge, and compare it to /var/public_ip … If that file does not exist, create it. If it does exist, and it matches my current IP, then exit. Otherwise poll the update openDNS update URL, and if successful, exit.

    — Nate

  24. edit … last line should read:

    Otherwise write the new IP to /var/public_ip (overwriting, not appending), poll the update openDNS update URL, and if successful, exit.

  25. hi Jeremy,
    I’m new to OpenDNS filtering and this is awesome service, wish I knew about this earlier.

    Find this post from your comment(s) on OpenDNS forum first…and since I’m running Jaunty full-time at home
    ,my search for an desktop updater led me to “ddclient” and “Inadyn”, I installed both.

    so my question is….is the purpose of your script here basically the same as those 2 ready-made packages ?

    thanks

Leave a Reply

Your email address will not be published. Required fields are marked *