NTP-Governance, SSDP-Relay live, WLAN-Config zurueck unter Drift-Kontrolle
92/92 compliant, 0 Drifts (vorher 71/76 bei 19 Rules -- jetzt 23 Rules). NTP: die Wurzel war doppelt. Der Core hatte keinen eigenen Client, UND sein Server hielt Stratum 16 fest, weil er eingeschaltet wurde, bevor der Client synchron war. Der Test, der es aufgeklaert hat: branch einmal auf at.pool.ntp.org zeigen lassen -- 20 Sekunden bis synchronized, also war der Client heil und der Server schwieg. Jetzt im Template, per DHCP-Option 42 an alle Clients ausgeliefert und mit der Rule system-ntp ueberwacht. TP7.1: SSDP-Relay laeuft als LXC 108 auf pve, zweibeinig in VLAN10+40. User-bestaetigt: "sonos ist da!". core ether13 traegt dafuer jetzt beide VLANs. TP28: die APs trugen noch die komplette Standalone-WLAN-Config aus TP3 -- wirkungslos, aber sie haette als Soll totes Zeug zur Absicht erklaert. Abgeraeumt, ohne einen einzigen Client zu verlieren (30 vorher, 30 nachher). Die fuenf wifi-*-Features haengen jetzt am Core, dazu drei neue Rules (wifi-capsman, wifi-provisioning, wifi-cap). Gelernt: [find !dynamic] ist auf /interface wifi configuration ein SYNTAXFEHLER, kein Filter -- der erste Anlauf aenderte nichts und meldete trotzdem "Plan Completed". Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -80,10 +80,13 @@
|
||||
/interface bridge port add bridge=bridge comment=defconf interface=sfp-sfpplus2
|
||||
# ether4 = Wohnzimmer-Sideboard: 2026-08-13 von Trunk auf untagged VLAN40 gezogen (TP21.1/4).
|
||||
/interface bridge vlan add bridge=bridge untagged=ether1,ether2 vlan-ids=1
|
||||
/interface bridge vlan add bridge=bridge tagged=ether1,ether8,ether15 vlan-ids=10
|
||||
# ether13 (pve) traegt VLAN10 + VLAN40 seit 2026-08-18: der SSDP-Relay-LXC fuer die
|
||||
# macOS-Sonos-App braucht ein Bein in beiden (TP7.1). SSDP ist link-lokal mit TTL 1 —
|
||||
# ein Relay muss Mitglied beider Broadcast-Domaenen sein, Routing hilft nicht.
|
||||
/interface bridge vlan add bridge=bridge tagged=ether1,ether8,ether13,ether15 vlan-ids=10
|
||||
/interface bridge vlan add bridge=bridge tagged=ether8,ether13,ether15 vlan-ids=20
|
||||
/interface bridge vlan add bridge=bridge tagged=ether1,ether8,ether15 untagged=ether14 vlan-ids=30
|
||||
/interface bridge vlan add bridge=bridge tagged=ether1,ether8,ether15 untagged=ether2,ether3,ether4,ether5 vlan-ids=40
|
||||
/interface bridge vlan add bridge=bridge tagged=ether1,ether8,ether13,ether15 untagged=ether2,ether3,ether4,ether5 vlan-ids=40
|
||||
/interface bridge vlan add bridge=bridge tagged=ether1,ether8,ether15 vlan-ids=50
|
||||
/interface bridge vlan add bridge=bridge tagged=ether1,ether8,ether15 vlan-ids=90
|
||||
/interface bridge vlan add bridge=bridge tagged=ether8,ether15,bridge vlan-ids=99
|
||||
@@ -124,7 +127,7 @@
|
||||
/ip dhcp-server add address-pool=pool-v{{ v.id }} comment={{ v.name }} interface=vlan{{ v.id }} lease-time={{ v.lease }} name=dhcp-v{{ v.id }}
|
||||
{% endfor %}
|
||||
{% for v in vlans %}
|
||||
/ip dhcp-server network add address=10.40.{{ v.id }}.0/24 dns-server=10.40.{{ v.id }}.1 domain=bf.lan gateway=10.40.{{ v.id }}.1
|
||||
/ip dhcp-server network add address=10.40.{{ v.id }}.0/24 dns-server=10.40.{{ v.id }}.1 domain=bf.lan gateway=10.40.{{ v.id }}.1 ntp-server=10.40.{{ v.id }}.1
|
||||
{% endfor %}
|
||||
/ip dhcp-server option add code=6 name="dns 1.1.1.1" value=0x01010101
|
||||
|
||||
@@ -142,6 +145,73 @@
|
||||
# Artefakt: routeros/tp23-stufe1-doh-core.rsc
|
||||
/ip dns set allow-remote-requests=yes mdns-repeat-ifaces=vlan10,vlan20,vlan40,vlan30,vlan90 servers=1.1.1.1 use-doh-server=https://px35ynlol3.cloudflare-gateway.com/dns-query verify-doh-cert=yes
|
||||
|
||||
# [6a] ZEIT. Der Core ist die Zeitquelle des Standorts — und braucht dafuer selbst eine.
|
||||
# Vor dem 2026-08-18 war /system ntp client AUS und der Server ebenfalls: die anderen drei
|
||||
# Geraete zeigten auf 10.40.99.1 ins Leere (`status: waiting`), ap2 war 17 h versetzt.
|
||||
# ⚠️ Ein NTP-Server mit `use-local-clock=no` und unsynchronisiertem Client liefert Stratum 16,
|
||||
# das jeder Client verwirft — Server einschalten allein reicht also NICHT.
|
||||
# Die Clients bekommen den Server zusaetzlich per DHCP (ntp-server=, s. [5]).
|
||||
# Schreibweise flach-einzeilig, weil das GC-Backup so ablegt (nicht im Sektions-Stil von /export).
|
||||
/system ntp client set enabled=yes
|
||||
/system ntp client servers add address=time.cloudflare.com
|
||||
/system ntp client servers add address=at.pool.ntp.org
|
||||
/system ntp server set enabled=yes
|
||||
|
||||
# [6b] WLAN — CAPsMAN. Seit TP28 (2026-08-17) ist der Core der Manager und ap1/ap2
|
||||
# sind reine CAPs. Die fuenf wifi-*-ComplianceFeatures gehoeren deshalb HIERHER
|
||||
# und nicht mehr in den AP-Zweig; auf den APs ist die entsprechende Config
|
||||
# abgeraeumt worden (sie war nach dem Cutover nur noch wirkungsloser Rest).
|
||||
#
|
||||
# 🔴 SECURITY IST NICHT DEPLOYBAR. Die Passphrasen stehen hier als
|
||||
# "<<REDACTED>>", weil TP22-Regel 1 maskierte Sektionen generell vom Push
|
||||
# ausschliesst. Ein gruener Compliance-Haken auf `wifi-security` beweist
|
||||
# deshalb NUR, dass Soll und Ist dieselbe Maske tragen — er beweist NICHT,
|
||||
# dass die Passphrasen stimmen und schon gar nicht, dass die Sektion
|
||||
# ausgerollt werden koennte. Wer sie wirklich aendern will, macht das am
|
||||
# Geraet und liest die Werte per REST zurueck
|
||||
# (`GET http://10.40.99.1/rest/interface/wifi/security`, s. TP28) —
|
||||
# NICHT aus `wlan-psks.env` oder den drei alten Bring-up-Dateien, die
|
||||
# voneinander abgeschrieben sind und schon einmal 20 Shellys aus dem Netz
|
||||
# geworfen haben.
|
||||
#
|
||||
# Literal-Block wie die L2-Fabric: Radio-MACs und Kanalzuordnung sind
|
||||
# geraetegebunden und in Nautobot nicht modelliert. Aenderungen daran sind
|
||||
# bewusst sichtbare Template-Aenderungen.
|
||||
/interface wifi channel add band=5ghz-ax frequency=5180 name=ch-5g-ap1 width=20/40mhz
|
||||
/interface wifi channel add band=5ghz-ax frequency=5220 name=ch-5g-ap2 width=20/40mhz
|
||||
/interface wifi channel add band=2ghz-ax frequency=2412 name=ch-2g-ap1 width=20mhz
|
||||
/interface wifi channel add band=2ghz-ax frequency=2462 name=ch-2g-ap2 width=20mhz
|
||||
/interface wifi datapath add bridge=bridge name=dp-main vlan-id=10
|
||||
/interface wifi datapath add bridge=bridge name=dp-infra vlan-id=20
|
||||
/interface wifi datapath add bridge=bridge name=dp-iot vlan-id=30
|
||||
/interface wifi datapath add bridge=bridge name=dp-media vlan-id=40
|
||||
/interface wifi datapath add bridge=bridge name=dp-untrusted vlan-id=50
|
||||
/interface wifi datapath add bridge=bridge name=dp-guest vlan-id=90
|
||||
/interface wifi security add authentication-types=wpa3-psk ft=yes ft-over-ds=yes name=sec-main passphrase="<<REDACTED>>"
|
||||
/interface wifi security add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=sec-infra passphrase="<<REDACTED>>"
|
||||
/interface wifi security add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=sec-iot passphrase="<<REDACTED>>"
|
||||
/interface wifi security add authentication-types=wpa2-psk,wpa3-psk ft=no name=sec-media passphrase="<<REDACTED>>"
|
||||
/interface wifi security add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=sec-untrusted passphrase="<<REDACTED>>"
|
||||
/interface wifi security add authentication-types=wpa2-psk,wpa3-psk disabled=no ft=no name=sec-guest passphrase="<<REDACTED>>"
|
||||
/interface wifi configuration add country=Austria datapath=dp-infra mode=ap name=cfg-infra security=sec-infra ssid=dirtyvader-infra
|
||||
/interface wifi configuration add country=Austria datapath=dp-iot mode=ap name=cfg-iot security=sec-iot ssid=dirtyvader-iot
|
||||
/interface wifi configuration add country=Austria datapath=dp-media mode=ap name=cfg-media security=sec-media ssid=dirtyvader-media
|
||||
/interface wifi configuration add country=Austria datapath=dp-untrusted mode=ap name=cfg-untrusted security=sec-untrusted ssid=dirtyvader-untrusted
|
||||
# st-guest hat eine EIGENE neighbor-group: mit bf-main wuerde 802.11k den Gaesten
|
||||
# BSSIDs einer SSID melden, auf die sie gar nicht assoziieren koennen (TP28).
|
||||
/interface wifi steering add name=st-main neighbor-group=bf-main rrm=yes wnm=yes
|
||||
/interface wifi steering add name=st-guest neighbor-group=bf-guest rrm=yes wnm=yes
|
||||
/interface wifi configuration add channel=ch-5g-ap1 country=Austria datapath=dp-main mode=ap name=cfg-main-5g-ap1 security=sec-main ssid=dirtyvader-main steering=st-main
|
||||
/interface wifi configuration add channel=ch-5g-ap2 country=Austria datapath=dp-main mode=ap name=cfg-main-5g-ap2 security=sec-main ssid=dirtyvader-main steering=st-main
|
||||
/interface wifi configuration add channel=ch-2g-ap1 country=Austria datapath=dp-main mode=ap name=cfg-main-2g-ap1 security=sec-main ssid=dirtyvader-main steering=st-main
|
||||
/interface wifi configuration add channel=ch-2g-ap2 country=Austria datapath=dp-main mode=ap name=cfg-main-2g-ap2 security=sec-main ssid=dirtyvader-main steering=st-main
|
||||
/interface wifi configuration add country=Austria datapath=dp-guest mode=ap name=cfg-guest security=sec-guest ssid=dirtyvader-guest steering=st-guest
|
||||
/interface wifi capsman set ca-certificate=auto certificate=auto enabled=yes interfaces=vlan99 upgrade-policy=none
|
||||
/interface wifi provisioning add action=create-dynamic-enabled comment="ap1 5GHz" master-configuration=cfg-main-5g-ap1 radio-mac=D0:EA:11:4D:40:E5 slave-configurations=cfg-media,cfg-untrusted,cfg-guest
|
||||
/interface wifi provisioning add action=create-dynamic-enabled comment="ap1 2.4GHz" master-configuration=cfg-main-2g-ap1 radio-mac=D0:EA:11:4D:40:E6 slave-configurations=cfg-iot,cfg-media,cfg-untrusted,cfg-guest
|
||||
/interface wifi provisioning add action=create-dynamic-enabled comment="ap2 5GHz" master-configuration=cfg-main-5g-ap2 radio-mac=D0:EA:11:4D:40:3E slave-configurations=cfg-media,cfg-untrusted,cfg-guest
|
||||
/interface wifi provisioning add action=create-dynamic-enabled comment="ap2 2.4GHz" master-configuration=cfg-main-2g-ap2 radio-mac=D0:EA:11:4D:40:3F slave-configurations=cfg-iot,cfg-media,cfg-untrusted,cfg-guest
|
||||
|
||||
# Kanonischer Mgmt-Nummernplan (User-Bestaetigung 2026-08-13, verbindlich):
|
||||
# core .99.1 | branch .99.2 | ap1 .99.11 | ap2 .99.12
|
||||
/ip dns static add address=10.40.99.1 comment="core = GW/Router" name=router.lan type=A
|
||||
@@ -205,6 +275,8 @@
|
||||
/interface vlan add comment=MGMT interface=bridge name=vlan99 vlan-id=99
|
||||
/ip address add address={{ obj.primary_ip4.address }} comment=TP21-mgmt-target interface=vlan99 network={{ obj.primary_ip4.host.split(".")[:3] | join(".") }}.0
|
||||
/ip dns set servers=10.40.99.1
|
||||
/system ntp client set enabled=yes
|
||||
/system ntp client servers add address=10.40.99.1
|
||||
/ip route add comment=TP21-default dst-address=0.0.0.0/0 gateway=10.40.99.1
|
||||
|
||||
# L2-FABRIC — wie beim Core ein Literal-Block (Begruendung dort).
|
||||
@@ -254,48 +326,21 @@
|
||||
# Referenz: routeros/state-backups/ap1-gc-backup-scrubbed-20260813.cfg
|
||||
# =====================================================================================
|
||||
|
||||
# [1] CHANNELS — Frequenz aus der Kanalnummer gerechnet (eine Quelle der Wahrheit)
|
||||
{% for r in ap.radios %}
|
||||
{% set ch = ap.channels[r.key] %}
|
||||
{% set freq = (5000 + 5 * ch) if r.key == "5g" else (2407 + 5 * ch) %}
|
||||
/interface wifi channel add band={{ r.band }} frequency={{ freq }} name=ch-{{ r.key }} width={{ r.width }}
|
||||
{% endfor %}
|
||||
|
||||
# [2] DATAPATH — je Zone ein VLAN-Tag. OHNE datapath egressiert die SSID ungetaggt
|
||||
# in VLAN1 (das war das TP3.1-Leck) -> jede Zone MUSS hier auftauchen.
|
||||
{% for z in ap.zones %}
|
||||
/interface wifi datapath add bridge={{ ap.bridge }} name=dp-{{ z.name }} vlan-id={{ z.vlan }}
|
||||
{% endfor %}
|
||||
|
||||
# [3] SECURITY — Passphrasen tragen die Backup-Maske aus TP22 Schritt 0.
|
||||
# ft-over-ds schreibt RouterOS nur, wenn ft=yes.
|
||||
{% for z in ap.zones %}
|
||||
/interface wifi security add authentication-types={{ z.auth }} ft={{ z.ft }}{% if z.ft == "yes" %} ft-over-ds={{ z.ft_over_ds }}{% endif %} name=sec-{{ z.name }} passphrase="<<REDACTED>>"
|
||||
{% endfor %}
|
||||
|
||||
# [3b] STEERING — 802.11k (rrm: Neighbor Reports) + 802.11v (wnm: BSS Transition).
|
||||
# OHNE das klebt der Client am sterbenden AP, bis die Verbindung abreisst; 802.11r/FT
|
||||
# macht die Uebergabe nur SCHNELL, es loest sie nicht aus. Genau das fehlte nach dem
|
||||
# TP3-Rebuild auf beiden APs und hat Videocalls beim Durchgehen abgerissen (TP3.3).
|
||||
# `neighbor-group` ist site-weit identisch -- nur dann gelten ap1/ap2 als Nachbarn.
|
||||
# Konstante statt ConfigContext: es gibt genau EINE Roaming-Domain pro Standort.
|
||||
{% set steering = {"name": "st-main", "neighbor_group": "bf-main"} %}
|
||||
/interface wifi steering add name={{ steering.name }} neighbor-group={{ steering.neighbor_group }} rrm=yes wnm=yes
|
||||
|
||||
# [4] CONFIGURATION — main sitzt auf den Master-Radios und bringt den Channel mit
|
||||
# (je Band eine configuration); alle anderen Zonen sind Slave-VAPs ohne channel=.
|
||||
# steering= haengt nur an den Master-Zonen (RouterOS exportiert es nach ssid=).
|
||||
{% for z in ap.zones %}
|
||||
{% if z.master %}
|
||||
{% for r in ap.radios %}
|
||||
{% if r.key in z.bands %}
|
||||
/interface wifi configuration add channel=ch-{{ r.key }} country={{ ap.country }} datapath=dp-{{ z.name }} mode=ap name=cfg-{{ z.name }}-{{ r.key }} security=sec-{{ z.name }} ssid={{ z.ssid }} steering={{ steering.name }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
/interface wifi configuration add country={{ ap.country }} datapath=dp-{{ z.name }} mode=ap name=cfg-{{ z.name }} security=sec-{{ z.name }} ssid={{ z.ssid }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
# [1] WLAN — ein CAP haelt KEINE eigene WLAN-Config.
|
||||
# Bis 2026-08-18 rendert dieser Zweig Kanaele, Datapaths, Security, Configurations
|
||||
# und Steering. Das war der Standalone-Stand von TP3; seit dem CAPsMAN-Cutover
|
||||
# (TP28, 2026-08-17) kommen all diese Objekte vom Manager `crs326-core` und werden
|
||||
# auf dem CAP als DYNAMISCHE Interfaces angelegt. Die statischen Reste auf ap1/ap2
|
||||
# waren danach wirkungslos — aber sie standen weiter in der Config und haetten,
|
||||
# als Soll gerendert, totes Zeug zur Absicht erklaert (dasselbe Argument wie bei
|
||||
# den defconf-Firewallregeln in TP26). Sie sind am 2026-08-18 abgeraeumt worden.
|
||||
#
|
||||
# Die fuenf wifi-*-ComplianceFeatures greifen jetzt am Core, s. dort [6b].
|
||||
# Hier bleibt genau eine Zeile: der CAP muss wissen, wo er suchen soll.
|
||||
# ⚠️ `discovery-interfaces` ist Layer-2-Discovery — der Manager wird ueber seine
|
||||
# MAC gefunden, nicht ueber eine IP. Deshalb muessen MNDP (udp/5678) und CAPWAP
|
||||
# (udp/5246-5247) in der input-Kette des Core offen bleiben (TP5 Etappe 4).
|
||||
/interface wifi cap set discovery-interfaces=vlan{{ ap.mgmt.vlan }} enabled=yes
|
||||
|
||||
# [4b] BRIDGE-PORTS — ether2 fehlt bewusst: seit der Uplink-Umstellung auf ether1 (PoE)
|
||||
# ist er KEIN Bridge-Port mehr. ether1 traegt kein comment=defconf (beim Rebuild
|
||||
@@ -327,6 +372,10 @@
|
||||
/interface list member add comment=defconf interface={{ ap.bridge }} list=LAN
|
||||
/interface list member add interface=vlan{{ ap.mgmt.vlan }} list=LAN
|
||||
/ip dns set allow-remote-requests=yes servers={{ ap.mgmt.gateway }}
|
||||
# Zeitquelle ist der Core. Vor dem 2026-08-18 lief dort kein NTP-Server — ap2 war deshalb 17 h
|
||||
# versetzt und seine Logs fuer jede geraeteuebergreifende Korrelation wertlos.
|
||||
/system ntp client set enabled=yes
|
||||
/system ntp client servers add address={{ ap.mgmt.gateway }}
|
||||
/interface vlan add interface={{ ap.bridge }} name=vlan{{ ap.mgmt.vlan }} vlan-id={{ ap.mgmt.vlan }}
|
||||
/ip address add address={{ obj.primary_ip4.address }} interface=vlan{{ ap.mgmt.vlan }} network={{ mgmt_host.split(".")[:3] | join(".") }}.0
|
||||
/ip route add comment="mgmt default via core" dst-address=0.0.0.0/0 gateway={{ ap.mgmt.gateway }}
|
||||
|
||||
Reference in New Issue
Block a user