In this small guide we will build a small dyndns serivce based on php. All you need is some webspace with php.
This project is not meant to be a 100% substitute for a professional dyndns. But it's a good start for your own experiments with php and dyndns. This dyndns script is small and easy to understand, even for php beginners. It's easy to extend with additional functions.
Keep in mind it's not meant for productional environment. Use a https connection if possible.
Main features:
- ip-update function for updating ip-adress
- forwarding to target ip-adress for http & https
- support for any port and path
- support for any protocol via parameter: http, https, ftp and more
- show current ip-adress
- save history of ip-adresses (optional)
Many dyndns web services started charging money for their services. Last year i read about a project of some people, who started programming their own php dyndns script. Based on this script i started to change some parts.
There are some parmeters supported by this script explained here:
Script parameters:
protocol=http (you can use any protocol you want (for example "VNC", "FTP", "SMB", "HTTPS"...) standard ist "http"
port=Portnumber (1-xxxxx)
pfad=path, subfile or filename (f.e. /subfile/start.html). "/" is automatically added.
Special script parameters:
protocol=showip -> displays current target ip adress
protocol=ipupdate -> used to update ip adress (parameter 'pw' & 'ip' needed)
protocol=cryptpw -> hashing function (sha256) (parameter 'pw' needed)
protocol=wol -> used for wake on lan feature (testing), (parameter 'mac' & 'port' needed)
protocol=cryptpwuser -> hashing function for username & password (testing) (sha256) (Parameter 'pw' & 'user' needed)
Examples using this script:
http://www.YourDomain.de/index.php?user=User&pw=Password&ip=<ipaddr>&protocol=ipupdate
Updates ip-adress (this is an example used by a fritzbox router, <ipaddr> delivers the ipadress within routers web-gui).
http://www.YourDomain.de/index.php?user=User&pw=Password&mip=127.0.0.1>&protocol=ipupdate
Updates ip-adress via webbrowser, parameter 'mip' contains the target ip-adress
http://www.YourDomain.de/index.php?protocol=cryptpw&pw=Username
Returns sha256 hashed parameter 'pw', for example username or password
http://www.YourDomain.de/index.php?user=User
Forwards your webbrowser to target ip-adress, without parameters http and port 80 is used
http://www.YourDomain.de/index.php?user=User&protocol=ftp&port=21
Forwards your webbroswer to target ip-adress as FTP://[IP-Adress]:21
http://www.YourDomain.de/index.php?user=User&protocol=vnc&port=5600
Forwards your webbrowser to target ip-adress using VNC//[IP-Adress]:5600
http://www.YourDomain.de/index.php?user=User&protocol=http&port=777&pfad=FunnyPath
Forwards your browser to http://[IP-Adress]:777/FunnyPath
First of all, for security reasons, put your own hashed username and password into variables $USER and $PASSWORT. Use SHA256 to hash your username/password. Some websites offer hashing function for this. But you can also hash your username & password with this script. Upload php-file to your server and start script with parameter protocol=cryptpw and pw=[Your Username]:
http://www.YourDomain.com/index.php?protocol=cryptpw&pw=Username
Script will return your hashed Username. Edit your php-file and change variable $USER = 'Your SHA256 hashed Username';
Next, do the same with your Password. Start script with parameter protocol=cryptpw and pw=[Your Password]:
http://www.YourDomain.com/index.php?protocol=cryptpw&pw=Password
Script will return your hashed password. Edit your php-file and change variable $PASSWORT = 'Your SHA256 hashed password';
Here is the full script:
<?
// DynDNS PHP Script
// versiondate: 2015-10-01
// autor: adxamg
// based on script by Axel Teichmann
//
// Script parameters:
// protocol=http (you can use any protocol you want (for example "VNC", "FTP", "SMB", "HTTPS"...) standard ist "http"
// port=Portnumber (1-xxxxx)
// pfad=subfile or file (f.e. start.html). a "/" is automatically added.
//
// Special script parameters:
// protocol=showip -> displays current target ip adress
// protocol=ipupdate -> used to update ip adress (parameter pw & ip needed)
// protocol=cryptpw -> hashing function (sha256) (parameter 'pw' needed)
// protocol=wol -> used for wake on lan feature (testing), (parameter mac & port needed)
// protocol=cryptpwuser -> hashing function for username & password (testing) (sha256) (Parameter 'pw' & 'user' needed)
// User variables:
$IP_Datei = "IP_Server_01.txt"; // Filename, here ip-adress will be saved
$USER = 'Username_hashed'; // Username for forwards, showip and so on
$PASSWORT = 'Password_hashed'; // Password for updating ip-adress
$Vorratsdatenspeicherung = "JA"; // Acticate ("JA") or deactivate ("NEIN") of saving ip-history
$VorratsdatenspeicherungsOrdner= "IP-Archiv"; // Subfile where ip history will be saved
$IParchivname = "IP-Archiv"; // Filename of ip-history "Year-Month-IP-Archiv", also "2014-01-IP-Archiv.txt"
// Programm variables:
$User = $_GET['user']; // reading Username from parameters
$Passwort = $_GET['pw']; // reading password from parameters
$Protocol = $_GET['protocol']; // reading protocol from parameters
$Port = $_GET['port']; // reading port from parameters
$Port=$Port+0; // adding 0 to port parameter makes it a number
$Pfad = $_GET['pfad']; // reading path from parameters
$FritzIP = $_GET['ip']; // reading ip-adress from parameters
$domain=$_SERVER['SERVER_NAME']; // reading domain from parameters
$Mac = $_GET['mac']; // reading mac adress from parameters used for wol (testing)
$CheckIP = ""; // variable for checking ip-adress
$pwcrypted = ""; // variable for checking hash
// Variable modification
date_default_timezone_set('Europe/Berlin'); setlocale(LC_TIME, "de_DE");
if ($Protocol=="") {$Protocol="http";} // set http when there is no protocol in parameters
if ($Port==0) {$Port="";} // no port was in parameters
if ($Port>=1) {$Port=":".$Port;} // add a ":" when there is a port
if ($Pfad!=="") {$Pfad="/".$Pfad;} // when there is a path, add a "/"
$UserHashed=hash("sha256", $User); // hashing username
// Hash Username & Password SHA256
if ($Protocol=="cryptpw") { // Hilfsfunktion: berechnet den Hash für den Paramter "pw"
$pwcrypted=hash("sha256", $Passwort);
echo $Passwort." -- crypted with SHA256 --> ".$pwcrypted;
exit;
}
// Check username
if ($UserHashed!==$USER) {sleep(5); exit;} // check username, wait 5 seconds when it's wrong
// Check existence of ip-filename
if (!file_exists($IP_Datei)) { // check existence of ip-filename
$datei = fopen("$IP_Datei", "w+"); // make new one, if there is no file
fwrite($datei, "127.0.0.1"); // Write dummy ipadress
fclose($datei); // close file
}
// IP-update function
if ($Protocol=="ipupdate") { // protocol=ipupdate, user wants to update target ip-adress
$CheckIP = str_replace('.', '', $FritzIP);// remove not needed parts of ip-adress
if (!ctype_digit($CheckIP)) {echo "Error: IP address invalid"; exit;}// check ip-adress for numbers
$Passwort=hash("sha256", $Passwort);// hash Password
if($Passwort==$PASSWORT) { // Password ok, then...
$datei = fopen("$IP_Datei", "w"); // open file for writing
fwrite($datei, $FritzIP); // write target ip-adress
fclose($datei); // close file
echo "good ".$domain; // Browser output
// Saving ip-history
if ($Vorratsdatenspeicherung=="JA") { // save ip-history activated (JA)
$jahr=date("Y");$monat=date("m"); // Datum ermitteln
$Filename=$VorratsdatenspeicherungsOrdner."/".$jahr."-".$monat."-".$IParchivname.".txt";
// Format output: yyyy-mm-dd hh:mm:ss IP:ipadress
$datum=date("Y-m-d H:i:s",time()); $inhalt=$datum." IP:".$FritzIP."\n";
// check for subfile, make new one if not existent
if (!file_exists($VorratsdatenspeicherungsOrdner)) { mkdir($VorratsdatenspeicherungsOrdner, 0777, true); }
// check file, read file, put ip-adress, date inside
if (file_exists($Filename)) {$Alterinhalt = file_get_contents($Filename);
$umdrehen=strrev($Alterinhalt); $Position= strpos($umdrehen, ":PI"); $AlteIP= substr($umdrehen, 1, $Position-1);
$AlteIP=strrev($AlteIP); }
if ($AlteIP!==$FritzIP) { // check if we have a new ip-adress
$datei = fopen("$Filename", "a"); // open file
fwrite($datei, $inhalt); // write ip, date
fclose($datei); // close file
}
}
exit; // exit script
}
exit;
}
if (file_exists($IP_Datei)) { // check existence of file
$datei= fopen("$IP_Datei", "r"); // open file for reading
$inhalt = fread($datei,filesize($IP_Datei)); // read ip-adress
fclose($datei); // close file
if ($Protocol=="showip") {echo $inhalt;exit;}// "protocol=showip" displays target ip-adress in browser
if ($Protocol=="cryptpw") {// Hash function for paramter "pw"
$pwcrypted=hash("sha256", $Passwort);
echo $Passwort." -- crypted with SHA256 --> ".$pwcrypted;
exit;
}
if ($Protocol=="cryptpwuser") {// Hash function for paramter "pw" and "user"
$pwcrypted=hash("sha256", $Passwort.$User);
echo $Passwort." & ".$User." -- crypted with SHA256 --> ".$pwcrypted;
exit;
}
if ($Protocol=="wol") {// "protocol=wol" is a test function for 'wake on lan' aus (needs user/mac/port)
if (!$Mac=="") {
if ($Port=="") {echo "Error: Port is missing!"; exit;}
$Mac = str_replace(':', '', $Mac);
if (!ctype_xdigit($Mac)) {echo "Fehler: Mac address invalid, only 0-9 and a-f are allowed"; exit;}
$MacBinary = pack('H12', $Mac);
$magicPacket = str_repeat(chr(0xff), 6).str_repeat($MacBinary, 16);
$datei= fopen("$IP_Datei", "r");
$broadcastAddress = fread($datei,filesize($IP_Datei));
fclose($datei);
if (!$fp = fsockopen('udp://' . $broadcastAddress, $Port, $errno, $errstr, 2)) {echo "Error: $errno - $errstr"; exit;}
fputs($fp, $magicPacket);
fclose($fp);
exit;
}
exit;
}
//Forwarding to target
$url=$Protocol."://".$inhalt."".$Port."".$Pfad; // URL = Protocol & IP-Adress & Port & Path
header("Location: $url"); // Forwarding browser
exit; // Exit
}
?>