Zwei Firewalls, ein Schema — Aufräumen nach der Kopplung
Warum nach der Kopplung von Heimnetz und Rechenzentrum alle Namen auf beiden OPNsense neu vergeben wurden, wie das offline in der config.xml ging, welche Namensregeln OPNsense wirklich durchsetzt und was beim Aufräumen sonst noch auffiel.
Seit dem 2. November sprechen zwei OPNsense miteinander: die im Rechenzentrum und die zu Hause. Am Tag danach fiel auf, was das bedeutet. Dieselbe Maschine hieß auf der einen Seite mailcow00_mai_Host, auf der anderen HOST_MAILCOW. Regeln trugen mal eine Nummer, mal einen Satz, mal gar nichts. Im HAProxy hießen Server BE_…, Backends BEP_… und Bedingungen IF …. Jede Seite war für sich gewachsen und in sich halbwegs schlüssig. Zusammen war es Wildwuchs.
Ein Gegenstand, ein Name
Die Regel ist einfach: Was auf beiden Firewalls vorkommt, heißt auf beiden gleich und hat dieselbe Beschreibung. Daraus folgt der Rest:
| Was | Schema | Beispiel |
|---|---|---|
| Alias für Hosts | HOST_<name> |
HOST_SRVJUMP00 |
| Alias für Netze | NET_<name> |
NET_HOME_ADMIN |
| Alias für Ports | PORT_<dienst> |
PORT_MAIL_CLIENT |
| Regelbeschreibung | <ZONE>: <Dienst> <Quelle> -> <Ziel> |
ADMIN: SSH Zone -> srvjump00 |
| NAT | 1:1 <host> <-> .<VIP>, OUT: <von> -> <nach> als <Adresse> |
|
| HAProxy | fe_, be_, srv_, host_, src_, use_, deny_unless_ |
use_be_gitlab00 |
Beschreibungen stehen ohne Umlaute, damit sie in pfctl, im Log und in jeder SSH-Sitzung gleich aussehen. Die Regeln in der WireGuard-Gruppe heißen WG-RW: für die Geräte unterwegs und WG-S2S: für die Kopplung. Nummern wie „S2S: 7“ sind weg. Sie sagten nichts und mussten bei jeder neuen Regel im Kopf mitgeführt werden.
Offline umbenennen statt klicken
Im Rechenzentrum sind es gut 200 Regeln, über 80 Aliase und rund 90 HAProxy-Objekte. Das von Hand in der Oberfläche umzubenennen, hätte einen Tag gekostet und Tippfehler produziert. Stattdessen habe ich die exportierte config.xml mit einem kleinen Skript bearbeitet:
- Aliase werden nur in den Feldern umbenannt, in denen sie vorkommen können: Quelle, Ziel, Ports und Inhalt anderer Aliase. Ein simples Suchen und Ersetzen über die ganze Datei hätte auch Beschreibungen und Zertifikate getroffen.
- HAProxy verknüpft seine Objekte über interne IDs. Dort lassen sich die Namen gefahrlos ändern.
- Vor dem Einspielen ein Abgleich: Jede Regel muss nach dem Umbenennen inhaltlich dieselbe sein wie vorher. Jeder Verweis muss auf einen existierenden Alias zeigen, und kein alter Name darf übrig bleiben.
Erst danach kam die Datei per Restore auf die Firewall, mit dem vorherigen Export als Rückweg.
Was OPNsense bei Namen wirklich erlaubt
Die Oberfläche prüft Namen erst beim Speichern. Eine bearbeitete Konfiguration läuft also problemlos, bis jemand das Objekt das nächste Mal anfasst. Deshalb habe ich im Quellcode nachgesehen statt zu raten, und tatsächlich einen eigenen Fehler gefunden:
| Objekt | Erlaubt |
|---|---|
| Firewall-Alias | Buchstabe oder _ am Anfang, dann Buchstaben, Ziffern, _; höchstens 31 Zeichen; keine pf-Schlüsselwörter und keine Dienstnamen wie ssh oder https |
| HAProxy Frontend, Backend, Server | Buchstaben, Ziffern, . _ - |
| HAProxy-Bedingung und -Aktion | alles außer Tab, , ; . [ ] { }, also kein Punkt |
| WireGuard-Instanz und -Peer | Buchstaben, Ziffern, . _ -, bis 64 Zeichen |
Meine erste Fassung nannte die Bedingungen host_git.oss-host.net. Das wäre beim nächsten Bearbeiten abgelehnt worden. Jetzt heißen sie host_git-oss-host-net.
Was beim Aufräumen sonst auffiel
Eine Freigabe war weiter offen als gedacht. Eine Regel aus der Zeit vor der Kopplung sollte einem einzelnen Gerät zu Hause Zugriff auf einen Dienst im Rechenzentrum geben. Als Quelle stand dort aber „any“. Seit das Gerät den Tunnel nutzt, wurde die Regel ohnehin nicht mehr gebraucht. Sie ist jetzt aus. Gefunden habe ich sie nur, weil beim Umbenennen jede Regel einmal angesehen werden musste.
Gruppenregeln kommen vor Interface-Regeln. Eine Freigabe für den Tunnel lag auf dem einzelnen WireGuard-Interface, die Sperre davor in der Interface-Gruppe. OPNsense wertet Gruppen zuerst aus, die Freigabe kam also nie zum Zug.
„Apply“ heißt nicht „geladen“. Eine neue Regel stand in der Oberfläche, die Verbindungen liefen trotzdem in die Standard-Sperre. pfctl -sr zeigte: Die Regel war nicht im laufenden Regelwerk. Erst configctl filter reload lud sie. Seitdem prüfe ich neue Regeln dort und nicht in der Oberfläche.
pfctl spricht in Dienstnamen. Wer nach 993 sucht, findet nichts, denn dort steht imaps. Port 853 heißt domain-s. Das kostet beim ersten Mal ein paar Minuten Verwirrung.
Zonen als Netz, nicht als Liste. Im Rechenzentrum gab es für jede Zone einen Alias mit den erlaubten Maschinen: Eine neue VM durfte nichts, bis sie eingetragen war. Das ist sauber, kostet aber bei jeder VM einen zweiten Handgriff. Die Regeln nutzen jetzt das Netz der Schnittstelle. Zu Hause war das ohnehin so, weil Handys und Gäste kommen und gehen.
DNS lässt sich nicht mehr umgehen
Zum Schluss der erste Teil des Werbefilters zu Hause. In den Netzen für Familie, Fernseher, Smart Home und Gäste landet jede DNS-Anfrage bei der eigenen Firewall, auch wenn ein Gerät fest einen fremden Resolver eingetragen hat. DNS über TLS nach außen ist gesperrt. Mein eigenes Netz bleibt bewusst ausgenommen, damit ich dort weiter fremde Resolver fragen kann, wenn ich einen Fehler suche.
Das Protokoll zeigte schon in der ersten Minute, wer das versucht: Der Fernseher fragt die Firewall, ob sie DNS über TLS kann, und nimmt dann normales DNS. Home Assistant hat einen eingebauten Rückfall auf einen öffentlichen Resolver über TLS, der nun ins Leere läuft. Beides ist harmlos. Ohne die Sperre wären beide Anfragen am Filter vorbeigegangen.
Und dann der Filter selbst
Am selben Vormittag kam die Blockliste dazu, im Unbound der Firewall und nur für dieselben vier Netze. Mein erster Reflex war, möglichst viele Listen anzuhaken: AdGuard, EasyList, EasyPrivacy, Steven Black, YoYo und HaGeZi. Das bringt wenig, denn HaGeZi sammelt die meisten dieser Quellen schon selbst ein. Jede weitere Liste bringt vor allem ihre eigenen Fehlalarme mit, und die Ausnahmen der einen Liste heben die Sperren der anderen nicht auf.
Übrig geblieben sind zwei: HaGeZi Multi PRO gegen Werbung und Tracking und die HaGeZi-Liste gegen DNS über HTTPS, VPN- und Proxy-Dienste. Erst die zweite schließt die Lücke, die nach der Sperre von DNS über TLS noch offen war: Ein Browser, der seine Namen über HTTPS bei einem fremden Anbieter auflöst, findet diesen Anbieter jetzt nicht mehr.
Ein Testfall hat mich kurz in die Irre geführt. doubleclick.net und ad.doubleclick.net kamen ungefiltert zurück. Das ist Absicht der Liste, denn über diese Namen laufen auch die Klicks auf Anzeigen in der Suche. Gesperrt sind die Namen, über die die Werbung tatsächlich ausgeliefert wird. Wer prüfen will, ob ein Filter greift, sollte nicht den bekanntesten Namen nehmen, sondern einen, der sicher auf der Liste steht.
Was ich daraus mitnehme
Namen sind Dokumentation. Eine Regel, die WG-S2S: Mail Heim-ADMIN -> mailcow00 heißt, erklärt sich im Live-Log von selbst. Eine Regel „S2S: 8“ braucht eine Tabelle daneben.
Aufräumen ist auch eine Prüfung. Die zu weit gefasste Freigabe hat kein Monitoring gemeldet und kein Test gefunden. Sie fiel auf, weil jede Regel einen neuen Namen brauchte und dabei jemand hinsah.
Erst in der Quelle nachsehen, dann umbenennen. Was die Oberfläche durchlässt und was eine bearbeitete Datei enthalten darf, ist nicht dasselbe. Der Blick in den Quellcode hat einen Fehler gefunden, bevor er beim nächsten Bearbeiten aufgefallen wäre.