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 Comments

  1. Brian says:

    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. Jeremy says:

    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. chanux says:

    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. Jeremy says:

    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. minyeli says:

    when I run the script I get this error:

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

  6. Jeremy says:

    What is the command you are using to run it?? Because I don’t see why it wouldn’t work.

  7. Daniel Craig says:

    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!

  8. minyeli says:

    I use:
    ./filename

  9. minyeli says:

    so I named it “odp”
    ./odp
    is my command

  10. Jeremy says:

    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.

  11. minyeli says:

    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?

  12. Jeremy says:

    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.

  13. minyeli says:

    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.

  14. Jeremy says:

    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.

  15. minyeli says:

    ok now it is working, log file shows date an ip as you said.
    but http://welcome.opendns.com doesn’t show my ip, just says I’m using opendns.

  16. Nick says:

    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

  17. Jeremy says:

    @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.

  18. links for 2009-02-09 - [LINICKX].com says:

    [...] OpenDNS Dynamic IP Update Script through Linux | bassmadrigal's blog 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. (tags: security linux dns bash scripts opendns) [...]

  19. Nick says:

    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
  20. Jeremy says:

    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
  21. Jeff says:

    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.

  22. Jeremy says:

    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.

  23. Sergi says:

    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
    
  24. Jeremy says:

    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.

  25. Beach says:

    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

  26. Beach says:

    The code tags above changed the actual code above, please replace ‘>>’ with ‘>>’

    -Beach

  27. Jeremy says:

    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.

  28. Quincie says:

    Thanks for the awesome post, it helped me out a lot.

  29. Arfy says:

    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

  30. Arfy says:

    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.

  31. Robert says:

    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

XHTML: To type code in the comments use <pre lang=""> </pre>. Supported languages can be found here.