Skip to content

Instantly share code, notes, and snippets.

@aaronk6
Created October 3, 2023 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronk6/57463e0e5f59302cbd9632bc7992d6eb to your computer and use it in GitHub Desktop.
Save aaronk6/57463e0e5f59302cbd9632bc7992d6eb to your computer and use it in GitHub Desktop.
RouterOS dynamic DNS update script for desec.io (IPv4 and IPv6)
# RouterOS dynamic DNS Update Script for deSEC
# ============================================
# make global to preserve IP and IPv4 address across script executions
:global ipddns
:global ipv6ddns
:local ddnshost "myhost.example.com"
:local token "MY_TOKEN"
: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://update.dedyn.io/"
: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."
}
# update IPV4 and IPv6 addresses in a single API call
:do {
:local urlParams ""
:if (($ipv4error = false) and ($ipfresh != "")) do={
:set urlParams ("myipv4=$ipfresh")
}
:if ($urlParams != "") do={
:set urlParams ($urlParams . "&")
}
:set urlParams ($urlParams . "myipv6=$ipv6fresh")
:if ($urlParams = "") do={
:log warning "DDNS: Both IPv4 and IPv6 are empty or errored. Skipping update."
:return
}
:local headers ("Authorization: Token $token")
:local result [/tool fetch mode=https url=("$url?$urlParams&hostname=$ddnshost") output=user http-header-field="$headers" as-value]
:if ($result->"status" != "finished") do={
:log error "DDNS: Failed to send IP update."
} else {
:log info ("DDNS: Response from server: " . $result->"data")
:if (([:find ($result->"data") "good"] = 0) or ([:find ($result->"data") "nochg"] = 0)) do={
:if ($ipv4error = false) do={
:set ipddns $ipfresh
}
:if ($ipv6error = false) do={
:set ipv6ddns $ipv6fresh
}
}
}
} on-error={
:log error "DDNS: An error occurred while checking and updating the IP addresses."
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment