Performante, sichere und stabile Drei-Punkt Mikrotik Wireguard vxlan outdoor bridge

reinhard@finalmedia.de Tue 11 Jul 2023 06:45:06 PM CEST

Disclaimer: Ich erläutere hier nicht alle Zwischenschritte und setze voraus, dass du mit Mikrotik Router OS und der der Grundkonfiguration von Wireguard und VXLANs, sowie IP-Adressen und Bridges bereits vertraut bist! Dies ist also keine Schritt-für-Schritt Anleitung sondern setzt ein Grundverständnis im Umgang mit Mikrotik RouterOS voraus. Zudem solltest du zwingend mit Wireguard und VXLANs im Allgemeinen bereits gearbeitet haben.

Szenario

Sei folgendes Szenario: Wir haben drei Mikrotik Router: alpha, beta, gamma.

Sei alpha unser zentraler Router im Hauptgebäude und wir möchten nun zwei weitere Router beta und gamma von je einem Nebengebäude sicher durch wireguard getunnelt an alpha anbinden. Der Außenanbindung (z.B. eine dedizierte Glasfaser zwischen den Gebäuden) trauen wir dabei nicht. Innerhalb des Wireguard-Tunnel nutzen wir dann routebare VXLANs, die wir auf je zwei dedizierte Ports an den jeweiligen Routern bridgen, womit also beliebiger und auch ansonsten nicht routbarer Layer2 Traffic für die getrennten Netze möglich wird. (Beachte: vxlan nicht vlan! Wenn du den Unterschied nicht kennst, schau dir das vorher an.). Für die später an diesen Ports angeschlossenen Endgeräte ist der komplette Aufbau völlig transparent. Im nachfolgenden Beispiel erstellen wir dabei zwei voneinander getrennte Bridges "guest" und "private".

Static WAN Setup

Dazu haben wir zunächst an allen drei Routern einen WAN Port auf ether1 wie aus der default config erhalten und mit dem Außennetzwerk verbunden. In unserem Fall arbeiten wir auf der WAN Seite dabei mit statischen IP-Adressen 192.168.33.0/24 und haben in der Firewall ALLER drei Router den UDP Port 33333 für Wireguard auf der WAN Seite explizit erlaubt!

chain=input action=accept protocol=udp src-address=192.168.33.0/24 dst-address=192.168.33.0/24 in-interface=ether1 dst-port=33333 log=no 

Die drei Router haben also statisch auf ether1 je diese Adresse:

alpha ether1 192.168.33.1/24
beta ether1 192.168.33.2/24
gamma ether1 192.168.33.3/24

Die Ethernet-Ports ether2 und ether3 an den jeweiligen Routern haben wir von der default bridge "bridge" entfernt und je zwei neuen bridges zugewiesen "private" und "guest". Diese sind erst mal sonst nicht weiter verbunden.

Static wireguard Setup

Zunächst setzen wir nun wireguard zwischen den Mikrotik Routern auf. Also ein peer über die WAN Anbindung.

Wähle dazu einen entsprechenden wireguard port 33333 und sorge dafür, dass beta und gamma mit alpha sprechen können. Du kannst auch alle drei Router zueinander peeren, wenn du später keine zentralen vxlan knoten möchtest, sondern auch eine entsprechende Vollvermaschung realisieren willst. In unserem Fall ist aber alpha der zentrale Knoten, sodass wir also nur alpha mit beta und wiederum alpha mit gamma peeren. Dabei verwenden wir folgende statische Wireguard IPs und aktivieren unbedingt einen KeepAlive, sowie die korrekte allowed-adress.

[admin@alpha] > /interface/wireguard/peers/print detail

 0   interface=wireguard1 public-key="2jT....Ag=" endpoint-address=192.168.33.2 endpoint-port=33333 
     current-endpoint-address=192.168.33.2 current-endpoint-port=33333 allowed-address=10.51.0.2/32
     persistent-keepalive=20s

 1   interface=wireguard1 public-key="tv5U...Fo=" endpoint-address=192.168.33.3 endpoint-port=33333 
     current-endpoint-address=192.168.33.3 current-endpoint-port=33333 allowed-address=10.51.0.3/32
     persistent-keepalive=20s


[admin@beta] > /interface/wireguard/peers/print detail 
Flags: X - disabled 
 0   interface=wireguard1 
     public-key="9wp...Yxw=" 
     endpoint-address=192.168.33.1 endpoint-port=33333 
     current-endpoint-address=192.168.33.1 current-endpoint-port=33333 
     allowed-address=10.51.0.1/32 persistent-keepalive=20s 


[admin@gamma] > /interface/wireguard/peers/print detail 
Flags: X - disabled 
 0   interface=wireguard1 
     public-key="9wp...Yxw=" 
     endpoint-address=192.168.33.1 endpoint-port=33333 
     current-endpoint-address=192.168.33.1 current-endpoint-port=33333 
     allowed-address=10.51.0.1/32 persistent-keepalive=20s 

statische wireguard IPs haben wir wie folgt gesetzt

alpha wireguard1 10.51.0.1/24 
beta wireguard1 10.51.0.2/24
gamma wireguard1 10.51.0.3/24

Beispiel auf Gamma:

[admin@gamma] > /interface/wireguard/print detail 
Flags: X - disabled; R - running 
 0  R name="wireguard1" mtu=1420 listen-port=33333 
      private-key="sGt6Ld........X3HaCuUc="
      public-key="gvzlQ0v........ZlGphzzg="
      preshared-key="DwVpSh......0GpVBy34="

[admin@gamma] > /ip/address/print
1   10.51.0.3/24      10.51.0.0     wireguard

Firewall Rules

Wichtig: Gestatte nun in der firewall auf ALLEN routern für die neu eingerichteten wireguard Interfaces MINDESTENS ein- und ausgehend ICMP Traffic, TCP Port 22, TCP Port 443 und UDP Port 8471, sowie UDP Port 8472.

Alternativ kannst du auf ALLEN routern auch breitgefächert für die wireguard Verbindung öffnen, da dies ja nur INNERHALB der wireguard Verbindung zwischen den Peers Traffic ermöglicht:

/ip/firewall/filter/print detail

chain=input action=accept src-address=10.51.0.0/24 dst-address=10.51.0.0/24 in-interface=wireguard1

Stelle generell sicher, dass du von alpha aus nun auch die wireguard ips von beta und gamma pingen kannst.

[admin@alpha]  /ping 10.51.0.2
[admin@alpha]  /ping 10.51.0.3

VXLAN Setup

Wichtiger Hinweis: Wir haben auch die beiden VXLANs via Ports 8471 und 8472 auf separaten vteps getrennt. Das wäre theoretisch nicht nötig, da wir auch ein gemeinsames vtep auf Port Port 8471 überall hätten verwenden können und dann die VXLANS nur durch die VNI hätten separieren können. Wenn wir das Setup jedoch wie hier nachfolgend beschrieben mit getrennten Ports durchführen, lässt es sich bei Bedarf auch bequemer portbasiert firewallen. Zudem wird so auch bequem der traffic pro port in einer Statistik auswertbar und ein separater dump/debug mit dem Sniffer ist bequem möglich.

vteps einrichten

Auf alpha sieht die Konfiguration wie nachfolgend aus, da wir sowohl für beta als auch für gamma zwei vxlans auf zwei unterschiedlichen ports terminieren. Es ist jeweils immer die statische wireguard ip der router definiert und alpha hat also VIER vteps:

[admin@alpha] > /interface/vxlan/vteps/print detail 
 0 interface=vxlan_private remote-ip=10.51.0.2 port=8472 
 1 interface=vxlan_private remote-ip=10.51.0.3 port=8472 
 2 interface=vxlan_guest remote-ip=10.51.0.2 port=8471 
 3 interface=vxlan_guest remote-ip=10.51.0.3 port=8471

vxlan interfaces einrichten

Die VXLANs sind dabei zuvor wie folgt definiert worden:

[admin@alpha] > /interface/vxlan/print detail       
Flags: X - disabled, R - running 
 0 R name="vxlan_guest" mtu=1500 l2mtu=65535 mac-address=...
     arp=enabled arp-timeout=auto loop-protect=default 
     loop-protect-status=off loop-protect-send-interval=5s 
     loop-protect-disable-time=5m vni=100 port=8471 dont-fragment=disabled 
     vrf=main vteps-ip-version=ipv4 allow-fast-path=yes max-fdb-size=4096 

 1 R name="vxlan_private" mtu=1500 l2mtu=65535 mac-address=... 
     arp=enabled arp-timeout=auto loop-protect=default 
     loop-protect-status=off loop-protect-send-interval=5s 
     loop-protect-disable-time=5m vni=200 port=8472 dont-fragment=disabled 
     vrf=main vteps-ip-version=ipv4 allow-fast-path=yes max-fdb-size=4096 

bei den vteps auf beta und gamma geben wir hingegen nur als Koordinator/Master die wireguard IP von alpha an, es gibt dort also jeweils nur ZWEI vteps.

[admin@beta] > /interface/vxlan/vteps/print detail 
 0 interface=vxlan_private remote-ip=10.51.0.1 port=8472 
 1 interface=vxlan_guest remote-ip=10.51.0.1 port=8471

[admin@gamma] > /interface/vxlan/vteps/print detail 
 0 interface=vxlan_private remote-ip=10.51.0.1 port=8472 
 1 interface=vxlan_guest remote-ip=10.51.0.1 port=8471

Auf gamma und beta daher auch die entsprechenden vxlan interfaces einrichten, wobei die entsprechenden vni und vorallem ports gesetzt werden.

/interface/vxlan/print detail 

 0 R name="vxlan_guest" mtu=1500 l2mtu=65535 mac-address=...
     arp=enabled arp-timeout=auto loop-protect=default 
     loop-protect-status=off loop-protect-send-interval=5s 
     loop-protect-disable-time=5m vni=100 port=8471 dont-fragment=disabled 
     vrf=main vteps-ip-version=ipv4 allow-fast-path=yes max-fdb-size=4096 

 1 R name="vxlan_private" mtu=1500 l2mtu=65535 mac-address=...
     arp=enabled arp-timeout=auto loop-protect=default 
     loop-protect-status=off loop-protect-send-interval=5s 
     loop-protect-disable-time=5m vni=200 port=8472 dont-fragment=disabled 
     vrf=main vteps-ip-version=ipv4 allow-fast-path=yes max-fdb-size=4096 

Bridge Setup

Nun bridgen wir. Wir legen also vxlan_privat mit auf die bridge "private" und das vxlan_guest mit auf die bridge "guest". Das tun wir auf ALLEN routern.

/interface/bridge/print detail 

...
 1 R name="guest" mtu=auto actual-mtu=1500 l2mtu=1598 arp=enabled arp-timeout=auto mac-address=... 
     protocol-mode=rstp fast-forward=yes igmp-snooping=no auto-mac=yes ageing-time=5m priority=0x8000 
     max-message-age=20s forward-delay=15s transmit-hold-count=6 vlan-filtering=no dhcp-snooping=no 

 3 R name="private" mtu=auto actual-mtu=1500 l2mtu=1598 arp=enabled arp-timeout=auto mac-address=... 
     protocol-mode=rstp fast-forward=yes igmp-snooping=no auto-mac=yes ageing-time=5m priority=0x8000 
     max-message-age=20s forward-delay=15s transmit-hold-count=6 vlan-filtering=no dhcp-snooping=no 
...

/interface/bridge/port/print detail

....

 6     interface=ether2 bridge=guest priority=0x80 path-cost=10 internal-path-cost=10 edge=auto 
       point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes 
       unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 

 7     interface=ether3 bridge=private priority=0x80 path-cost=10 internal-path-cost=10 edge=auto 
       point-to-point=auto learn=auto horizon=none hw=yes auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes 
       unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 
...
10     interface=vxlan_private bridge=private priority=0x80 path-cost=10 internal-path-cost=10 edge=auto
       point-to-point=auto learn=auto horizon=none auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes 
       unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 

11     interface=vxlan_guest bridge=guest priority=0x80 path-cost=10 internal-path-cost=10 edge=auto 
       point-to-point=auto learn=auto horizon=none auto-isolate=no restricted-role=no 
       restricted-tcn=no pvid=1 frame-types=admit-all ingress-filtering=yes unknown-unicast-flood=yes 
       unknown-multicast-flood=yes broadcast-flood=yes tag-stacking=no bpdu-guard=no trusted=no 
       multicast-router=temporary-query fast-leave=no 

Weiterführende Informationen

Tipp 1: Du kannst nun natürlich auch weitere bridges, vxlans etc. ergänzen. Zudem kannst du eine ausfallsichere Topologie konstruieren, indem du RSTP nutzt, entsprechende priority und path-cost für die bridges definierst und zuvor für ein vollständiges wireguard peering aller router gesorgt hast.

Tipp 2: Natürlich brauchst du für all das hier nicht zwingend Mikrotik Router. VXLANs und wireguard sind auch mit einem halbwegs aktuellen Linux Kernel nativ(!) möglich:

ip link add vxlan_private type vxlan id 100 dstport 8471 remote 10.51.0.1 local 10.51.0.2 dev eth0
ip link add vxlan_guest type vxlan id 200 dstport 8472 remote 10.51.0.1 local 10.51.0.2 dev eth0
ip link set vxlan_private up
ip link set vxlan_guest up
...
ip link add bridge_private type bridge
ip link add bridge_guest type bridge
ip link set vxlan_private master bridge_private
ip link set vxlan_guest master bridge_guest
ip link set bridge_guest up
ip link set bridge_private up