Last active
July 18, 2024 23:12
-
-
Save aaronk6/dfb2216ab98a1606fcc9094c76b4e5e8 to your computer and use it in GitHub Desktop.
RouterOS dynamic DNS update script for he.net (IPv4 and IPv6)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# RouterOS dynamic DNS Update Script for he.net | |
# ============================================= | |
# make global to preserve IP and IPv6 address across script executions | |
:global ipddns | |
:global ipv6ddns | |
:local ddnshost "myhost.example.com" | |
:local ddnspass "MY_SECURE_PASSWORD" | |
:local waninterfacev4 "V4_INTERFACE_NAME" # Interface to retrieve WAN IPv4 address from (i.e. pppoe-out1) | |
:local waninterfacev6 "V6_INTERFACE_NAME" # Interface to retrieve WAN IPv6 address from (i.e. bridge1) | |
:local ipv6pool "YOUR_IP6_POOL" # Pool that IPv6 address needs to be part of | |
:local url "https://dyn.dns.he.net/nic/update" | |
:local ipfresh "" | |
:local ipv6fresh "" | |
:local ipv4error false | |
:local ipv6error false | |
:do { | |
# get current IP address from WAN interface | |
:set ipfresh [/ip address get [find where interface=$waninterfacev4] value-name=address] | |
# Check if ipfresh is empty | |
:if ($ipfresh = "") do={ | |
:log error ("DDNS: Failed to get IP address from interface $waninterfacev4.") | |
:set ipv4error true | |
} | |
:if ([ :typeof $ipfresh ] = nil ) do={ | |
:log error ("DDNS: No IP address on $waninterfacev4") | |
:set ipv4error true | |
} | |
} on-error={ | |
:log error "DDNS: An error occurred while getting the current IP address from WAN interface." | |
:set ipv4error true | |
} | |
:do { | |
# get current IPv6 address from LAN interface | |
:set ipv6fresh [/ipv6/address get [find where from-pool="telekom-ipv6" interface=$waninterfacev6] address] | |
# Check if ipv6fresh is empty | |
:if ($ipv6fresh = "") do={ | |
:log error ("DDNS: Failed to get IPv6 address from interface $waninterfacev6.") | |
:set ipv6error true | |
} | |
:if ([ :typeof $ipv6fresh ] = nil ) do={ | |
:log error ("DDNS: No IPv6 address on $waninterfacev6") | |
:set ipv6error true | |
} | |
} on-error={ | |
:log error "DDNS: An error occurred while getting the current IPv6 address from LAN interface." | |
:set ipv6error true | |
} | |
# extract the portion of the IP address before the last / character | |
:do { | |
# extract the portion of the IP address before the last / character | |
:for i from=( [:len $ipfresh] - 1) to=0 do={ | |
:if ( [:pick $ipfresh $i] = "/") do={ | |
:set ipfresh [:pick $ipfresh 0 $i]; | |
} | |
} | |
:for i from=( [:len $ipv6fresh] - 1) to=0 do={ | |
:if ( [:pick $ipv6fresh $i] = "/") do={ | |
:set ipv6fresh [:pick $ipv6fresh 0 $i]; | |
} | |
} | |
} on-error={ | |
:log error "DDNS: An error occurred while extracting the portion of the IP addresses." | |
} | |
:do { | |
# Check and update IPv4 address | |
:if ($ipv4error) do={ | |
:log warning "DDNS: Skipping IPv4 update due to previous error." | |
} else { | |
:if ($ipddns = $ipfresh) do={ | |
:log info ("DDNS: IP address is already up to date") | |
} else { | |
:log info ("DDNS: IP address has changed from $ipddns to $ipfresh, sending update...") | |
:local body "hostname=$ddnshost&password=$ddnspass&myip=$ipfresh" | |
:local result [/tool fetch mode=https output=user url=$url http-method=post http-data=$body as-value] | |
:if ($result->"status" != "finished") do={ | |
:log error ("DDNS: Failed to send IPv4 update") | |
} else { | |
:log info ("DDNS: Response from server: " . $result->"data") | |
:if (([:find ($result->"data") "good"] = 0) or ([:find ($result->"data") "nochg"] = 0)) do={ | |
:set ipddns $ipfresh | |
} | |
} | |
} | |
} | |
} on-error={ | |
:log error "DDNS: An error occurred while checking and updating the IPv4 address." | |
} | |
:do { | |
# Check and update IPv6 address | |
:if ($ipv6error) do={ | |
:log warning "DDNS: Skipping IPv6 update due to previous error." | |
} else { | |
:if ($ipv6ddns = $ipv6fresh) do={ | |
:log info ("DDNS: IPv6 address is already up to date") | |
} else { | |
:log info ("DDNS: IPv6 address has changed from $ipv6ddns to $ipv6fresh, sending update...") | |
:local body "hostname=$ddnshost&password=$ddnspass&myip=$ipv6fresh" | |
:local result [/tool fetch mode=https output=user url=$url http-method=post http-data=$body as-value] | |
:if ($result->"status" != "finished") do={ | |
:log error ("DDNS: Failed to send IPv6 update") | |
} else { | |
:log info ("DDNS: Response from server: " . $result->"data") | |
:if (([:find ($result->"data") "good"] = 0) or ([:find ($result->"data") "nochg"] = 0)) do={ | |
:set ipv6ddns $ipv6fresh | |
} | |
} | |
} | |
} | |
} on-error={ | |
:log error "DDNS: An error occurred while checking and updating the IPv6 address." | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment