Wechsel von OpenVPN zu WireGuard zur Zusammenführung von Netzwerken in ein L2-Netzwerk

Wechsel von OpenVPN zu WireGuard zur Zusammenführung von Netzwerken in ein L2-Netzwerk

Ich möchte meine Erfahrungen teilen, wie man Netzwerke in drei geografisch entfernten Wohnungen, in denen Router mit OpenWRT als Gateways dienen, zu einem gemeinsamen Netzwerk verbindet. Bei der Wahl der Methode zur Zusammenführung der Netzwerke zwischen L3 mit Subnetz-Routing und L2 mit Bridging, bei dem alle Knoten im selben Subnetz sind, wurde die zweite Methode bevorzugt, die zwar komplexer einzurichten ist, jedoch größere Möglichkeiten bietet, da in dem erstellten Netzwerk eine transparente Nutzung von Wake-on-Lan und DLNA geplant war.

Teil 1: Vorgeschichte

Für die Umsetzung dieser Aufgabe wurde ursprünglich das Protokoll OpenVPN gewählt, da es erstens die Möglichkeit bietet, ein Tap-Gerät zu erstellen, das problemlos in ein Netzwerk-Bridge integriert werden kann, und zweitens OpenVPN die Verwendung des TCP-Protokolls unterstützt. Dies war ebenfalls wichtig, da in keiner der Wohnungen eine feste IP-Adresse verfügbar war. Zudem konnte ich STUN nicht verwenden, da mein Anbieter aus unbekannten Gründen eingehende Verbindungen über das UDP-Protokoll aus seinen Netzen blockiert, während das TCP-Protokoll es mir ermöglichte, den Port des VPN-Servers über SSH auf dem gemieteten VPS freizugeben. Ja, dieser Ansatz erzeugt eine hohe Last, da die Daten doppelt verschlüsselt werden, aber ich wollte das VPS nicht in mein privates Netzwerk integrieren, da das Risiko bestand, dass Dritte die Kontrolle darüber erlangen könnten. Folglich war es äußerst unerwünscht, ein solches Gerät im heimischen Netzwerk zu haben, und ich entschied mich, für Sicherheit einen höheren Overhead in Kauf zu nehmen.

Für das Portforwarding auf dem Router, auf dem der Server eingerichtet werden sollte, wurde das Programm sshtunnel verwendet. Ich werde nicht auf die Feinheiten seiner Konfiguration eingehen – das ist ganz einfach zu handhaben. Ich möchte nur erwähnen, dass seine Aufgabe darin bestand, den TCP-Port 1194 vom Router auf den VPS weiterzuleiten. Anschließend wurde der OpenVPN-Server auf dem Gerät tap0 eingerichtet, das in die Bridge br-lan eingebunden wurde. Nachdem ich die Verbindung zu dem gerade eingerichteten Server von meinem Laptop aus überprüft hatte, wurde klar, dass die Idee des Portforwardings erfolgreich war und mein Laptop Teil des Netzwerks des Routers wurde, obwohl er physisch nicht darin war.

Es blieb nur noch eine Kleinigkeit zu tun: Die IP-Adressen in den verschiedenen Wohnungen so zu verteilen, dass sie nicht in Konflikt stehen, und die Router als OpenVPN-Clients einzurichten.
Für die Router wurden folgende IP-Adressen und DHCP-Server-Bereiche ausgewählt:

  • 192.168.10.1 mit dem Bereich 192.168.10.2192.168.10.80 für den Server
  • 192.168.10.100 mit dem Bereich 192.168.10.101192.168.10.149 für den Router in Wohnung Nr. 2
  • 192.168.10.150 mit dem Bereich 192.168.10.151192.168.10.199 für den Router in Wohnung Nr. 3

Es war auch notwendig, genau diese Adressen den OpenVPN-Client-Routern zuzuweisen, indem die folgende Zeile in seine Konfiguration hinzugefügt wurde:

ifconfig-pool-persist /etc/openvpn/ipp.txt 0

und die folgenden Zeilen in die Datei /etc/openvpn/ipp.txt hinzugefügt wurden:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

wobei flat1_id und flat2_id die Gerätenamen sind, die bei der Erstellung von Zertifikaten für die Verbindung zu OpenVPN angegeben werden.

Anschließend wurden auf den Routern OpenVPN-Clients eingerichtet, und die Geräte tap0 auf beiden Routern wurden in das Bridge br-lan aufgenommen. Zu diesem Zeitpunkt schien alles in Ordnung zu sein, da alle drei Netzwerke einander sahen und wie eine Einheit funktionierten. Doch stellte sich heraus, dass eine unangenehme Kleinigkeit auftrat: Manchmal konnten Geräte eine IP-Adresse nicht von ihrem eigenen Router erhalten, mit allen daraus resultierenden Problemen. Aus irgendeinem Grund war der Router in einer der Wohnungen nicht schnell genug, um auf DHCPDISCOVER zu antworten, und das Gerät erhielt nicht seine eigene Adresse. Ich erkannte, dass ich solche Anfragen in tap0 auf jedem der Router filtern musste, doch stellte sich heraus, dass iptables nicht mit einem Gerät arbeiten kann, wenn es Teil eines Bridges ist, und ich benötigte ebtables. Leider war es in meinen Firmware-Versionen nicht vorhanden, sodass ich die Images für jedes Gerät neu compilieren musste. Nachdem ich das erledigt hatte und solche Zeilen in /etc/rc.local jedes Routers hinzugefügt hatte, war das Problem gelöst:

ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A INPUT --in-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-destination-port 67:68 -j DROP
ebtables -A FORWARD --out-interface tap0 --protocol ipv4 --ip-protocol udp --ip-source-port 67:68 -j DROP

Diese Konfiguration bestand drei Jahre lang.

Teil 2: Einführung in WireGuard

In letzter Zeit wird im Internet zunehmend über WireGuard gesprochen, das für seine einfache Konfiguration, hohe Übertragungsgeschwindigkeit und niedrige Latenz bei vergleichbarer Sicherheit gelobt wird. Die Suche nach weiteren Informationen ergab, dass weder die Funktion als Bridge noch der TCP-Protokollbetrieb unterstützt werden, was mich zu der Überzeugung führte, dass es für mich nach wie vor keine Alternative zu OpenVPN gibt. So zögerte ich, mich mit WireGuard vertraut zu machen.

Vor einigen Tagen machte eine Nachricht um die IT-Ressourcen die Runde, dass WireGuard endlich ab Version 5.6 in den Linux-Kernel integriert wird. Die Berichterstattung lobte WireGuard wie gewohnt. Ich tauchte wieder in die Suche nach Alternativen zum altbewährten OpenVPN ein. Diesmal stieß ich auf diesen ArtikelIn dem Artikel wurde die Erstellung eines Ethernet-Tunnels über L3 mithilfe von GRE beschrieben. Dieser Artikel gab mir Hoffnung. Es war jedoch unklar, wie ich mit dem UDP-Protokoll umgehen sollte. Meine Suche führte mich zu Artikeln über die Verwendung von socat in Kombination mit einem SSH-Tunnel zum Weiterleiten eines UDP-Ports, jedoch wurde dort erwähnt, dass dieser Ansatz nur im Einzelverbindungsmodus funktioniert, was bedeutet, dass die gleichzeitige Nutzung von mehreren VPN-Clients unmöglich wäre. Mir kam die Idee, einen VPN-Server auf einem VPS einzurichten und GRE für die Clients zu konfigurieren, doch stellte sich heraus, dass GRE keine Verschlüsselung unterstützt. Dies hätte zur Folge gehabt, dass bei Zugriff Dritter auf den Server der gesamte Verkehr zwischen meinen Netzwerken gefährdet wäre, was für mich inakzeptabel war.

Wieder fiel die Entscheidung zugunsten einer doppelten Verschlüsselung durch die Verwendung von VPN über VPN nach folgendem Schema:

Erstes VPN:
VPS ist dem Server durch mit der internen Adresse 192.168.30.1
PC ist Client VPS mit interner Adresse 192.168.30.2
PC2 ist Client VPS mit interner Adresse 192.168.30.3
PC3 ist Client VPS mit interner Adresse 192.168.30.4

Zweites VPN:
PC ist dem Server durch mit der externen Adresse 192.168.30.2 und interner 192.168.31.1
PC2 ist Client PC mit der Adresse 192.168.30.2 und hat die interne IP 192.168.31.2
PC3 ist Client PC mit der Adresse 192.168.30.2 und hat eine interne IP 192.168.31.3

* PC — Router-Server in Wohnung 1, PC2 — Router in Wohnung 2, PC3 — Router in Wohnung 3
* Die Gerätekonfigurationen sind im Spoiler am Ende des Artikels veröffentlicht.

Die Pings zwischen den Knoten des Netzwerks 192.168.31.0/24 funktionieren, es ist Zeit, die GRE-Tunnelkonfiguration zu beginnen. Zuvor sollten zur Sicherstellung des Zugangs zu den Routern SSH-Tunnel eingerichtet werden, um den Port 22 auf dem VPS weiterzuleiten. Zum Beispiel wird der Router aus Wohnung 2 über den Port 10022 auf dem VPS erreichbar sein, und der Router aus Wohnung 3 über den Port 11122. Es wird empfohlen, die Portweiterleitung mit sshtunnel einzurichten, da dieser Tunnel im Falle eines Ausfalls wiederhergestellt wird.

Der Tunnel ist eingerichtet, Sie können sich über den weitergeleiteten Port mit SSH verbinden:

ssh root@MEIN_VPS -p 10022

Als Nächstes sollte OpenVPN deaktiviert werden:

/etc/init.d/openvpn stop

Nun konfigurieren wir den GRE-Tunnel auf dem Router aus Wohnung 2:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set grelan0 up

Und fügen wir das erstellte Interface zum Bridge hinzu:

brctl addif br-lan grelan0

Das gleiche Verfahren führen wir auf dem Server-Router aus:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set grelan0 up

Und auch hier fügen wir das erstellte Interface zur Bridge hinzu:

brctl addif br-lan grelan0

Ab diesem Moment können die Pings erfolgreich in das neue Netzwerk gesendet werden, und ich mache mich zufrieden auf den Weg, um Kaffee zu trinken. Um zu überprüfen, wie das Netzwerk auf der anderen Seite funktioniert, versuche ich, mich per SSH mit einem der Computer in Wohnung 2 zu verbinden. Allerdings „hängt“ der SSH-Client und fordert mich nicht zur Eingabe des Passworts auf. Ich teste die Verbindung zu diesem Computer über Telnet auf Port 22 und sehe eine Zeile, die darauf hinweist, dass die Verbindung hergestellt wird. Der SSH-Server antwortet, bietet mir jedoch aus irgendeinem Grund keinen Zugang an.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Ich versuche, mich über VNC zu verbinden und erblicke nur einen schwarzen Bildschirm. Ich sage mir, dass es am Remote-Computer liegen muss, denn ich kann mich problemlos über die interne Adresse mit dem Router aus dieser Wohnung verbinden. Doch ich entscheide mich, über den Router eine SSH-Verbindung zu diesem Computer herzustellen, und stelle überrascht fest, dass die Verbindung klappt und der Remote-Computer ganz normal arbeitet, jedoch auch nicht in der Lage ist, sich mit meinem Computer zu verbinden.

Ich entferne das Gerät grelan0 von der Bridge und starte OpenVPN auf dem Router in Wohnung 2, um sicherzustellen, dass das Netzwerk wieder wie gewünscht funktioniert und die Verbindungen stabil sind. Bei der Suche stoße ich auf Foren, in denen Leute ähnliche Probleme schildern und den Rat geben, das MTU zu erhöhen. Gesagt, getan. Doch solange das MTU nicht groß genug eingestellt war – 7000 für gretap-Geräte – traten entweder Verbindungsabbrüche bei TCP auf oder die Übertragungsgeschwindigkeit war zu niedrig. Aufgrund des hohen MTUs für gretap wurden die MTUs für die WireGuard-Verbindungen der ersten und zweiten Ebene auf 8000 bzw. 7500 eingestellt.

Ich habe eine ähnliche Konfiguration auch auf dem Router in Wohnung 3 vorgenommen, mit dem einzigen Unterschied, dass auf dem Router-Server eine zweite gretap-Schnittstelle mit dem Namen grelan1 hinzugefügt wurde, die ebenfalls in die Bridge br-lan integriert wurde.

Alles funktioniert. Jetzt kann ich die gretap-Konfiguration in den Autostart einfügen. Dafür:

Ich habe diese Zeilen in /etc/rc.local auf dem Router in Wohnung 2 eingefügt:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.2
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

Ich habe das in /etc/rc.local auf dem Router in Wohnung 3 hinzugefügt:

ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

Und auf dem Router-Server:

ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set dev grelan0 mtu 7000
ip link set grelan0 up
brctl addif br-lan grelan0

ip link add grelan1 type gretap remote 192.168.31.3 local 192.168.31.1
ip link set dev grelan1 mtu 7000
ip link set grelan1 up
brctl addif br-lan grelan1

Nach dem Neustart der Client-Router stellte ich fest, dass sie aus irgendeinem Grund keine Verbindung zum Server herstellen konnten. Als ich mich über SSH (zum Glück hatte ich vorher sshtunnel dafür konfiguriert) einloggte, entdeckte ich, dass WireGuard aus irgendeinem Grund eine Route für den Endpoint erstellt und dabei einen falschen Pfad verwendet. So war für 192.168.30.2 in der Routing-Tabelle eine Route über das Interface pppoe-wan angegeben, also über das Internet, obwohl die Route dorthin über das Interface wg0 führen sollte. Nach dem Löschen dieser Route wurde die Verbindung wiederhergestellt. Ich konnte leider keine Anleitungen finden, wie man WireGuard dazu bringt, diese Routen nicht zu erstellen. Zudem verstand ich nicht, ob dies ein spezifisches Problem von OpenWRT oder WireGuard selbst war. Ohne lange herumzubasteln, fügte ich einfach in beide Router in ein script, das nach einem Timer in einer Schleife läuft, eine Zeile hinzu, die diese Route löscht:

route del 192.168.30.2

Zusammenfassend

Ich habe bisher OpenVPN nicht vollständig aufgegeben, da ich manchmal von meinem Laptop oder Telefon aus auf ein neues Netzwerk zugreifen muss, und die Konfiguration eines gretap-Geräts darauf im Allgemeinen nicht möglich ist. Dennoch habe ich eine Geschwindigkeitsverbesserung beim Datentransfer zwischen den Wohnungen erzielt, wodurch beispielsweise die Nutzung von VNC jetzt reibungslos funktioniert. Der Ping hat sich nur geringfügig verringerte, ist aber stabiler geworden.

Bei Verwendung von OpenVPN:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=133 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=125 ms

--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19006ms
rtt min/avg/max/mdev = 124.722/126.152/136.907/3.065 ms

Bei Verwendung von WireGuard:

[r0ck3r@desktop ~]$ ping -c 20 192.168.10.110
PING 192.168.10.110 (192.168.10.110) 56(84) bytes of data.
64 bytes from 192.168.10.110: icmp_seq=1 ttl=64 time=124 ms
...
64 bytes from 192.168.10.110: icmp_seq=20 ttl=64 time=124 ms
--- 192.168.10.110 ping statistics ---
20 packets transmitted, 20 received, 0% packet loss, time 19003ms
rtt min/avg/max/mdev = 123.954/124.423/126.708/0.675 ms

Der hohe Ping zu VPS beeinflusst dies stärker, der ungefähr 61,5 ms beträgt.

Die Geschwindigkeit hat sich jedoch erheblich erhöht. In der Wohnung mit dem Router-Server habe ich eine Internetgeschwindigkeit von 30 Mbit/s, während in den anderen Wohnungen nur 5 Mbit/s zur Verfügung stehen. Dabei konnte ich während der Nutzung von OpenVPN mit iperf keine Übertragungsrate von mehr als 3,8 Mbit/s zwischen den Netzwerken erreichen, während WireGuard sie auf die gleichen 5 Mbit/s gebracht hat.

WireGuard-Konfiguration auf dem VPS[Interface]
Adresse = 192.168.30.1/24
HörPort = 51820
PrivaterSchlüssel =

[Peer]
PublicKey =
AllowedIPs = 192.168.30.2/32

[Peer]
PublicKey =
AllowedIPs = 192.168.30.3/32

[Peer]
PublicKey =
AllowedIPs = 192.168.30.4/32

WireGuard-Konfiguration auf dem MS (hinzuzufügen in /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.2/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МС'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option route_allowed_ips '1'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - сервер
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option listen_port '51821'
        list addresses '192.168.31.1/24'
        option auto '1'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list allowed_ips '192.168.31.2'

config wireguard_wg1ip link add grelan0 type gretap remote 192.168.31.1 local 192.168.31.3

        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list allowed_ips '192.168.31.3'

WireGuard-Konfiguration auf dem MK2 (hinzuzufügen in /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.3/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК2'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК2'
        list addresses '192.168.31.2/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

WireGuard-Konfiguration auf dem MK3 (hinzuzufügen in /etc/config/network)

#VPN первого уровня - клиент
config interface 'wg0'
        option proto 'wireguard'
        list addresses '192.168.30.4/24'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_1_МК3'
        option auto '1'
        option mtu '8000'

config wireguard_wg0
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_1_VPS'
        option endpoint_port '51820'
        option persistent_keepalive '25'
        list allowed_ips '192.168.30.0/24'
        option endpoint_host 'IP_АДРЕС_VPS'

#VPN второго уровня - клиент
config interface 'wg1'
        option proto 'wireguard'
        option private_key 'ЗАКРЫТЫЙ_КЛЮЧ_VPN_2_МК3'
        list addresses '192.168.31.3/24'
        option auto '1'
        option listen_port '51821'
        option mtu '7500'

config wireguard_wg1
        option public_key 'ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МС'
        option endpoint_host '192.168.30.2'
        option endpoint_port '51821'
        option persistent_keepalive '25'
        list allowed_ips '192.168.31.0/24'

In den beschriebenen Konfigurationen für das VPN der zweiten Ebene gebe ich den WireGuard-Klienten Port 51821 an. Theoretisch ist das nicht erforderlich, da der Client eine Verbindung von jedem freien, nicht privilegierten Port herstellen kann, aber ich habe es so gemacht, dass alle eingehenden Verbindungen an den Interfaces wg0 aller Router, außer den eingehenden UDP-Verbindungen an Port 51821, verboten werden können.

Ich hoffe, dass der Artikel für einige von Nutzen sein wird.

P.S. Außerdem möchte ich mein Skript teilen, das mir eine PUSH-Benachrichtigung auf mein Telefon in der WirePusher-App schickt, wenn ein neues Gerät in meinem Netzwerk entdeckt wird. Hier ist der Link zum Skript: github.com/r0ck3r/device_discover.

UPDATE: Konfiguration des OpenVPN-Servers und der Clients

OpenVPN-Server

client-to-client

ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/vpn-server.crt
dh /etc/openvpn/server/dh.pem
key /etc/openvpn/server/vpn-server.key

dev tap
ifconfig-pool-persist /etc/openvpn/ipp.txt 0
keepalive 10 60
proto tcp4
server-bridge 192.168.10.1 255.255.255.0 192.168.10.80 192.168.10.254
status /var/log/openvpn-status.log
verb 3
comp-lzo

OpenVPN-Client

client
tls-client
dev tap
proto tcp
remote VPS_IP 1194 # Ändern Sie dies auf die externe IP Ihres Routers
resolv-retry infinite
nobind

ca client/ca.crt
cert client/client.crt
key client/client.key
dh client/dh.pem

comp-lzo
persist-tun
persist-key
verb 3

Zur Generierung der Zertifikate habe ich easy-rsa verwendet

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster