Migration von OpenVPN zu WireGuard, um Netzwerke in einem L2-Netzwerk zu konsolidieren

Migration von OpenVPN zu WireGuard, um Netzwerke in einem L2-Netzwerk zu konsolidieren

Ich möchte meine Erfahrungen mit der Kombination von Netzwerken in drei geografisch weit entfernten Wohnungen, die jeweils Router mit OpenWRT als Gateway verwenden, zu einem gemeinsamen Netzwerk teilen. Bei der Auswahl einer Methode zum Kombinieren von Netzwerken zwischen L3 mit Subnetz-Routing und L2 mit Bridging, bei der sich alle Netzwerkknoten im selben Subnetz befinden, wurde der zweiten Methode der Vorzug gegeben, die schwieriger zu konfigurieren ist, aber mehr Möglichkeiten bietet, da transparent Der Einsatz von Technologien war im geschaffenen Netzwerk Wake-on-Lan und DLNA geplant.

Teil 1: Hintergrund

Als Protokoll zur Umsetzung dieser Aufgabe wurde zunächst OpenVPN gewählt, da es erstens ein Tap-Device erstellen kann, das problemlos zur Bridge hinzugefügt werden kann, und zweitens OpenVPN den Betrieb über das TCP-Protokoll unterstützt, was auch wichtig war, weil Keine der Wohnungen hatte eine dedizierte IP-Adresse und ich konnte STUN nicht verwenden, da mein ISP aus irgendeinem Grund eingehende UDP-Verbindungen aus seinen Netzwerken blockiert, während das TCP-Protokoll es mir erlaubte, den VPN-Server-Port auf gemieteten VPS per SSH weiterzuleiten. Ja, dieser Ansatz stellt eine große Belastung dar, da die Daten doppelt verschlüsselt werden, aber ich wollte den VPS nicht in mein privates Netzwerk einführen, da immer noch die Gefahr bestand, dass Dritte die Kontrolle darüber erlangen, weshalb ich über ein solches Gerät besitze im Heimnetzwerk war äußerst unerwünscht und es wurde beschlossen, die Sicherheit mit einem hohen Mehraufwand zu bezahlen.

Um den Port auf dem Router weiterzuleiten, auf dem der Server bereitgestellt werden sollte, wurde das Programm sshtunnel verwendet. Ich werde die Feinheiten seiner Konfiguration nicht beschreiben – das geht ganz einfach, ich stelle nur fest, dass seine Aufgabe darin bestand, den TCP-Port 1194 vom Router an den VPS weiterzuleiten. Als nächstes wurde der OpenVPN-Server auf dem tap0-Gerät konfiguriert, das mit der br-lan-Bridge verbunden war. Nachdem ich die Verbindung zum neu erstellten Server vom Laptop aus überprüft hatte, wurde klar, dass sich die Idee der Portweiterleitung rechtfertigte und mein Laptop Mitglied des Netzwerks des Routers wurde, obwohl er sich physisch nicht darin befand.

Die Sache blieb klein: Es galt, IP-Adressen in verschiedenen Wohnungen so zu verteilen, dass sie nicht in Konflikt geraten, und Router als OpenVPN-Clients zu konfigurieren.
Die folgenden Router-IP-Adressen und DHCP-Serverbereiche wurden ausgewählt:

  • 192.168.10.1 mit Reichweite 192.168.10.2 - 192.168.10.80 für den Server
  • 192.168.10.100 mit Reichweite 192.168.10.101 - 192.168.10.149 für einen Router in Wohnung Nr. 2
  • 192.168.10.150 mit Reichweite 192.168.10.151 - 192.168.10.199 für einen Router in Wohnung Nr. 3

Es war auch notwendig, genau diese Adressen den Client-Routern des OpenVPN-Servers zuzuweisen, indem man die Zeile in seine Konfiguration einfügte:

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

und Hinzufügen der folgenden Zeilen zur Datei /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

Dabei sind flat1_id und flat2_id die Gerätenamen, die beim Generieren von Zertifikaten für die Verbindung zu OpenVPN angegeben werden

Als nächstes wurden OpenVPN-Clients auf den Routern konfiguriert, die tap0-Geräte auf beiden wurden zur Br-LAN-Brücke hinzugefügt. Zu diesem Zeitpunkt schien alles in Ordnung zu sein, da sich alle drei Netzwerke gegenseitig sehen und als Ganzes funktionieren. Es stellte sich jedoch ein nicht sehr erfreuliches Detail heraus: Manchmal erhielten Geräte eine IP-Adresse, die nicht von ihrem Router stammte, mit allen daraus resultierenden Konsequenzen. Aus irgendeinem Grund hatte der Router in einer der Wohnungen keine Zeit, rechtzeitig auf DHCPDISCOVER zu antworten, und das Gerät erhielt die falsche Adresse. Mir wurde klar, dass ich solche Anfragen in tap0 auf jedem der Router filtern muss, aber wie sich herausstellte, kann iptables nicht mit einem Gerät funktionieren, wenn es Teil einer Bridge ist und ebtables sollte mir helfen. Zu meinem Bedauern war es nicht in meiner Firmware enthalten und ich musste die Images für jedes Gerät neu erstellen. Dadurch und durch Hinzufügen dieser Zeilen zu /etc/rc.local jedes Routers wurde 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 dauerte drei Jahre.

Teil 2: Einführung von WireGuard

In letzter Zeit wird im Internet zunehmend über WireGuard gesprochen und die Einfachheit seiner Konfiguration, die hohe Übertragungsgeschwindigkeit und der niedrige Ping bei vergleichbarer Sicherheit bewundert. Bei der Suche nach weiteren Informationen dazu wurde deutlich, dass weder die Arbeit als Bridge-Mitglied noch die Arbeit am TCP-Protokoll dadurch unterstützt wird, was mich zu dem Schluss brachte, dass es für mich immer noch keine Alternativen zu OpenVPN gibt. Deshalb habe ich es aufgeschoben, WireGuard kennenzulernen.

Vor ein paar Tagen verbreitete sich in den IT-Ressourcen die Nachricht, dass WireGuard ab Version 5.6 endlich in den Linux-Kernel integriert wird. Nachrichtenartikel lobten WireGuard wie immer. Ich machte mich erneut auf die Suche nach Möglichkeiten, das gute alte OpenVPN zu ersetzen. Diesmal bin ich auf sie gestoßen dieser Artikel. Darin ging es um die Erstellung eines Ethernet-Tunnels über L3 mithilfe von GRE. Dieser Artikel hat mir Hoffnung gegeben. Es blieb unklar, was mit dem UDP-Protokoll geschehen soll. Die Suche führte mich zu Artikeln über die Verwendung von socat in Verbindung mit einem SSH-Tunnel zur Weiterleitung eines UDP-Ports. Sie stellten jedoch fest, dass dieser Ansatz nur im Einzelverbindungsmodus funktioniert, was bedeutet, dass mehrere VPN-Clients unmöglich wären. Ich hatte die Idee, einen VPN-Server auf einem VPS einzurichten und GRE für Clients zu konfigurieren, aber wie sich herausstellte, unterstützt GRE keine Verschlüsselung, was dazu führen wird, dass, wenn Dritte Zugriff auf den Server erhalten, Der gesamte Datenverkehr zwischen meinen Netzwerken liegt in ihren Händen, was mir überhaupt nicht gefiel.

Auch hier fiel die Entscheidung zugunsten einer redundanten Verschlüsselung, indem VPN über VPN nach folgendem Schema genutzt wird:

Layer-XNUMX-VPN:
VPS ist Server mit interner Adresse 192.168.30.1
MS ist vom Kunden VPS mit interner Adresse 192.168.30.2
MK2 ist vom Kunden VPS mit interner Adresse 192.168.30.3
MK3 ist vom Kunden VPS mit interner Adresse 192.168.30.4

Layer-XNUMX-VPN:
MS ist Server mit externer Adresse 192.168.30.2 und interner 192.168.31.1
MK2 ist vom Kunden MS mit der Adresse 192.168.30.2 und hat eine interne IP von 192.168.31.2
MK3 ist vom Kunden MS mit der Adresse 192.168.30.2 und hat eine interne IP von 192.168.31.3

* MS - Router-Server in Wohnung 1, MK2 - Router in Wohnung 2, MK3 - Router in Wohnung 3
* Gerätekonfigurationen werden im Spoiler am Ende des Artikels veröffentlicht.

Und so gehen die Pings zwischen den Knoten des Netzwerks 192.168.31.0/24 weiter, es ist Zeit, mit dem Einrichten des GRE-Tunnels fortzufahren. Um den Zugriff auf Router nicht zu verlieren, lohnt es sich vorher, SSH-Tunnel einzurichten, um Port 22 an den VPS weiterzuleiten, sodass beispielsweise ein Router aus Wohnung 10022 auf Port 2 des VPS verfügbar ist und a Router aus Wohnung 11122 wird auf Port 3 des VPS verfügbar sein. Router aus Wohnung XNUMX. Am besten konfigurieren Sie die Weiterleitung mit demselben SSH-Tunnel, da dieser den Tunnel bei einem Ausfall wiederherstellt.

Der Tunnel ist konfiguriert, Sie können über den weitergeleiteten Port eine Verbindung zu SSH herstellen:

ssh root@МОЙ_VPS -p 10022

Als nächstes deaktivieren Sie OpenVPN:

/etc/init.d/openvpn stop

Nun richten wir einen GRE-Tunnel auf dem Router von Wohnung 2 ein:

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

Und fügen Sie die erstellte Schnittstelle zur Bridge hinzu:

brctl addif br-lan grelan0

Führen wir einen ähnlichen Vorgang auf dem Server-Router durch:

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

Und fügen Sie außerdem die erstellte Schnittstelle zur Bridge hinzu:

brctl addif br-lan grelan0

Von diesem Moment an beginnen Pings erfolgreich in das neue Netzwerk zu gelangen und ich gehe zufrieden Kaffee trinken. Um dann zu sehen, wie das Netzwerk am anderen Ende der Leitung funktioniert, versuche ich, eine SSH-Verbindung zu einem der Computer in Wohnung 2 herzustellen, aber der SSH-Client friert ein, ohne mich zur Eingabe eines Passworts aufzufordern. Ich versuche, über Telnet auf Port 22 eine Verbindung zu diesem Computer herzustellen und sehe eine Zeile, aus der man erkennen kann, dass die Verbindung hergestellt wird, der SSH-Server antwortet, aber aus irgendeinem Grund bietet er mir keinen Zugang an.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Ich versuche, über VNC eine Verbindung herzustellen und sehe einen schwarzen Bildschirm. Ich überzeuge mich davon, dass die Sache am entfernten Computer liegt, da ich mich von dieser Wohnung aus über die interne Adresse problemlos mit dem Router verbinden kann. Ich entscheide mich jedoch, über den Router eine SSH-Verbindung zu diesem Computer herzustellen, und stelle zu meiner Überraschung fest, dass die Verbindung erfolgreich ist und der Remote-Computer einwandfrei funktioniert, aber auch keine Verbindung zu meinem Computer herstellen kann.

Ich nehme das grelan0-Gerät aus der Bridge und starte OpenVPN auf dem Router in Wohnung 2 und stelle sicher, dass das Netzwerk wieder ordnungsgemäß funktioniert und die Verbindungen nicht abbrechen. Beim Suchen stoße ich auf Foren, in denen sich Leute über die gleichen Probleme beschweren und in denen ihnen empfohlen wird, die MTU zu erhöhen. Gesagt, getan. Bis die MTU jedoch auf einen ausreichend großen Wert von 7000 für Gretap-Geräte eingestellt wurde, wurden entweder unterbrochene TCP-Verbindungen oder langsame Übertragungen beobachtet. Aufgrund der hohen MTU für Gretap wurden die MTUs für WireGuard-Verbindungen der ersten und zweiten Ebene auf 8000 bzw. 7500 festgelegt.

Ich habe ein ähnliches Setup auf dem Router aus Wohnung 3 durchgeführt, mit dem einzigen Unterschied, dass eine zweite Gretap-Schnittstelle namens grelan1 zum Server-Router hinzugefügt wurde, die auch zur Br-LAN-Bridge hinzugefügt wurde.

Alles arbeitet. Jetzt können Sie die Gretap-Assembly in den Autoload-Modus versetzen. Dafür:

Habe diese Zeilen in /etc/rc.local auf dem Router in Apartment 2 platziert:

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

Dies wurde zu /etc/rc.local auf dem Router in Apartment 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 Server-Router:

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 herstellten. Beim Herstellen einer Verbindung zu ihrem SSH (glücklicherweise hatte ich zuvor den SSH-Tunnel dafür konfiguriert) wurde festgestellt, dass WireGuard aus irgendeinem Grund eine Route für den Endpunkt erstellte, obwohl diese falsch war. Für 192.168.30.2 wurde die Routentabelle also über die PPPOE-WAN-Schnittstelle, also über das Internet, angegeben, obwohl die Route dorthin über die WG0-Schnittstelle hätte geleitet werden sollen. Nach dem Löschen dieser Route wurde die Verbindung wiederhergestellt. Ich konnte nirgendwo eine Anleitung finden, wie man WireGuard dazu zwingen kann, diese Routen nicht zu erstellen. Außerdem habe ich nicht einmal verstanden, ob dies eine Funktion von OpenWRT oder von WireGuard selbst ist. Ohne mich lange mit diesem Problem auseinandersetzen zu müssen, habe ich einfach in einem von einem Timer durchgeschleiften Skript zu beiden Routern eine Zeile hinzugefügt, die diese Route löschte:

route del 192.168.30.2

Zusammenfassend

Ich habe OpenVPN noch nicht vollständig abgelehnt, da ich manchmal von einem Laptop oder Telefon aus eine Verbindung zu einem neuen Netzwerk herstellen muss und das Einrichten eines Gretap-Geräts darauf im Allgemeinen unmöglich ist, aber trotzdem habe ich einen Vorteil bei der Datenübertragung erzielt Geschwindigkeit zwischen Wohnungen und beispielsweise die Verwendung von VNC ist nicht mehr umständlich. Ping ging leicht zurück, wurde aber stabiler:

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

Es wird hauptsächlich durch einen hohen Ping zum VPS beeinträchtigt, der etwa 61.5 ms beträgt

Allerdings hat sich die Geschwindigkeit deutlich erhöht. In einer Wohnung mit Router-Server habe ich also eine Internetverbindungsgeschwindigkeit von 30 Mbit/s und in anderen Wohnungen 5 Mbit/s. Gleichzeitig konnte ich bei der Verwendung von OpenVPN laut iperf keine Datenübertragungsrate zwischen Netzwerken von mehr als 3,8 Mbit/s erreichen, während WireGuard sie auf die gleichen 5 Mbit/s „aufgepumpt“ hat.

WireGuard-Konfiguration auf VPS[Interface] Address = 192.168.30.1/24
ListenPort = 51820
PrivateKey = <ЗАКРЫТЫЙ_КЛЮЧ_ДЛЯ_VPS>

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_1_МС>
AllowedIPs = 192.168.30.2/32

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК2>
AllowedIPs = 192.168.30.3/32

[Peer] PublicKey = <ОТКРЫТЫЙ_КЛЮЧ_VPN_2_МК3>
AllowedIPs = 192.168.30.4/32

WireGuard-Konfiguration auf MS (zu /etc/config/network hinzugefügt)

#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 MK2 (zu /etc/config/network hinzugefügt)

#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 MK3 (zu /etc/config/network hinzugefügt)

#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 Second-Level-VPN gebe ich WireGuard-Clients den Port 51821 an. Theoretisch ist dies nicht notwendig, da der Client eine Verbindung von jedem freien, nicht privilegierten Port aus aufbaut, aber ich habe es so gemacht, dass alle eingehenden Verbindungen kann auf den wg0-Schnittstellen aller Router abgelehnt werden, mit Ausnahme eingehender UDP-Verbindungen auf Port 51821.

Ich hoffe, dass der Artikel für jemanden nützlich sein wird.

PS Außerdem möchte ich mein Skript teilen, das mir in der WirePusher-Anwendung eine PUSH-Benachrichtigung an mein Telefon sendet, wenn ein neues Gerät in meinem Netzwerk erscheint. Hier ist ein Link zum Skript: github.com/r0ck3r/device_discover.

AKTUALISIEREN: Konfiguration von OpenVPN-Servern und -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 # Change to your router's External IP
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

Ich habe easy-rsa verwendet, um Zertifikate zu erstellen.

Source: habr.com

Kommentar hinzufügen