Be Your Own DDNS Service Using PHP

by glider

The Problem

You want to set up a darknet for a few friends, and so you need to be able to give them a static IP address.

Of course, your ISP switches your Internet-accessible IP address randomly and gives you a relatively useless dynamic IP.  Yes, you can find a Dynamic DNS service which allows you to update a domain name as often as your ISP changes your IP, but either I picked a bad DDNS service or a lot of people have the same problem: more often than not, the domain name I had been given would timeout, leaving my friends disconnected.

That's when I cobbled together a quick personal DDNS service, using less than 50 lines of code, most of which are PHP.

The Ingredients

To make this work, you'll need your own domain or web page with FTP access and PHP.

You also need the ability to run PHP on your home machine.  Finally, you need a command-line FTP utility on your home machine, such as the one included with Windows XP.  I set my service up under Windows XP, running PHP under XAMPP.

Getting Your IP

This is the whole code of the PHP page you'll place somewhere on your domain, to sniff your IP:

ip.php:

<?php
$ip = $HTTP_SERVER_VARS["REMOTE_ADDR"];
echo $ip;
?>

If you hit that page using a web browser, you'll get your current Internet-accessible IP as the result.

Sharing Your IP

This is the main bit of coding; it's also in PHP.

In a nutshell, the script goes out to your page on the web, which returns your current IP.  I chose to output this to a file on my home machine, then upload the file, which contains nothing but my IP, to my web server.  I could have written the code on my server to log my IP when I hit the page, but the danger there is that some web robot, spider, or casual surfer might trip the page, writing the wrong IP address to the file.

Anyway, here's the magic:

sendip.php:

<?php
$url = "http://www.your-domain.com/ip.php";
// this is the page on the web that returns your IP
$fn = "C:\ip.txt";
// this is the file that you'll write your IP to
$cmd = "ftp -s:E:\ipup.txt";
// this is the command-line call to the FTP program

// comment this out, if running invisibly
echo "Getting IP from $url...";

// open the web page and nab the IP
$fp = fopen($url,"r") or die;
$data = fread($fp, 4096);
fclose($fp);

// write the IP to the file for upload
// open for overwriting
$fnew = fopen($fn,"w+") or die;

// comment this out, if running invisibly
echo "Writing $data to local file...";

if (is_writable($fn))
	{
	if (!$handle = fopen($fn, 'wb'))
		{
        exit;
		}
    if (fwrite($handle, $data) === FALSE)
		{
        exit;
		}
    fclose($handle);
	}

shell_exec($cmd);
// this executes the FTP command that uploads the file you just wrote
// comment this out, if running invisibly
echo "FTP-ing $data to your-domain...";
?>

Updating Your IP: The FTP Call

This part may be different for some people.

This is the code in a text file that tells the FTP utility what to do.  This file is called ipup.txt in the $cmd variable above.

The lines that start with quote are commands to your FTP server once you're connected.  To find the exact wording, I used the FireFTP plugin for Firefox, copied a file over to my domain, and took the commands from its log.

open www.your-domain.com
username
password
quote CWD /your-domain.com/new-directory
quote TYPE A
quote PASV
put C:\ip.txt
close
quit

The CWD command is just to change the directory once connected, so that my IP file gets saved somewhere other than the root directory of my domain.

Updating Your IP: The Service

So far, so easy.

The problem is that you'd have to call the main PHP script every time you want to update your IP.  Instead, you can schedule it as a "Scheduled Task" in Windows to run all day, every day, every 15 minutes.  It's as simple as writing a one-line batch file:

Write this into sendip.bat:

C:\xampp\php\php.exe C:\sendip.php

You then schedule the task to run that "program" every 15 minutes.

The only problem is making the task run invisibly without having to go in and edit the Registry to set it up as a bona-fide service.  The way it's set up now, the task will run, but a shell window will pop-up every time it does so.  It's only there for a few seconds, but it's really annoying every 15 minutes.  To make it run invisibly, you need to run it using wscript, the Windows scripting language.

Write this into invisible.vbs:

CreateObject("Wscript.Shell").Run """" & WScript.Arguments(0) & """", 0, False

Then, change your scheduled task to call your script like this.  The only danger is that if you don't test your script first and it fails, you'll never know about the failure.

C:\WINDOWS\system32\wscript.exe "C:\invisible.vbs" "C:\sendip.bat"

Your script will now run invisibly every fifteen minutes, uploading your current IP address to your website as a text file.  You can either tell your friends to hit that file to get your current IP address, or you can work it into a quick and easy PHP page that tells them the IP and also when the file was last updated.

Hell, throw this on the page, too, and it'll ping your IP so they know if the connection is still good:

currentip.php:

<?php
$fp = @fsockopen ($addy, $port, $errno, $errstr, $timeout);
// $addy is your current IP, $port is the port your client is using,
// $timeout is how long to wait (2 is dandy)
if ($fp) {
  echo "Connection good!"
  @fclose($fp);
}
else {
  echo "Connection down."
}
?>

Caveats

So, that's it!

48 lines of code over five files, by my count; that's with nicely-spaced PHP, and it includes the scheduled task call as a line of code.  I didn't count the ping code, since it's not necessary.

Who needs to give a third-party service any idea what you're up to or a DDNS updater app running in the background?  But there are some caveats...

The FTP connection is not secure, so you're broadcasting your unencrypted FTP username and password every 15 minutes.  Also, if your web host is stingy, they might limit the number of FTP connections you can make in a day.  And, finally, you're putting your current IP address on the web.

Weigh the odds, draw your own conclusions, and tweak the fix.

Code: ip.php

Code: sendip.php

Code: sendip.bat

Code: invisible.vbs

Code: currentip.php

Return to $2600 Index