Finding my computer at home from the outside.

By Mark Nielsen

  1. Introduction
  2. Perl script uploading ip address.
  3. Webpage and perl script on remote computer.
  4. Cron job I run in the background.
  5. Conclusion
  6. References

Introduction

The purpose of this article is to make it so I can find my computer at home when I am traveling around the Bay Area doing computer work, recruiting, and volunteer work. Most of the time, I am busy traveling around, although I am able to work from home half the time now. My computer at home uses a Ricochet modem. The dumb people who promised me a good DSL connection and a satellite connection where I live were a bunch of morons. The max DSL I could get would be 144k (which I found out AFTER I moved in), which is pointless when I already have a Ricochet modem at 128k. Plus, I am facing the wrong way for a satellite connection. Whatever you do, make sure the morons who sell you their apartments have it in the contract that you are promised certain speed connections to the internet, or you can break the contract with no penalty. As soon as it is worth, I am moving. For now, I am stuck with a dial-up connection, which isn't bad most of the time.

Some people can have static DSL connections, which takes of the problem I have, which is my ip address to the internet changes each time I dial up. I used to email myself the ip address, parse out the data, and put it on a webpage. I have a better solution now. I use ssh to transfer a file to my remote webserver once an hour.

Setting up ssh.

The version of ssh I am using is 1.2.27. I should be using OpenSSH, but for now, I am using commercial ssh.

We need to make it so we can transfer files securely from my computer at home to the remote computer. We use the ssh-keygen program (which comes with ssh). Here is a paragraph from the manpage for ssh.

       Ssh  implements  the RSA authentication protocol automati­
       cally.  The user creates his/her RSA key pair  by  running
       ssh-keygen(1).   This stores the private key in .ssh/iden­
       tity and the public key in .ssh/identity.pub in the user's
       home  directory.   The  user  should  then  copy the iden­
       tity.pub to .ssh/authorized_keys in his/her home directory
       on  the  remote  machine  (the authorized_keys file corre­
       sponds to the conventional .rhosts file, and has  one  key
       per line, though the lines can be very long).  After this,
       the user can log in  without  giving  the  password.   RSA
       authentication is much more secure than rhosts authentica­
       tion.
So I ran "ssh-keygen" as a user on my computer at home. Then I transferred the ".ssh/identity.pub" file on my computer at home to the remote computer as ".ssh/authorized_keys" for the user "web1" on the remote computer. This makes it so I can login in from home to my remote computer without having to use a password. This can also be used to transfer files.
rsync -e ssh -av /home/test1/IP.txt web1@somecomputer.com:public_html/IP.txt

Perl script uploading ip address.

Here is the perl script I use to upload the ip address. You should change values of the usernames and remote computer address. You can also get the perl script here.
#!/usr/bin/perl

use strict;

  ### Run ifconfig and store the data in the @Temp list. 
my @Temp = `/sbin/ifconfig`;

  #### Search for ppp
my $Search = "ppp";
  ### If you are looking for the ip address of your ethernet card, 
  ### uncomment the next line;
# $Search = "eth0";

  ### Make the line we find the ip address blank initially.
my $Match_Line = "";
my $Match_Device = "no";

  ## Search through the lines, if we find a match, save the lines until
  ## we find a blank line. 

foreach my $Line (@Temp)
  {
    ### If we have a match, abort. 
  if ($Match_Line ne "")   {@Temp = ();}
    ### else, see if we can find a match at the beginning of line;
  elsif ($Line =~ /^$Search/) {$Match_Device = "yes";}
    ### else, if we found the device, and we find the line we are looking for
  elsif (($Match_Device eq "yes") && ($Line =~ /^ +inet/)) 
    {$Match_Line = $Line;}  
  }

  ## If our $Match_Line is not blank, split it and get the ip address.
my $IP = "";
if ($Match_Line ne "") 
   {
    ### Get rid of stuff before addr:
   my ($Junk,$Good) = split(/addr\:/, $Match_Line,2);
    ### Get rid of stuff after the first space
   my ($Good,$Junk) = split(/ /, $Good,2);
   $IP = $Good;
   }

  ## If $IP is not blank, we have something. Save to file and transfer file
  ## to remote site. 
  ### Please don't use the /tmp to store this file, but some other location.
if ($IP ne "")
  {  
  open(FILE,">/tmp/IP.txt");
  print FILE "$IP\n";
  close FILE;
  system ('rsync -av -e ssh /tmp/IP.txt web1@somecomputer.com:public_html/IP.txt');
  }
   ### Else, we should send ourselves an email, or do something
   ### to let us know it didn't work. This is left as an exercise.
else {}

Webpage and perl script on remote computer.

On the remote computer are storing the ip address, we need to detect if it is an hour old. If it is less than an hour old, we should print out an error message. So I use this perl script. I name it "/home/web1/public_html/IP.pl".

You may want to consider moving this perl script into the normal cgi-bin directory of your webserver. Otherwise, here is a dangerous example of how to make it so you can run perl scripts from a users directory. THIS IS DANGEROUS! If your web server allows any user to execute a perl script, that person can get the webserver to do anything they want.

To make it so you can execute perl scripts on your webserver,


<Directory /home/*/public_html>
   ## Options All is reduntant with some of the other options. 
    Options All Indexes FollowSymLinks MultiViews ExecCGI Includes 
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

   #### This requires several perl apache modules
 <Files *.pl>
 SetHandler perl-script
 PerlHandler Apache::OutputChain Apache::SSIChain Apache::Registry 
 PerlSendHeader On
 Options ExecCGI
 </Files>
And for the perl script,
#!/usr/bin/perl

use strict;

print "Content-type: text/html\n\n\n\n";

my $File = "/home/web1/public_html/IP.txt";
open(FILE,"/home/web1/public_html/IP.txt");
my $Line = <FILE>;
chomp $Line;
close FILE;

my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
   $atime,$mtime,$ctime,$blksize,$blocks)
     = stat($File);
my $time = time();

print "<br> Last known ip address was $Line\n";
print qq(<br> To transfer to the website, 
     <a href="http://$Line">click here</a>\n);

my $Diff = $time - $mtime;
if ($Diff > 4000) 
  {
  print "<p>ERROR: The ip address should have been updated once an hour, 
  but 4000 seconds has past since the last update.
  <br> $time - $mtime = $Diff \n";
  }

The Cron Script to make it run nightly

Not the best crontab file, but it will do.
#/bin/sh

### Crontab file
### Name the file "Crontab" and execute with "crontab Crontab"
### Or, you can edit the current crontab with 'crontab -e' and then put
### the lines below in it -- which is safer. 

  ### Download every two hours
1 * * * *   /www/Cron/Remote_Website.pl >> /www/Cron/out  2>&1  

Conclusion

I know people are probably doing the same thing in different ways. I like this solution because the files are transferred securely. This makes it so people can't see what I am transferring over the internet. So that nobody can get to the file, we should password protect the webpage and perl script that display the ip address.

Thanks for Mike Orr for suggestions!

References

  1. ssh
  2. OpenSSH
  3. Apache
  4. If this article changes, it will be available here http://www.gnujobs.com/Articles/17/Remote_Website.html

Mark works as an independent consultant donating time to causes like GNUJobs.com, writing articles, writing free software, and working as a volunteer at eastmont.net.

Copyright © 3/2001 Mark Nielsen
Article