UNIX based sysadmins like MikrotiK routers, but often home provider not give Static IP.
Today i have fix it mistake, but DynDNS not pay free more. ;(
I as many sysadmins have access to LINUX based web-server.
Then i write mikrotik based “HTTP GET” IP pushing script. It’s sent to web-server my external IP, then PHP5 part of web server generate BIND9 compatible Zone file. And after that reload BIND9 config to load new zone and send notify to secondary DNS.
And i not need any external DDNS service.
Mikrotik script
# DNS server
:local sendhost "dns.mywebserver.ru";
# Zone
:local host "mydomain.net";
# Access password
:local password "passwordblablabla";
# Mikrotik external IFace
:local iface "beeline-l2tp";
# Location of PHP script in web-server home dir
:local script "/update_dns.php";
# get current IP address from DNS system
:local currentdnsaddress [ :resolve $host ];
# get Mikrotik external address
:local iptemp [ /ip address get [find interface=$iface] address ];
# cut IP without mask
:local str [:pick $iptemp 0 [:find $iptemp "/"]];
# if DNS address not equal our external
:if ($str != $currentdnsaddress) do={
:log info "Update DynamicIP needed, Sending UPDATE...!"
# make request parameters
:local str2 "$script\?hostip=$str&password=$password&host=$host";
:put $str2
# execute GET http request with parameters
/tool fetch address=$sendhost host=$sendhost src-path=$str2 mode=http keep-result=no;
} else={ :log info "DynamicIP: dont need changes"; }
PHP5 script update_dns.php
<?
//
// Author: Andrey Bykanov (adm@shodtech.net)
//
// BIND9 Dynamic IP update script
////////////////////////////////////////////////////////////////////////////////////////////////////////
$password="passwordblablabla";
$host="mydomain.net";
////////////////////////////////////////////////////////////////////////////////////////////////////////
function is_ipv4($string)
{
// The regular expression checks for any number between 0 and 255 beginning with a dot (repeated 3 times)
// followed by another number between 0 and 255 at the end. The equivalent to an IPv4 address.
return (bool) preg_match('/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])'.'\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|[0-9])$/', $string);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
if(isset($_GET["password"]) & isset($_GET["hostip"]) & isset($_GET["host"])) // check for all nesesery parameters is exist
{
if($_GET["password"]!=$password){echo " Wrong password: ".$_GET["password"]; die();} // Check password
if($_GET["host"]!=$host) {echo " Wrong host: ".$_GET["host"]; die();} // Check hostname
if(!(is_ipv4($_GET["hostip"]) & ($_SERVER["HTTP_X_REAL_IP"]==$_GET["hostip"]))){echo " Wrong IP address : ".$_GET["hostip"]; die();} // Check IP address
$zone_time=(integer)(((date('H')*60)+date('i'))/15); // Calculate Zone time, one tick is allmost 15 minutes
$zone_date=date('Ymd').$zone_time; // Calculate complette zone serial eg, YearMonthDayTime
$fp = fopen('shodtech.net_zone_data.txt', 'w'); // zone file name
// Writing BIND9 Zone content
fwrite($fp, "\$ORIGIN mydomain.net. \r\n");
fwrite($fp, "\$TTL 600 ; 10 minutes \r\n");
fwrite($fp, "@ IN SOA ns.mydomain.net. adm.mydomain.net. ( \r\n");
fwrite($fp, " ".$zone_date." ; serial \r\n");
fwrite($fp, " 600 ; refresh (10 minutes) \r\n");
fwrite($fp, " 600 ; retry (10 minutes) \r\n");
fwrite($fp, " 86400 ; expire (1 day) \r\n");
fwrite($fp, " 600 ; minimum (10 minutes) \r\n");
fwrite($fp, " ) \r\n");
fwrite($fp, " NS ns1.mywebserver.ru. \r\n");
fwrite($fp, " NS ns2.mywebserver.ru. \r\n");
fwrite($fp, " A ".$_GET["hostip"]." \r\n"); // Put Mikrotik external IP address
fwrite($fp, "ftp A ".$_GET["hostip"]." \r\n"); // Put Mikrotik external IP address
fwrite($fp, "www A ".$_GET["hostip"]." \r\n"); // Put Mikrotik external IP address
fclose($fp); // Close file
exec('/usr/sbin/rndc reload'); // Reloading BIND9 config (Web-server must have permission for write to /etc/bind/rndc.key)
} else echo "Wrong parameters";
?>
Part of BIND9 config
zone "mydomain.net" {
type master;
file "/var/www/mydomain.net_zone_data.txt"; // Full path to zone file generated by PHP script
allow-update { none;};
allow-query {any; } ;
allow-transfer { 62.12.13.12; } ; // IP to transfer zone (Secondary DNS)
notify yes;
};
.htaccess
Options All -Indexes
Deny from All
<Files "update_dns.php">
Allow from All
</Files>