Last active
June 19, 2022 13:03
-
-
Save kroteau/de05fa01c367a3329f85f99c0930e817 to your computer and use it in GitHub Desktop.
Mikrotik DuckDns Updater w/IPv6 support
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
# inspired by https://github.com/beeyev/Mikrotik-Duckdns-Dynamic-IP-Updater | |
# DuckDNS Sub Domain | |
:local duckdnsSubDomain "CHANGEME" | |
# DuckDNS Token | |
:local duckdnsToken "CHANGEME" | |
# Online services which respond with your IPv4 | |
:local ipv4detectList {"https://api4.my-ip.io/ip.txt"; "http://v4.ipv6-test.com/api/myip.php"} | |
# Online services which respond with your IPv6 | |
:local ipv6detectList {"https://api6.my-ip.io/ip.txt"; "http://v6.ipv6-test.com/api/myip.php"} | |
#=============END OF CONFIG=============== | |
:local previousIP; :local currentIP; :local currentIPv6; :local duckdnsFullDomain "$duckdnsSubDomain.duckdns.org"; | |
# Function to resolve external IP using public web services | |
:local getip do={ | |
# Parameters: 1 - list of urls | |
:local extIP; | |
:foreach url in=$1 do={ | |
:do { :set extIP ([/tool fetch url=$url output=user as-value]->"data")} on-error={ :log error "DDNS: Service $url failed" }; | |
if ( [:len "$extIP"]>0 ) do={ :return $extIP }; | |
}; | |
}; | |
# Detect IPv6 (grab default route from ipv4 interface, search for a global ipv6 address on the same interface) | |
:local hasIPv6 ([:len [/ipv6 address find where interface=[/ip route get number=[/ip route find where dst-address="0.0.0.0/0" && active=yes ] gateway] global]] > 0); | |
# Resolve current DuckDNS subdomain ipv4 address since Mikrotik is limited on resolving ipv6 | |
:do {:set previousIP [:resolve $duckdnsFullDomain]} on-error={ :log warning "DDNS: Could not resolve dns name $duckdnsFullDomain"}; | |
# Detect router's public IPv4 address | |
:set currentIP [$getip $ipv4detectList]; | |
# Detect router's public IPv6 address | |
if ($hasIPv6 = true) do={ | |
:set currentIPv6 [$getip $ipv6detectList]; | |
}; | |
# Intentionally using put here instead of log debug, running the script from console/ssh outputs values w/o modifying the source | |
:put "DDNS: Resolved IPv4 ($previousIP), Detected IPv4 ($currentIP), HasIPv6 ($hasIPv6), Detected IPv6 ($currentIPv6)" | |
# Push DDNS update if IPv4 has changed | |
:if ($currentIP != $previousIP) do={ | |
:local httpResponse; :local httpRequestUrl "https://www.duckdns.org/update\?domains=$duckdnsSubDomain&token=$duckdnsToken&verbose=true&ip=$currentIP"; | |
# In case of IPv4&IPv6 update expand request url with ipv6 parameter and value | |
if ($hasIPv6 = true) do={ | |
:set httpRequestUrl "$httpRequestUrl&ipv6=$currentIPv6" | |
}; | |
:put "GET request: $httpRequestUrl" | |
# Make http request based on the settings | |
:do {:set httpResponse ([/tool fetch url=$httpRequestUrl output=user as-value]->"data")} on-error={ :log error "DDNS: request to duckdns server failed"}; | |
# Log abnormal responses | |
:if ([:pick $httpResponse 0 2] != "OK") do={ | |
:log warning "DDNS: abnormal response ($httpResponse)" | |
}; | |
} else={ :put "DDNS: No update needed"}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment