Zwölf Bridges, ein Trunk — der VLAN-Umbau auf dem Proxmox-Host
Wie aus zwölf Linux-Bridges mit /29-Netzen ein einziger VLAN-Trunk mit /24 je Dienst wurde — Vorgehen, Skripte, Stolpersteine mit OPNsense, Foreman und Puppet.
Bis zum 13. Oktober 2026 hing jedes Netz meiner Umgebung an einer eigenen Linux-Bridge: vmbr1 bis vmbr12, die Nummer der Bridge gleich der Nummer des Netzes, dazu eine eigene Netzwerkkarte der OPNsense je Bridge. Jedes Netz war ein /29 oder /28. Das hat gut funktioniert — und wurde mit jedem neuen Dienst ein Stück unhandlicher. An diesem Tag habe ich alles auf einen VLAN-Trunk umgestellt. Hier steht, wie, und wo es gehakt hat.
Warum überhaupt
Drei Dinge haben gestört:
- Ein neues Netz war ein Eingriff an drei Stellen. Bridge auf dem Host anlegen, der OPNsense eine weitere Netzwerkkarte geben, die Firewall dafür neu starten. Bei einer VM, die alles andere trägt, ist ein Neustart kein Nebenbei.
- /29 ist zu klein. Sechs nutzbare Adressen, davon eine für das Gateway. Ein zweiter Datenbankknoten, ein Testsystem, eine Handvergabe — schon wird es eng, und ein Netz nachträglich zu vergrößern heißt, jede Maschine darin anzufassen.
- FreeBSD nummeriert Netzwerkkarten nach Reihenfolge. Fällt eine Karte aus der VM-Konfiguration, rutschen alle dahinter um eins nach vorn — und die Zuordnung der Schnittstellen in der OPNsense zeigt plötzlich auf das falsche Netz.
Das Ziel
Zwei Bridges statt dreizehn — vmbr0 für das WAN bleibt, aus vmbr1 wird der Trunk, vmbr2 bis vmbr12 fallen weg:
| Bridge | Zweck |
|---|---|
vmbr0 |
WAN — der Uplink des Hosts und die WAN-Karte der OPNsense |
vmbr1 |
VLAN-Trunk für alle internen Netze, VLAN-aware |
Jedes Netz bekommt ein /24 und eine VLAN-ID nach einer festen Regel: VLAN-ID = 1000 + drittes Oktett. Das Netz 10.100.7.0/24 ist also VLAN 1007. Wer eine Adresse sieht, kennt das VLAN, ohne nachzuschlagen. Das Gateway ist immer .1, die bestehenden Maschinen behalten ihre Adresse.
Auf dem Host ist der Trunk eine einzige Bridge:
auto vmbr1
iface vmbr1 inet manual
bridge-ports none
bridge-stp off
bridge-fd 0
bridge-vlan-aware yes
bridge-vids 2-4094
Die Gäste hängen danach an vmbr1 mit einem Tag, die OPNsense ohne Tag — sie bekommt den ganzen Trunk und zerlegt ihn selbst.
Vorgehen
Ich habe den Umbau in einem Skript festgehalten, das drei Dinge kann: Vorschau, Ausführen und Rückbau. Die Vorschau zeigt für jede VM die alte und die neue Netzwerkzeile; erst wenn sie stimmt, wird ausgeführt. Vor jeder Änderung sichert das Skript die VM-Konfigurationen und schreibt ein Rückbau-Skript daneben.
Die Reihenfolge:
- Alle VMs herunterfahren. Ein Umbau am laufenden System hätte bedeutet, zwei Netzwelten gleichzeitig zu betreiben. Für eine private Umgebung ist eine geplante Pause ehrlicher als eine schlaue Übergangslösung.
- Netzwerkkarten umschreiben. Aus
bridge=vmbr7wirdbridge=vmbr1,tag=1007. Die MAC-Adresse bleibt dabei erhalten — sonst sähe jede Maschine eine neue Karte, und udev oder systemd-networkd vergäben andere Namen. - Alte Bridges entfernen, Netz auf dem Host neu laden.
- Zuerst die OPNsense starten und dort zwölf VLAN-Geräte auf der Trunk-Karte anlegen, die Schnittstellen neu zuordnen, jede auf /24.
- Dann die Gäste, einer nach dem anderen, und die Maske von /29 auf /24 setzen.
Der letzte Schritt lief von der Jump-Maschine aus für alle Hosts in einem Durchgang: Maske in /etc/network/interfaces per sed ändern, dann abgekoppelt systemctl restart networking — und warten, bis der Host per SSH wieder erreichbar ist und /24 meldet, bevor der nächste drankommt. Kein Neustart der Maschinen. Die Jump-Maschine selbst stand zuletzt in der Liste, weil das Skript dort läuft.
sudo nohup sh -c "sleep 1; systemctl restart networking" >/dev/null 2>&1 &
Das nohup mit der kurzen Pause ist nicht Zierde: Ohne es reißt die SSH-Sitzung beim Neuladen ab und nimmt den Befehl mit, bevor das Netz wieder oben ist.
Stolpersteine
VLAN-Hardwarefilter in der OPNsense. Auf virtio-Karten ist der Hardware-VLAN-Filter eine bekannte Fehlerquelle: Pakete einzelner VLANs kommen dann einfach nicht an, ohne dass irgendwo ein Fehler steht. Ich habe ihn unter Interfaces → Settings abgeschaltet, bevor ich das erste VLAN angelegt habe — eine Fehlersuche weniger.
Die Kartennummerierung. Nach dem Entfernen der alten Karten war die Trunk-Karte nicht mehr dort, wo sie vorher war. Die Zuordnung lässt sich nur sicher über die MAC-Adresse prüfen, nicht über den Namen vtnetN. Ich habe die MAC vorher notiert — das hat die Suche auf eine Minute verkürzt.
Mehrere Warteschlangen. Eine Karte, über die jetzt zwölf Netze laufen, bekommt mehr als eine Queue (queues=4). Sonst hängt der gesamte interne Verkehr an einem einzigen CPU-Kern der Firewall.
Foreman. Die Subnetze in Foreman mussten nachziehen: Maske, VLAN-ID, für IPv6 nur die VLAN-ID. Mein Skript dafür scheiterte zunächst an etwas Banalem — hammer liefert seine JSON-Ausgabe in der eingestellten Sprache, die Schlüssel hießen also nicht Id, sondern deutsch. Am Ende waren es ein paar direkte hammer subnet update-Aufrufe. Einige Subnetze verweigerten das Update außerdem mit dem Hinweis, der zugeordnete BMC-Proxy habe kein BMC-Feature — ein Überbleibsel aus einer alten Zuordnung, das sich am schnellsten über die Rails-Konsole entfernen ließ.
Puppet-Routen. Ein Hook, der beim Hochfahren der Schnittstelle alle statischen Routen löscht und aus der Puppet-Konfiguration neu setzt, verhielt sich genau so, wie er sollte — nur standen in der Konfiguration noch die alten, kleinteiligen Routen. Aus vielen /29-Routen wurde eine einzige auf das ganze interne /16.
Ergebnis
Nach dem Umbau lief eine Prüfung über alle Maschinen: Adresse und Maske, DNS, Zeit, fehlgeschlagene systemd-Einheiten, Puppet-Lauf, die wichtigen Wege quer durch die Netze (Puppet, Metriken, Protokolle, Monitoring) und jeder Dienst einzeln. Alles grün.
Ein neues Netz ist jetzt ein VLAN-Gerät in der OPNsense und ein Tag an der VM. Kein Neustart der Firewall, keine neue Bridge, keine verschobene Kartennummer.
Was ich wieder so machen würde
- Vorschau vor jedem Schritt. Ein Skript, das zuerst zeigt, was es tun wird, kostet zehn Minuten mehr und spart die eine Stunde, in der man sonst rät.
- Rückbau schreiben, bevor man ihn braucht. Gebraucht habe ich ihn nicht. Aber mit ihm im Rücken arbeitet man ruhiger.
- Eine Regel statt einer Tabelle. VLAN-ID aus dem Oktett abzuleiten heißt, dass es keine zweite Wahrheit gibt, die auseinanderlaufen kann.