Saturday, February 23, 2013

Script for updating no-ip DDNS from behind the router

no-ip is my favourite dynamic DNS service, and I was saddened by the fact that my new Cisco EPC3825 cable modem didn't support it.

I have a Linux server running, so my second option was to use that for updating the IP. All I needed was a script to do it for me, from inside the LAN of my home. Problem is, my server is in a LAN with an internal IP, while I need it to update no-ip.org with the IP address of my cable modem.

It was made possible by
1) no-ip - maybe the best free dynamic DNS?
2) ifconfig.me - an AWESOME site for figuring out your IP in linux
3) some scripting skills
4) cron


First, have an account at no-ip.org ready, so sign in and create an account if you haven't done it yet.

Install curl and wget:

apt-get install curl wget

Install also the no-ip client (more info at their help site):
cd /usr/local/src
wget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gz
tar xzf noip-duc-linux.tar.gz
cd no-ip-2.1.9
make
make install


Now, the no-ip client will ask you which hosts you want to update with the program. You need to enter your username, password, and select which of the hosts at no-ip you want to update.

Now the no-ip client is configured, we just need to give it the correct IP address.

For that we create a script somewhere, for example noipscript.sh:
nano noipscript.sh

Enter this:
#!/bin/bash
curl ifconfig.me > /tmp/current_ip
/usr/local/bin/noip2 -i `cat /tmp/current_ip`

The script will use ifconfig.me to figure out the IP of your cable modem. The IP is stored in a file current_ip. Then the no-ip client is used to update no-ip DNS to point to that IP.

Now you need to use cron to schedule this update process. 

Use "crontab -e" command to edit your crontab. Add the line:
00 *  * * * /path/to/noipscript.sh

This will update no-ip with a 1-hour interval.

Have fun!

Even better version of the script

I went a bit further and made a more secure version of the script. The problem is that the folks at ifconfig.me have the possibility of injecting malicious script into the result of "curl ifconfig.me". This way they could potentially gain control over your server. So I decided it would be best to grep the result using regular expressions, to make sure that the result is an IP address and nothing else.

Here's the updated code:

#!/bin/bash
curl ifconfig.me > /tmp/current_ip
/usr/local/bin/noip2 -i `cat /tmp/current_ip | grep '^[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}$'`

3 comments: