Setting static DNS record for each DHCP lease

From MikroTik Wiki
Revision as of 05:01, 1 July 2011 by Nsayer (talk | contribs) (fix bugs)
Jump to: navigation, search

Run this in scheduler and it will add static dns entry for each DHCP lease.

NB: As this script may delete already added static DNS entries, bases on received hostname over DHCP, the script involves a security risk. Use a uniq domain, for example dhcp.yourdomain.com, dynamic.yourdomain.com or similar. If you have to mix static and dynamic DNS entries on exact same domain, see below.

# DNS record for DHCP lease
# Prepare variables in use
:local topdomain;
:local hostname;
:local hostip;

# Configure your domain
:set topdomain "dhcp.yourdomain.com";

/ip dhcp-server lease;
:foreach i in=[find] do={
  /ip dhcp-server lease;
  :if ([:len [get $i host-name]] > 0) do={
    :set hostname ([get $i host-name] . "." . $topdomain);
    :set hostip [get $i address];
    /ip dns static;
# Remove if DNS entry already exist
    :foreach di in [find] do={
      :if ([get $di name] = $hostname) do={
        :put ("Removing: " . $hostname . " : " . $hostip);
        remove $di;
      }
    }
# Add DNS entry
    :put ("Adding: " . $hostname . " : " . $hostip);
    /ip dns static add name=$hostname address=$hostip;
  }
}


This second script takes another approach. Using TTL as a way to distinguish dynamical added DNS entries and delete those before adding new. Adding hostnames that already exist is denied.

Also old DNS-entries will be removed, when not longer in DHCP-lease. This will prevent messed up DNS-static with a lot of entries.


# Domain to be added to your DHCP-clients hostname
:local topdomain;
:set topdomain "lan";

# Use ttl to distinguish dynamic added DNS records
:local ttl;
:set ttl "00:59:59";

# Set variables to use
:local hostname;
:local hostip;
:local free;

# Remove all dynamic records
/ip dns static;
:foreach a in=[find] do={
  :if ([get $a ttl] = $ttl) do={
    :put ("Removing: " . [get $a name] . " : " . [get $a address]);
    remove $a;
  }
}

/ip dhcp-server lease ;
:foreach i in=[find] do={
  /ip dhcp-server lease ;
  :if ([:len [get $i host-name]] > 0) do={
    :set free "true";
    :set hostname ([get $i host-name] . "." . $topdomain);
    :set hostip [get $i address];
    /ip dns static ;
# Check if entry already exist
    :foreach di in [find] do={
      :if ([get $di name] = $hostname) do={
        :set free "false";
        :put ("Not adding already existing entry: " . $hostname);
      }
    }
    :if ($free = true) do={
      :put ("Adding: " . $hostname . " : " . $hostip ) ;
      /ip dns static add name=$hostname address=$hostip ttl=$ttl;
    }
  }
}

Here's another example. This one will only change the DNS information when changes are necessary, and deletes old DNS entries when leases expire.

       :local zone "dhcp";
       :local ttl "00:05:00"
       :local hostname
       :local ip
       :local dnsip
       :local dhcpip
       :local dnsnode
       :local dhcpnode
       
       /ip dns static;
       :foreach i in=[find where name ~ (".*\\.".$zone) ] do={
         :set hostname [ get $i name ];
         :set hostname [ :pick $hostname 0 ( [ :len $hostname ] - ( [ :len $zone ] + 1 ) ) ];
         /ip dhcp-server lease;
         :set dhcpnode [ find where host-name=$hostname ];
         :if ( [ :len $dhcpnode ] > 0) do={
           :log debug ("Lease for ".$hostname." still exists. Not deleting.");
         } else={
           :log info ("Lease expired for ".$hostname.", deleting DNS entry.");
           /ip dns static remove $i;
         }
       }
       
       /ip dhcp-server lease;
       :foreach i in=[find] do={
         :set dhcpip [ get $i address ];
         :if ( [ :len [ get $i host-name ] ] > 0) do={
           :set hostname ( [ get $i host-name ] . "." . $zone );
           /ip dns static;
           :set dnsnode [ find where name=$hostname ];
           :if ( [ :len $dnsnode ] > 0 ) do={
       # it exists. Is its IP the same?
             :set dnsip [ get $dnsnode address ];
             :if ( $dnsip = $dhcpip ) do={
               :log debug ("DNS entry for " . $hostname . " does not need updating.");
             } else={
               :log info ("Replacing DNS entry for " . $hostname);
               /ip dns static remove $dnsnode;
               /ip dns static add name=$hostname address=$dhcpip ttl=$ttl;
             }
           } else={
       # it doesn't exist. Add it
             :log info ("Adding new DNS entry for " . $hostname);
             /ip dns static add name=$hostname address=$dhcpip ttl=$ttl;
           }
         }
       }