Skip to content

Instantly share code, notes, and snippets.

@aaronk6
Last active June 2, 2024 11:54
Show Gist options
  • Save aaronk6/dfb2216ab98a1606fcc9094c76b4e5e8 to your computer and use it in GitHub Desktop.
Save aaronk6/dfb2216ab98a1606fcc9094c76b4e5e8 to your computer and use it in GitHub Desktop.
RouterOS dynamic DNS update script for he.net (IPv4 and IPv6)
# 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