OpnSense Erfahrungencongenio

* Motivation

In München gibt es jetzt vielerorts Glasfaser des Providers M-Net. Wir haben daher unseren Internetanschluss auf Glasfaser umgestellt. Aufgrund der mit 600/200 MBit/s gestiegenen Geschwindigkeit ergibt sich die Notwendigkeit, einige Probleme mit dem vorhandenen Router (Ubiquiti Edgerouter 4) zu lösen.

Der ER-4 ist performancemäßig nicht in der Lage, bei annähernd Gigabit-Geschwindigkeit zu routen, zumindest nicht mit eingeschaltetem QoS, das wir aufgrund der -> Bufferbloat-Thematik nutzen wollten. Die mit QoS maximal erzielbare Geschwindigkeit lag bei ca. 200 MBit/s. Ohne QoS ist viel mehr möglich, da dann Hardware-Offloading genutzt wird.

Außerdem hatten wir das Problem, dass das Routing zwischen unseren Inhouse-Netzen (LAN, IoT, Gastnetz und DMZ) immer über einen Gigabit-Port des Routers zum Switch lief. Dadurch sind Transfers zwischen den Netzen auf 500 MBit/s beschränkt. Überträgt man also eine Datei aus dem Internet in die DMZ, erfolgt das mit 600 MBit/s, das Weiterschieben ins LAN ist de facto langsamer als die Internet-Verbindung!

Im Lieferprogramm von Ubiquiti findet sich als Maximalausbaustufe der -> Edgerouter Infinity, der jedoch mit ca. 1500€ weder preislich noch (angesichts einer kolportierten QoS-Performance von ca. 500 MBit/s) überhaupt attraktiv erscheint.

Bei einem Systemwechsel rückt sofort der -> Mikrotik CCR2004-1G-12S+2XS in den Fokus, der neben vielen SFP+-Ports auch noch zwei SFP28-Ports für späteren Ausbau mitbringt und für ca. 600€ zu haben ist. Unsere Tests mit diesem Gerät verliefen allerdings wenig befriedigend, weil die verbaute CPU - ein AL32400 - auf dem Performance-Niveau eines Mittelklasse-Smartphones von 2017 liegt. Die gemessene Routing-Performance zwischen zwei (!) Ports lag bei uns bei nur ca. 2500 MBit/s. Das Gerät ist somit zwar flexibel, aber wenig performant.

* OpnSense

Da klar war, dass etwas schnelleres her musste, haben wir uns auf dem Markt weiter umgesehen und kamen auf Lösungen auf Basis von pfSense und OpnSense. Hier gibt es einerseits fertige Lösungen der Hersteller Netgate und Deciso, andererseits die Option, mittels eigener X64-Hardware eine Lösung zu bauen. Unsere Wahl fiel zuerst auf den -> Supermicro E300-9D-4CN8TP. Es gibt ein -> Review auf Youtube dazu. Das Gerät wurde mit 32 GByte DDR4 ECC-RAM und einer 500 GByte NVME SSD ausgestattet und per SFP+-DAC-Kabel an unseren Switch angeschlossen. Ein kleines Manko: Die verwendeten Intel X722-Adapter lassen nur unterstützte SFP-Module zu - bei uns funktionierten nur DAC-Kabel, aber kein einziges unserer SFP(+)-Module. Bei der Software entschieden wir uns für OpnSense, weil diese stets etwas aktueller ist und mit FQ-Codel auch das aktuell beste QoS-Verfahren mitbringt. Die Oberfläche ist auch etwas moderner als pfSense.

Nach der Einrichtung hatten wir auch mit QoS den vollen Datendurchsatz und keinen Bufferbloat mehr - der Ping lag immer bei 2-3 Millisekunden.

DSLreports Bufferbloat Test




Waveform Bufferbloat Test




Speedtest



* Konfiguration OpnSense

Für die Konfiguration sollte man ein paar Kniffe kennen:
  • Wir empfehlen, DNSmasq anstelle von Unbound zu verwenden, weil damit lokal vergebene DNS-Namen und Aliases genutzt werden können.
  • Beim Einsatz von LAN-Bridges immer in den Tunables "net.link.bridge.pfil_bridge = 1" und "net.link.bridge.pfil_member = 0" setzen - dann rebooten. Wir benötigten die LAN-Bridge, um den entfallenen 10-GBit-Port zu ersetzen.
  • Beim Einsatz von LAN-Bridges gilt: Die VLANs müssen auf den Member-Interfaces definiert werden, nicht auf der Bridge. Will man dann ein VLAN bridgen, -> benötigt man dafür eine separate Bridge.
  • Eine Bridge hat per Default eine künstlich erzeugte MAC und normalerweise keine IPv6 Link Local Adresse. Man kann diese an der Bridge aktivieren.
  • Für IPv6 sollte man die IPv6-Einstellungen der Interfaces auf "Track Interface" einstellen und in den Router Advertisements "Unmanaged" mit Default Gateway und einer spezifischen Domain Search List senden.
  • Wenn man IPv6 Link Local Adressen selbst setzen möchte oder auch Unique Local Adressen, geht das nicht in den IPv6-Einstellungen des Interfaces selbst, weil man dort nur eine IP setzen kann (gilt auch für IPv4). Der Trick ist der Bereich "Virtual IP", dort geht das.
  • Falls man eine Fritzbox einsetzt: Das Weiterleiten von SIP und RTP-Ports allein reicht nicht aus, weil dann nach ein paar Minuten keine Verbindungen von außen mehr zugelassen werden und ankommende Anrufe nicht durchkommen. Man muss in der Fritzbox auf jeden Fall in den Anschlusseinstellungen unter Telefonieverbindung die Einstellung "Portweiterleitung des Internet-Routers für Telefonie aktiv halten" einschalten. Zudem muss man eine separate Regel für die Outbound NAT definieren, bei der für die Fritzbox "Static Port" gesetzt wird.
  • Für IPsec-Verbindungen mit Fritzboxen müssen immer zwei Einträge angelegt werden, eine für IKE und eine für den ESP Tunnel. In den Advanced Settings findet sich ein Eintrag "Disable all auto-added VPN rules.", den man deaktiviert lassen sollte.
  • Die Remote-Backup-Funktionen zu Google Drive bzw. NextCloud sind hilfreich und sollten genutzt werden.
  • IGMP und MDNS können bei Bedarf als Plugins nachgeladen werden.
  • Die Webproxy-Konfiguration ist etwas komplex, man muss beachten, dass es neben den Reitern noch Drop-Downs für Regeln, Matches und Proxies gibt. Damit lassen sich Regeln definieren, die in eine WPAD-Datei münden, die OpnSense dann bereitstellt. Oft muss man noch eine Neuerzeugung erzwingen, besser ist eine manuelle Kontrolle der Datei.
    Dann fehlen noch zwei Bausteine: Im DHCP muss man dafür sorgen, dass WPAD aktiviert wird und man muss den Namen "wpad" in der LAN-DNS-Domäne auf die OpnSense-IP richten, damit die URL "http://wpad.XYZ/wpad.dat" erreichbar ist.
  • Im DHCP auf keinen Fall die Einstellung "Response delay" nutzen! Dies sorgt effektiv dafür, dass manche Clients -> nicht funktionieren.
  • Bei IPv6-Portfreigaben hat man mit dynamischen Präfixen das Problem, dass man die resultierende IPv6 eines bestimmten Geräts nicht in eine Firewall-Regel eintragen kann. Dazu gibt es drei Tricks: Man kann 1. "This Firewall" und 2. einen Firewall-Alias, der sich auf eine MAC bezieht, als Ziel einer Regel verwenden oder 3. einen Alias vom Typ dynamische IPv6-Adresse einrichten, bei der der IPv6-Präfix eines beliebigen Interfaces vorangestellt werden kann.
  • Um Bufferbloat zu vermeiden, sollten Einstellungen wie -> hier beschrieben verwendet werden.
  • Um maximale Stromeinsparung zu erhalten, bietet es sich an, den niedrigsten C-State für alle Cores einzustellen. Standardmäßig wird nur C1 verwendet. In den Tunables kann man dev.cpu.N.cx_lowest=C3 oder C2 setzen, je nachdem, was "sysctl dev.cpu.0" als möglich ausweist.
  • Für ZFS bietet es sich an, TRIM einzuschalten. Prüfen mit "zpool get autotrim", einschalten mit "zpool set autotrim=on zroot", erstmalig durchführen mit "zpool trim zroot", ansehen mit "zpool status -t". Außerdem kann man mit "zfs set recordsize=16k zroot" den Wear auf SSDs etwas reduzieren (siehe "smartctl -a /dev/nvme0").
  • Bei Verwendung von Wireguard muss man darauf achten, dass die Default-MTU von 1420 Bytes u.U. geändert werden muss. Es gibt diverse Faktoren, die diese Größe weiter beschränken, z.B. IPv6 (-20 Bytes) oder PPPoE (-8 Bytes). Man kann das entweder in den erweiterten Einstellungen für die lokalen Endpunkte oder für alle Wireguard-Interfaces die MSS reduzieren (unter Firewall->Normalisation).
  • Falls man IPv6 auf einem Bridge-Interface nutzen will, sollte man "Enable Link-local address" einschalten, sonst wird per radvd keine Adresse zugewiesen.
  • Achtung, bei AMD 10GBit Interfaces (axgbe Treiber) -> funktioniert das Hardware CRC Oflloading nicht!

* Nachtrag

Wir sind inzwischen aufgrund des hohen Strombedarfs auf andere Lösungen ausgewichen, siehe hier.