Skip to content

Instantly share code, notes, and snippets.

@SmartFinn
Last active October 22, 2025 21:55
Show Gist options
  • Select an option

  • Save SmartFinn/acc7953eaeb43cece034 to your computer and use it in GitHub Desktop.

Select an option

Save SmartFinn/acc7953eaeb43cece034 to your computer and use it in GitHub Desktop.

Revisions

  1. SmartFinn revised this gist Dec 31, 2020. 1 changed file with 23 additions and 34 deletions.
    57 changes: 23 additions & 34 deletions dhcp-leases-to-dns.rsc
    Original file line number Diff line number Diff line change
    @@ -3,12 +3,8 @@
    #
    # author SmartFinn <https://gist.github.com/SmartFinn>

    :local domainName;
    :local fqdn;
    :local hostname;
    :local safeHostname;
    :local dnsTTL "00:15:00";
    :local token "$leaseServerName-$leaseActMAC";
    :local ttl [/ip dhcp-server get $leaseServerName lease-time];

    # Normalize hostname (e.g. "-= My Phone =-" -> "My-Phone")
    # - truncate length to 63 chars
    @@ -31,48 +27,41 @@
    };
    };
    };
    # trim the last invalid char
    # delete trailing hyphen
    :if ($isInvalidChar) do={
    :set result [:pick $result 0 ([:len $result]-1)]
    :set result [:pick $result 0 ([:len $result]-1)];
    }
    :return $result;
    };

    # Getting the domain name from DHCP server. If a domain name is not
    # specified will use hostname only
    /ip dhcp-server network {
    :set domainName [get [:pick [find $leaseActIP in address] 0] domain];
    :if ($domainName != "") do={
    # Add a dot before domain name
    :set domainName ("." . $domainName);
    }
    };

    :if ($leaseBound = 1) do={
    :log debug "$leaseServerName: Processing bound lease $leaseActMAC ($leaseActIP)";
    /ip dhcp-server lease {
    :set hostname [get [find active-mac-address=$leaseActMAC] host-name];
    # Getting the hostname and delete all disallowed chars from it
    :local hostName $"lease-hostname";
    :set hostName [$normalizeHostname name=$hostName];

    # Use MAC address as a hostname if the hostname is missing or contains only
    # disallowed chars
    :if ([:len $hostName] = 0) do={
    :set hostName [$normalizeHostname name=$leaseActMAC];
    };

    # Delete unallowed chars from the hostname
    :for i from=0 to=([:len $hostname]-1) do={
    :local char [:pick $hostname $i];
    :if ($char~"[a-zA-Z0-9-]") do={
    :set safeHostname ($safeHostname . $char);
    # Getting the domain name from DHCP server. If a domain name is not
    # specified will use hostname only
    /ip dhcp-server network {
    :local domainName [get [:pick [find $leaseActIP in address] 0] domain];
    :if ([:len $domainName] > 0) do={
    # Append domain name to the hostname
    :set hostName ($hostName . "." . $domainName);
    };
    };

    :if ([:len $safeHostname] > 0) do={
    :set fqdn ($safeHostname . $domain);
    :do={
    # Add DNS entry
    /ip dns static add name=$fqdn address=$leaseActIP ttl=$ttl comment=$token;
    } on-error={
    :log error "Unable to add DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    :do {
    /ip dns static {
    add name=$hostName address=$leaseActIP ttl=$dnsTTL comment=$token;
    };
    } on-error={
    :log error "Fail to add DNS entry: $hostname -> $leaseActIP ($leaseActMAC)";
    };
    } else={
    # Remove entry when lease expires ($leaseBound=0)
    :log debug "$leaseServerName: Processing deassigned lease $leaseActMAC ($leaseActIP)";
    /ip dns static remove [find comment=$token];
    };
  2. SmartFinn revised this gist Dec 30, 2020. 1 changed file with 5 additions and 6 deletions.
    11 changes: 5 additions & 6 deletions dhcp-leases-to-dns.rsc
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    #
    # author SmartFinn <https://gist.github.com/SmartFinn>

    :local domain;
    :local domainName;
    :local fqdn;
    :local hostname;
    :local safeHostname;
    @@ -41,12 +41,11 @@
    # Getting the domain name from DHCP server. If a domain name is not
    # specified will use hostname only
    /ip dhcp-server network {
    :do {
    :set domainName [get [:pick [find $leaseActIP in address] 0] domain];
    :if ($domainName != "") do={
    # Add a dot before domain name
    :set domain ("." . [get [find $leaseActIP in address] domain]);
    } on-error={
    :set domain "";
    };
    :set domainName ("." . $domainName);
    }
    };

    :if ($leaseBound = 1) do={
  3. SmartFinn revised this gist Dec 30, 2020. 1 changed file with 28 additions and 0 deletions.
    28 changes: 28 additions & 0 deletions dhcp-leases-to-dns.rsc
    Original file line number Diff line number Diff line change
    @@ -10,6 +10,34 @@
    :local token "$leaseServerName-$leaseActMAC";
    :local ttl [/ip dhcp-server get $leaseServerName lease-time];

    # Normalize hostname (e.g. "-= My Phone =-" -> "My-Phone")
    # - truncate length to 63 chars
    # - substitute disallowed chars with a hyphen
    # param: name
    :local normalizeHostname do={
    :local result;
    :local isInvalidChar true;
    :for i from=0 to=([:len $name]-1) do={
    :local char [:pick $name $i];
    :if ($i < 63) do={
    :if ($char~"[a-zA-Z0-9]") do={
    :set result ($result . $char);
    :set isInvalidChar false;
    } else={
    :if (!$isInvalidChar) do={
    :set result ($result . "-");
    :set isInvalidChar true;
    };
    };
    };
    };
    # trim the last invalid char
    :if ($isInvalidChar) do={
    :set result [:pick $result 0 ([:len $result]-1)]
    }
    :return $result;
    };

    # Getting the domain name from DHCP server. If a domain name is not
    # specified will use hostname only
    /ip dhcp-server network {
  4. SmartFinn revised this gist Dec 28, 2020. 1 changed file with 7 additions and 30 deletions.
    37 changes: 7 additions & 30 deletions dhcp-leases-to-dns.rsc
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,6 @@
    # for clients when they obtain a DHCP lease.
    #
    # author SmartFinn <https://gist.github.com/SmartFinn>
    # based on https://github.com/karrots/ROS-DDNS

    :local domain;
    :local fqdn;
    @@ -15,9 +14,8 @@
    # specified will use hostname only
    /ip dhcp-server network {
    :do {
    :set domain [get [find where ($leaseActIP in address)] domain];
    # Add a dot before domain name
    :set domain ("." . $domain);
    :set domain ("." . [get [find $leaseActIP in address] domain]);
    } on-error={
    :set domain "";
    };
    @@ -39,36 +37,15 @@

    :if ([:len $safeHostname] > 0) do={
    :set fqdn ($safeHostname . $domain);

    /ip dns static {
    :local itemId [find name=$fqdn];

    :if ($itemId != "") do={
    # This DNS entry already exists
    :if ([get $itemId comment] = $token) do={
    :if ([get $itemId address] != $leaseActIP) do={
    set $itemId address=$leaseActIP ttl=$ttl;
    :log info "Update DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    };
    } else={
    :log warning "Cannot to add DNS entry. $fqdn already exists";
    };
    } else={
    # Add DNS entry if it does not exist
    add name=$fqdn address=$leaseActIP ttl=$ttl comment=$token;
    :log info "Add DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    };
    :do={
    # Add DNS entry
    /ip dns static add name=$fqdn address=$leaseActIP ttl=$ttl comment=$token;
    } on-error={
    :log error "Unable to add DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    };
    };
    } else={
    # Remove entry when lease expires ($leaseBound=0)
    :log debug "$leaseServerName: Processing deassigned lease $leaseActMAC ($leaseActIP)";
    /ip dns static {
    :local itemId [find comment=$token];
    :if ($itemId != "") do={
    :set fqdn ([get $itemId name]);
    remove $itemId;
    :log info "Remove DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    };
    };
    /ip dns static remove [find comment=$token];
    };
  5. SmartFinn revised this gist Aug 9, 2018. 1 changed file with 59 additions and 54 deletions.
    113 changes: 59 additions & 54 deletions dhcp-leases-to-dns.rsc
    Original file line number Diff line number Diff line change
    @@ -3,67 +3,72 @@
    #
    # author SmartFinn <https://gist.github.com/SmartFinn>
    # based on https://github.com/karrots/ROS-DDNS
    #
    # tested on RouterOS 6.34.2
    #

    :local domain
    :local fqdn
    :local hostname
    :local isFree
    :local token "$leaseServerName-$leaseActMAC"
    :local ttl [/ip dhcp-server get $leaseServerName lease-time]
    :local domain;
    :local fqdn;
    :local hostname;
    :local safeHostname;
    :local token "$leaseServerName-$leaseActMAC";
    :local ttl [/ip dhcp-server get $leaseServerName lease-time];

    # Getting the domain name from DHCP server. If a domain name is not
    # specified will use hostname only
    /ip dhcp-server network {
    :foreach network in=[find] do={
    :local address [get $network address]
    :local netaddr [:pick $address 0 [:find $address "/"]]
    :local cidr [:pick $address ([:find $address "/"] + 1) [:len $address]]

    :if (($leaseActIP & ~(255.255.255.255 >> $cidr)) = $netaddr) do={
    :if ([:typeof [get $network domain]] != "nil") do={
    :set domain ("." . [get $network domain])
    }
    }
    }
    }
    :do {
    :set domain [get [find where ($leaseActIP in address)] domain];
    # Add a dot before domain name
    :set domain ("." . $domain);
    } on-error={
    :set domain "";
    };
    };

    :if ($leaseBound = 1) do={
    :log debug "$leaseServerName: Processing bound lease $leaseActMAC ($leaseActIP)"
    :log debug "$leaseServerName: Processing bound lease $leaseActMAC ($leaseActIP)";
    /ip dhcp-server lease {
    :set hostname [get [find active-mac-address=$leaseActMAC] host-name]
    :set hostname [get [find active-mac-address=$leaseActMAC] host-name];
    };

    # Delete unallowed chars from the hostname
    :for i from=0 to=([:len $hostname]-1) do={
    :local char [:pick $hostname $i];
    :if ($char~"[a-zA-Z0-9-]") do={
    :set safeHostname ($safeHostname . $char);
    };
    };

    :if ([:len $safeHostname] > 0) do={
    :set fqdn ($safeHostname . $domain);

    :if ([:typeof $hostname] != "nil") do={
    :set isFree true
    :set fqdn ($hostname . $domain)
    /ip dns static {
    :local itemId [find name=$fqdn];

    /ip dns static {
    :if ([find name=$fqdn] != "") do={
    :if ([get [find name=$fqdn] comment] = $token) do={
    :if ([get [find name=$fqdn] address] != $leaseActIP) do={
    :log info "Updating DNS entry: $fqdn -> $leaseActIP"
    :set isFree false
    set [find name=$fqdn] address=$leaseActIP ttl=$ttl
    }
    } else={
    :log warning "Not adding already existing entry: $fqdn"
    :set isFree false
    }
    }
    :if ($isFree = true) do={
    :log info "Adding DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)"
    add name=$fqdn address=$leaseActIP ttl=$ttl comment=$token
    }
    }
    }
    }
    :if ($itemId != "") do={
    # This DNS entry already exists
    :if ([get $itemId comment] = $token) do={
    :if ([get $itemId address] != $leaseActIP) do={
    set $itemId address=$leaseActIP ttl=$ttl;
    :log info "Update DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    };
    } else={
    :log warning "Cannot to add DNS entry. $fqdn already exists";
    };
    } else={
    # Add DNS entry if it does not exist
    add name=$fqdn address=$leaseActIP ttl=$ttl comment=$token;
    :log info "Add DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    };
    };
    };
    } else={
    :log debug "$leaseServerName: Processing deassigned lease $leaseActMAC ($leaseActIP)"
    # Remove entry when lease expires ($leaseBound=0)
    :log debug "$leaseServerName: Processing deassigned lease $leaseActMAC ($leaseActIP)";
    /ip dns static {
    :if ([find comment=$token] != "") do={
    :set fqdn ([get [find comment=$token] name])
    :log info "Remove DNS entry: $fqdn ($leaseActIP)"
    remove [find comment=$token]
    }
    }
    }
    :local itemId [find comment=$token];
    :if ($itemId != "") do={
    :set fqdn ([get $itemId name]);
    remove $itemId;
    :log info "Remove DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)";
    };
    };
    };
  6. SmartFinn created this gist Mar 22, 2016.
    69 changes: 69 additions & 0 deletions dhcp-leases-to-dns.rsc
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    # MikroTik (RouterOS) script for automatically setting DNS records
    # for clients when they obtain a DHCP lease.
    #
    # author SmartFinn <https://gist.github.com/SmartFinn>
    # based on https://github.com/karrots/ROS-DDNS
    #
    # tested on RouterOS 6.34.2
    #

    :local domain
    :local fqdn
    :local hostname
    :local isFree
    :local token "$leaseServerName-$leaseActMAC"
    :local ttl [/ip dhcp-server get $leaseServerName lease-time]

    /ip dhcp-server network {
    :foreach network in=[find] do={
    :local address [get $network address]
    :local netaddr [:pick $address 0 [:find $address "/"]]
    :local cidr [:pick $address ([:find $address "/"] + 1) [:len $address]]

    :if (($leaseActIP & ~(255.255.255.255 >> $cidr)) = $netaddr) do={
    :if ([:typeof [get $network domain]] != "nil") do={
    :set domain ("." . [get $network domain])
    }
    }
    }
    }

    :if ($leaseBound = 1) do={
    :log debug "$leaseServerName: Processing bound lease $leaseActMAC ($leaseActIP)"
    /ip dhcp-server lease {
    :set hostname [get [find active-mac-address=$leaseActMAC] host-name]

    :if ([:typeof $hostname] != "nil") do={
    :set isFree true
    :set fqdn ($hostname . $domain)

    /ip dns static {
    :if ([find name=$fqdn] != "") do={
    :if ([get [find name=$fqdn] comment] = $token) do={
    :if ([get [find name=$fqdn] address] != $leaseActIP) do={
    :log info "Updating DNS entry: $fqdn -> $leaseActIP"
    :set isFree false
    set [find name=$fqdn] address=$leaseActIP ttl=$ttl
    }
    } else={
    :log warning "Not adding already existing entry: $fqdn"
    :set isFree false
    }
    }
    :if ($isFree = true) do={
    :log info "Adding DNS entry: $fqdn -> $leaseActIP ($leaseActMAC)"
    add name=$fqdn address=$leaseActIP ttl=$ttl comment=$token
    }
    }
    }
    }
    } else={
    :log debug "$leaseServerName: Processing deassigned lease $leaseActMAC ($leaseActIP)"
    /ip dns static {
    :if ([find comment=$token] != "") do={
    :set fqdn ([get [find comment=$token] name])
    :log info "Remove DNS entry: $fqdn ($leaseActIP)"
    remove [find comment=$token]
    }
    }
    }