# ============================================================================= # TP10 — Cloudflare-DDNS-Updater fuer bf4.emsenhuber.net # ============================================================================= # Zweck: der WG-Hub-Endpoint der Spokes (fm/dw) ist bf4.emsenhuber.net. Der # A-Record muss der Liwest-Public-IP des Core folgen. Heute manuell gepflegt. # # BASIS: bajodel/mikrotik-cloudflare-dns (MIT, Copyright (c) 2025 bajodel) # https://github.com/bajodel/mikrotik-cloudflare-dns # Aenderungen ggue. dem Original (Christoph-Entscheid 2026-10-03): # 1. IP kommt aus der DHCP-Lease (client1/vlan100), NICHT von Echo-Diensten. # Liwest ist die Quelle, kein Dritter; kein Cloudflare im Pfad. # 2. check-certificate=yes (Original-Default war false -> Token ungeprueft). # 3. Nur EIN Record (bf4), Konfiguration auf das Noetige reduziert. # # Token: liegt NICHT hier, sondern als globale Script-Variable `cfDdnsToken`. # Einmalig setzen per SSH (siehe docs/teilprojekte.md ### TP10). # # Installation: /import file=tp10-ddns-cf-updater.rsc # danach /system scheduler add ... (siehe unten) # ============================================================================= # ---- Konfiguration ---------------------------------------------------------- :local DnsRcName "bf4.emsenhuber.net" :local DnsZoneID "1b5bc02fdf61b6b989afde543f3f4134" # CF_ZONE_ID aus mcp/cloudflare/.env :local DnsRcrdID "dba9d9ec3b261fdb314c0f83e4e62f0d" :local RecordTTL "120" # wie der bestehende Record :local RecordProxied "false" # WG-Endpoint: NICHT proxied :local VerboseLog false :local WanDhcpName "client1" # ----------------------------------------------------------------------------- # Token aus /system script environment holen (NIE im Skriptkopf, NIE per :global). # Grund (2026-10-03): :global cfDdnsToken liest im Skript-Kontext "nothing", obwohl # /system script environment cfDdnsToken gesetzt ist. CLI-Scope und Skript-Scope sind # auf RouterOS 7.24 unterschiedlich. `/system script environment get` ist scope-unabhaengig. :do { :local tk "" :local found [/system script environment find name=cfDdnsToken] :if ([:len $found] > 0) do={ :set tk [/system script environment get [find name=cfDdnsToken] value] } :if ([:typeof $tk] = "") do={ :log error "[tp10-ddns] cfDdnsToken nicht gesetzt - Abbruch" :error "cfDdnsToken fehlt" } :global cfDdnsToken :set cfDdnsToken $tk } on-error={ :log error "[tp10-ddns] cfDdnsToken nicht lesbar - Abbruch" :error "cfDdnsToken fehlt" } # ---- WAN-IPv4 aus der DHCP-Lease (Quelle: Liwest, kein Dritter) ------------ :local CFWanIP4New "" :do { :local leaseAddr [/ip dhcp-client get [find name=$WanDhcpName] address] :if ([:typeof $leaseAddr] != "nothing") do={ # "90.146.33.177/24" -> "90.146.33.177" :local slashPos [:find $leaseAddr "/"] :if ($slashPos >= 0) do={ :set CFWanIP4New [:pick $leaseAddr 0 $slashPos] } else={ :set CFWanIP4New $leaseAddr } } } on-error={ :log error "[tp10-ddns] DHCP-Lease nicht lesbar ($WanDhcpName)" } :if ($CFWanIP4New = "") do={ :log warning "[tp10-ddns] Keine WAN-IP aus der Lease, naechster Lauf" } else={ # ---- Guard: nur oeffentliche IPv4 zulassen -------------------------------- # Faengt den Fall ab, dass DHCP Muell liefert (privat/CGNAT) -> kein Write. :local isPrivate false :if ([:pick $CFWanIP4New 0 3] = "10.") do={ :set isPrivate true } :if ([:pick $CFWanIP4New 0 8] = "192.168.") do={ :set isPrivate true } :if ([:pick $CFWanIP4New 0 7] = "172.16.") do={ :set isPrivate true } :if ([:pick $CFWanIP4New 0 8] = "100.64.0") do={ :set isPrivate true } # CGNAT 100.64/10 :if ($isPrivate) do={ :log error "[tp10-ddns] Lease liefert nicht-oeffentliche IP ($CFWanIP4New) - ABBRUCH, kein Write" } else={ # ---- Nur bei Abweichung schreiben (Idempotenz) -------------------------- :global CFWanIP4Cur :if ($CFWanIP4New != $CFWanIP4Cur) do={ :if ($VerboseLog) do={ :log info "[tp10-ddns] WAN-IP: $CFWanIP4Cur -> $CFWanIP4New" } # Kommentar am Record: Zeit + Geraet, wie im Original :local ds [/system clock get date] :local ts [/system clock get time] :local datetime ([:pick $ds 0 4] . "." . [:pick $ds 5 7] . "." . [:pick $ds 8 10] . "-" . [:pick $ts 0 2] . ":" . [:pick $ts 3 5]) :local CFComment ("$datetime by crs326-core") :local url "https://api.cloudflare.com/client/v4/zones/$DnsZoneID/dns_records/$DnsRcrdID/" :do { :local res [/tool fetch http-method=put mode=https url=$url check-certificate=yes output=user as-value http-header-field="Authorization: Bearer $cfDdnsToken,Content-Type: application/json" http-data="{\"type\":\"A\",\"name\":\"$DnsRcName\",\"content\":\"$CFWanIP4New\",\"ttl\":$RecordTTL,\"proxied\":$RecordProxied,\"comment\":\"$CFComment\"}"] :if (($res->"status") = "finished") do={ :log warning "[tp10-ddns] $DnsRcName -> $CFWanIP4New aktualisiert" :set CFWanIP4Cur $CFWanIP4New } else={ :log error "[tp10-ddns] Update fehlgeschlagen (status != finished)" } } on-error={ :log error "[tp10-ddns] Exception beim Cloudflare-Update - naechster Lauf" } } else={ :if ($VerboseLog) do={ :log info "[tp10-ddns] WAN-IP unveraendert ($CFWanIP4New)" } } } }