In some scenarios you need access to selected resources of your home network from the outside world. It may be your teenaged son running Minecraft server. It may yourself trying to access some ISOs over FTP. It may be, as in my case, your better half wanting to spy on kittens using a web cam. In any of the above answer seems to be simple: set up port forwarding. All is well and good, until your ISP assigned IP address changes. “Use dynamic DNS”, you say. But what if your router does not support this feature? Or, like in my case, supports a list of ONE (yes, it is a drop-down box of one option) dynamic DNS service, which requires paid subscription and you are not willing to pay for that? So, if connecting using IP is your only option for whatever reason, you need to tell E.T. what number to use to phone home.
Luckily for me, I have a network-connected Raspberry Pi sitting there running Linux and not doing much. If you haven’t heard of Raspberry Pi, just look it up. It is a small board with ARM processor and some I/O connectivity available. The are so many things you can do with it, but total cost of ownership makes it a perfect platform for the task at hand. It will cost you around 50 quid for the board, case and SD card to put OS on, and it will cost you close to nothing to power the box.
So, first you need a way to tell what is your public IP address. Your home router should have that information, but getting that off of the device may not be straightforward. Your best bet is an external website that will give you just that. Many of websites display that info for you, but the piece of information you are after will be wrapped up in HTML code that is bound to change at any point, so all you really want is just your public IP address in plain text. There are few websites that provide you with just that, with ifconfig.me/ip being my personal choice. Having all the information at hand, we can start coding.
#!/bin/bash ip_file="/home/pi/scripts/wan_ip/wan_ip.txt" SMTPFROMfirstname.lastname@example.org SMTPTOemail@example.com SMTPSERVER=smtp.gmail.com:587 SMTPUSER=yourusername SMTPPASS=YourPassword SUBJECT="Public IP address has changed" if [ ! -f "$ip_file" ] ; then touch "$ip_file" fi WAN_IP=`curl ifconfig.me/ip` echo "Public IP address is: $WAN_IP" while read line do if [ "$line" = "$WAN_IP" ] then echo "Public IP did not change." else echo "Public IP has changed. Writing new value..." echo "$WAN_IP" > "$ip_file" echo "Mailing the admin..." MESSAGE="Network configuration change warning! The IP address is now $WAN_IP." sendemail -f $SMTPFROM -t $SMTPTO -u $SUBJECT -m $MESSAGE -s $SMTPSERVER -xu $SMTPUSER -xp $SMTPPASS -o tls=yes fi done < "$ip_file"
First of all, we need an e-mail account to send the information from. There are some other methods of sending e-mails, but we want to send it using “proper” account so it doesn’t get filtered out by anti-spam systems. Lines 4 through to 10 define some variables that seem to be self-explanatory. If you are intending to use different e-mail to gmail, check with your mail service provider for relevant settings. Don’t forget to include port number in server’s FQDN and enable TLS if your account supports it.
Next, the actual processing begins. In lines 12-14 we cover our basics by checking if a temp file where we are going to store our IP address exists. If it doesn’t we use touch command to create the file. Next we use curl to download plain text file containing our public IP address. Having that information at hand, we go through our temp file line by line (the whole one line) and compare it with current IP address. If they match, there is nothing to be done and we can exit the script. However, if there is a miss-match we first write new IP address back to our file (line 27) and then use sendmail (line 30) to notify mail recipient of the change.
OK, we have the script, but now we need a way to periodically check if anything has changed. We can easily achieve that using cron, a UNIX job scheduler. Execute following command to start editing cron job table.
Next, edit the table according to your preference. You can find a useful guide on editing cron table here: http://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/. Since my application is not time critical, I have decided to run my job every three hours at 17-th minute of that hour. My task ends with >/dev/null 2>&1, which basically sends all output and errors of my script into the void.
17 */3 * * * /home/pi/scripts/wan_ip/wan_ip_check.sh >/dev/null 2>&1
I hope the above gave you a general idea on how you can use described methods to your advantage. Of course you need to be careful when using this script – you are saving your e-mail password in plain text, so make sure you have assigned correct access rights to the script, but securing that is beyond the scope of this post.