Dynamic dns with BIND and Mikrotik
Tested on Centos 6.7
Assuming we have the domain name domain.com with private nameservers ns1.domain.com and ns2.domain.com that will resolve to 1.1.1.1 and 2.2.2.2 respectively.
We also have a VPS with static IP 1.1.1.1 on which we will setup dyndns server for Mikrotik clients.
Install BIND (version 9.8.2 in our case), PHP and the text editor:
yum install bind nano php
Add include directive:
nano /etc/named.conf
include "/var/www/html/dyndns/domain.com.zones";
Add the primary DNS zone:
zone "domain.com" IN { type master; file "domain.com.zone"; allow-update { none; }; };
Save and close.
Create the primary zone file:
nano /var/named/domain.com.zone
$TTL 86400 @ IN SOA ns1.domain.com. root.domain.com. ( 2013042201 ;Serial 3600 ;Refresh 1800 ;Retry 604800 ;Expire 86400 ;Minimum TTL ) ; Specify our two nameservers IN NS ns1.domain.com. IN NS ns2.domain.com. ; Resolve nameserver hostnames to IP, replace with your two droplet IP addresses. ns1 IN A 1.1.1.1 ns2 IN A 2.2.2.2 ; Define hostname -> IP pairs which you wish to resolve @ IN A 1.1.1.1 www IN A 1.1.1.1
In our case 1.1.1.1 and 2.2.2.2 are the same IP. We have ns1 and ns2 at the same VPS.
Create and open zones file.
mkdir -p /var/www/html/dyndns nano /var/www/html/dyndns/domain.com.zones
Insert zone for each dynamic host, for example:
zone "dyn.domain.com" IN { type master; file "/var/www/html/dyndns/dyn.domain.com/dyn.domain.com.zone"; allow-update { none; }; };
Add dynamic subdomain
Assuming we have a running Apache webserver with default configuration and web root /var/www/html/.
Step 1 Create zone file.
mkdir /var/www/html/dyndns/dyn.domain.com chmod root:apache /var/www/html/dyndns/dyn.domain.com nano /var/www/html/dyndns/dyn.domain.com/dyn.domain.com.zone
$TTL 86400 @ IN SOA ns1.domain.com. root.domain.com. ( 2013042201 ;Serial 3600 ;Refresh 1800 ;Retry 604800 ;Expire 86400 ;Minimum TTL ) ; Specify our two nameservers IN NS ns1.domain.com. IN NS ns2.domain.com. ; Resolve nameserver hostnames to IP, replace with your two droplet IP addresses. ns1 IN A 1.1.1.1 ns2 IN A 2.2.2.2 ; Define hostname -> IP pairs which you wish to resolve @ IN A 1.2.3.4
Where 1.1.1.1 and 2.2.2.2 are the IPs of nameservers and 1.2.3.4 is the IP of dynamic host.
Step 2 Create php script for receiving input from clients;
nano /var/www/html/dyndns/dyn.domain.com/deviceupdate.php
<?php $ip=$_SERVER[REMOTE_ADDR]; if ($_GET['hash']="ae2b1fca515949e5d54fb22b8ed95575") { file_put_contents("deviceupdate.log","DATE: ".date("Y-m-d H:i:s")." IP: ".$ip."\n",FILE_APPEND | LOCK_EX); file_put_contents("homeip.log",$ip,LOCK_EX); print "DATE: ".date("Y-m-d H:i:s")." IP: ".$ip; } ?>
Step 3 Create bash script for updating BIND zones.
nano /var/www/html/dyndns/dyn.domain.com/dyndns.sh
#!/bin/bash dhost=dyn.domain.com dpath=/var/www/html/dyndns newip=$(cat $dpath/$dhost/homeip.log) md5old=$(cat $dpath/$dhost/homeip.md5) md5new=$(md5sum $dpath/$dhost/homeip.log) #echo "$(date) RunTime" >> /var/log/dyndns.log if test "$md5old" = "$md5new" then echo "$(date) - No change" >> /var/log/dyndns.log else sed -i "/@ IN A/ c\@ IN A $newip" $dpath/$dhost/$dhost.zone rndc reload $dhost md5sum $dpath/$dhost/homeip.log > $dpath/$dhost/homeip.md5 echo "$(date) - Updated ip $newip" >> /var/log/dyndns.log fi
Make it exacutable:
chmod +x /var/www/html/dyndns/dyn.domain.com/dyndns.sh
Step 4 Set http auth for apache (optional): open http conf file:
nano /etc/httpd/conf/httpd.conf
add lines:
<Directory "/var/www/html/dyndns"> AuthUserFile /etc/httpd/.htpasswd AuthType Basic AuthName "Restricted Content" Require valid-user </Directory>
restart apache
service httpd restart
create http user and set password:
htpasswd -c /etc/httpd/.htpasswd httpuser
Step 5 Set a cron task:
nano /etc/crontab
*/5 * * * * root /var/www/html/dyndns/dyn.domain.com/dyndns.sh
Restart BIND:
service named restart
Client side.
In our case the client is Mikrotik router board.
Add the following script to Mikrotik and setup scheduler to run every few minutes.
/tool fetch keep-result=no mode=http user=httpuser password=httppassword url="http://domain.com/dyndns/dyn.domain.com/deviceupdate.php?hash=ae2b1fca515949e5d54fb22b8ed95575"