Part 4. How to handle a dynamic IP address

My ISP gives out dynamic IP addresses. This means that my IP address will change periodically, notably if there is any problem with the connection, my router/modem disconnects, or if I have a power failure. It may also change for no obvious reason. Since I am not paying for a static IP address and I am not paying for and hosting a domain name from home, I have to be able to find out my home IP address from wherever I am travelling. This involves having my home IP address posted to a webpage that I can access from anywhere on the internet.

I have tried three free solutions to this problem:

  1. Use a service like DynDns.org. My problem is that this is not always reliable. I have had all sorts of trouble connecting to DynDns and getting my home IP. It was incredibly slow when it did work. I figured that I could do it better by myself and I did.
  2. Use CGI scripts to update the webpage (This one is the best option!)
  3. Use email to update the webpage

Finally, there is 4.: a script for a Windows XP laptop to automatically find your home server's IP address and connect to it.

Note: methods 2 and 3 assume that you have a website or part of one that you can control (e.g. henceforth referred to as "mysite.com"). We will set things up so that your home linux server automatically contacts this website if your home IP address has changed. In both cases a file called "myip.num", which has your home IP address, is updated. This file is used for scripts that automate connecting to your home server from anywhere (so you don't have to manually look up the IP number from myip.num and type it into putty). It also enables you to always find out what your home IP address is when you're not at home. Part 5 will explain how to automatically retreive this and set up tunnels.


Solution 2 in detail (updating webpage via CGI scripts)

You must be able to upload your own CGI scripts, written in Perl or PHP. I have done this example using Perl. You may also have to specify a particular directory to upload them into (eg. /cgi-bin)

Steps: Set up Fishuntu (your home Linux server)to
(i) find its current IP address,
(ii) access a special hidden webpage on mysite.com to update the webpage that holds Fishuntu's IP address (i.e. your home IP address).

Create and upload the following files to your webpage (which I am calling "mysite.com). The exact location will depend on your webhosting service. Most companies require these scripts to be put into a folder called cgi-bin.

On mysite.com, put the following script into a file called myip.shtml
(What this does is to pop up a webpage that displays the IP address you are using. It displays nothing else.)

<html><head></head><body> <!--#echo var="REMOTE_ADDR" --> </body></html>

On mysite.com upload the following lines into saveIP.pl
What this does is to (i) save your home IP address to the file myip.num, and (ii) display your IP address on the screen. Keep this filename private. If anyone else browses to it, it will save their IP address instead of the one from your home server.

#!/usr/bin/perl use CGI qw/:standard/; use CGI::Carp qw(fatalsToBrowser); # #note: you may have to change the path to myip.num depending where it is open FILE, ">myip.num" or die $!; print FILE $ENV{REMOTE_ADDR}; close FILE; print <<EOF; Content-Type: text/html <HTML> <HEAD> </HEAD> <BODY> $ENV{REMOTE_ADDR} </BODY> </HTML> EOF

Upload the following lines to mysite.com into updateIP.pl
What this does is update the file myip.txt (appending the current IP to it). Again, this URL must be kept private. Using "updateIP.pl" is optional; it is not needed for the scripts to work properly.

#!/usr/bin/perl use CGI qw/:standard/; use CGI::Carp qw(fatalsToBrowser); # #note: you may have to change the path to myip.txt depending where it is in your folders open FILE, ">>myip.txt" or die $!; $ddd=`date`; #print $ENV{REMOTE_ADDR}; chomp($ddd); $str=$ddd."\t\t".$ENV{REMOTE_ADDR}."\n"; print FILE $str; close FILE; print <<EOF; Content-Type: text/html <HTML> <HEAD> <TITLE>Hello World</TITLE> </HEAD> <BODY> <H4>Hello World</H4> <P> Your IP Address is $ENV{REMOTE_ADDR} <P> <H5>Have a "nice" day</H5> <p>Name:<input type="text" size="20" name="txt_name" value="name"> </BODY> </HTML> EOF

Set the correct permissions on the two cgi files:
chmod 755 saveIP.pl
chmod 755 updateIP.pl

On mysite.com make put the following text into a file called myip.txt

The correct, working IP address is the LAST one in this list. The port number will not change. **************************************************************

Put the following scripts on your home linux server, Fishbuntu.

On your server, Fishbuntu, put the following into a file called mycrontab

#update IP on remote server as well as store a copy here 9 * * * * lynx -dump http://mysite.com/cgi-bin/saveIP.pl > $HOME/scripts/newip #see if the IP address has been changed, if so, update the log on the server 12 * * * * $HOME/scripts/ip_script

Next type: "crontab mycrontab". Check this by typing "crontab -l"

What this does is to run the saveIP.pl script every hour at 9 minutes past the hour. (I used to call myip.shtml instead of saveIP.pl .) Another way of doing it would be to just get the lastest correct IP from mysite.com/myip.num and comparing it to your current IP address. If it has changed then the server IP needs to be updated.

* You will have to install lynx or wget on your server Fishbuntu for this to work.

On your server, Fishbuntu, now create/edit a file called ip_script so that it looks like this.
Then set the correct permissions: chmod 744 ip_script

#!/bin/sh #check for unintialed parameters set -u WORKDIR=$HOME/scripts # Compare the files: newip and oldip and act accordingly if [ ! -f $WORKDIR/newip ]; then echo "newip doesn't exist" exit fi # Get the stored IP addresses OLDIP=$(cat $WORKDIR/oldip) NEWIP=$(grep \. $WORKDIR/newip) #this is supposed to strip whitespace. # x=${x#"${x%%[! ]*}"} #or #read x <<< $x #this will strip whitespace as there are no quotes echo $NEWIP > $WORKDIR/newip #good programming to put all filename variables inside double quote #(in case there are spaces in them) #but then I have whitespace mismatches if [ $NEWIP = $OLDIP ]; then # echo "no change to ip" exit fi #copy new ip to old ip echo $NEWIP > $WORKDIR/oldip # now update local IP listing with newip echo `date +%c` "\t\t${NEWIP}" >> $WORKDIR/myip.txt #call the perl script to update the online file lynx -dump http://mysite.com/cgi-bin/updateIP.pl > /dev/null

At this point, everything should be working. I don't think that I have left out any steps. Perhaps the file permissions need to be set correctly on the cgi scripts on the server.

You can test things by going to the following webpages :

http://mysite.com/myip.shtml
http://mysite.com/myip.num
http://mysite.com/myip.txt
http://mysite.com/saveIP.pl
http://mysite.com/updateIP.pl
and then myip.num and myip.txt again


Solution 3 in detail (updating webpage via email)

Steps: Set up Fishuntu to
(i) find its current IP address,
(ii) email this address to mysite.com,
(iii) set up mysite.com to process this email and add it to a special webpage.

On mysite.com, put the following script into a file called myip.shtml
(What this does is to pop up a webpage that displays the IP address you are using. It displays nothing else.)
<html><head></head><body> <!--#echo var="REMOTE_ADDR" --> </body></html>
On your server, Fishbuntu, put the following into a file called mycrontab
#Extract IP from website (i.e. find current IP address) 0,30 * * * * lynx -dump http://mysite.com/myip.shtml > $HOME/scripts/newip #email IP address to mysite.com 15,45 * * * * $HOME/scripts/ip_emailer #20,50 * * * * $HOME/scripts/ipnum_check

Next type: "crontab mycrontab". Check this by typing "crontab -l"

What this does is to (i) get the current IP address at 0 and 30 minutes part the hour, then (ii) run the sip_emailer script at 15 and 45 minutes past the hour.
(iii) 5 minutes after the email has been sent, ipnum_check is run to make sure that the email got through. You probably don't need to do this. Using CGI scripts is actually more robust and less likely to screw up.
* You will have to install lynx or wget on your server fishbuntu for this to work.

Now paste the following into a file called ip_emailer (in $HOME/scripts)
#!/bin/sh #check for unintialed parameters set -u # WORKDIR=$HOME/scripts #clear log file and then timestamp it #rm $WORKDIR/script_log #touch $WORKDIR/script_log echo `date` > $WORKDIR/script_log # check for existence of newip if [ ! -f $WORKDIR/newip ]; then echo "newip doesn't exist" >> $WORKDIR/script_log exit fi # Get the stored IP addresses OLDIP=$(cat $WORKDIR/oldip) NEWIP=$(grep \. $WORKDIR/newip) #this will strip whitespace as there are no quotes echo $NEWIP > $WORKDIR/newip #get a clean copy of NEWIP (needed for the email address below NEWIP=$(grep \. $WORKDIR/newip) #good programming to put all filename variables inside double quote (in case there are spaces in them) #but then I have whitespace mismatches if [ $NEWIP = $OLDIP ]; then echo "no change to ip" >> $WORKDIR/script_log exit fi #copy new ip to old ip echo $NEWIP > $WORKDIR/oldip # now update webpage with newip #use {} to isolate variable from the rest of the text echo `date +%c` "\t\t${NEWIP}" >> $WORKDIR/myip.txt #remove old period (from the very last line) grep -v "^\.$" $WORKDIR/myip.txt > $WORKDIR/myip.txt_2 mv $WORKDIR/myip.txt_2 $WORKDIR/myip.txt #add a period to indicate end of email message for sendmail echo '.' >> $WORKDIR/myip.txt # new send email ... echo "uploading IP email" >> $WORKDIR/script_log #build text string and send email SUBJ="-s IP_updater_${NEWIP}" ADDR="abcde@mysite.com -c abcde@mysite.com" /usr/bin/mail $SUBJ $ADDR < $WORKDIR/myip.txt
If you want to run ipnum_check, here it is:
#!/bin/bash # script to check if myip.num on mysite.com is empty # I imagine that this is because NEWIP has spaces before it sometimes # and this means that the spaces get sent to mysite.com via email, instead of the # IP address. It is not actually checking to see if myip.shtml can be accessed. wget -q mysite.com/myip.num -O myip.num BYTES=`wc -c myip.num | cut -b 1,2` #echo $BYTES bytes if [ $BYTES -gt 8 ]; then # echo "exiting" exit fi #echo "less than 8" echo 999 > $HOME/scripts/oldip $HOME/scripts/ip_emailer
Now on mysite.com you need to set up the email processing programs.
In the file called .forward, put the following line:
|/exec /usr/bin/procmail
This will send all of your email to the procmail processing program.
In the file called .procmailrc put the following lines:
#send IP_updater email to the correct file :0: * ^Subject.*IP_updater* | $HOME/scripts/IP_mail
# everything else goes to mysite.com account :0: * ! abcde@mysite.com
Now you have to create the email handling program IP_mail (in $HOME/scripts). This will get the whole "myip.txt" which was emailed to mysite.com and replace the old file.
It will also take the IP address which was in the subject line and save it as a webpage in myip.num.
You can use either of these files to find your home IP address.
#!/bin/bash #check for unintialled parameters set -u #go to correct directory; make a backup file cd $HOME/public_html mv myip.txt myip.txt.bak #copy input to file cat 1> myip.txt chmod 644 myip.txt #now extract the IP address from the subject line and save to another file NEWIP=`grep IP_updater $HOME/public_html/myip.txt | sed "s/[^0-9.]//g"` echo ${NEWIP} > $HOME/public_html/myip.num chmod 644 $HOME/public_html/myip.num

Automating a your laptop's connection to your home linux server

1. Install AutoIt on your laptop.