Overstappen van OpenVPN naar WireGuard om netwerken in één L2-netwerk te verbinden

Overstappen van OpenVPN naar WireGuard om netwerken in één L2-netwerk te verbinden

Ik zou graag mijn ervaring delen over het samenvoegen van netwerken in drie geografisch gescheiden appartementen, waarbij in elk appartement routers met OpenWRT als gateway worden gebruikt, tot één gezamenlijk netwerk. Bij de keuze van de methode om de netwerken samen te voegen, tussen L3 met subnet-routering en L2 met bridging, waarbij alle netwerkapparaten zich in één subnet bevinden, werd de voorkeur gegeven aan de tweede methode. Deze is ingewikkelder in te stellen, maar biedt grotere mogelijkheden, aangezien in het op te zetten netwerk transparant gebruik van Wake-on-Lan en DLNA-technologieën werd gepland.

Deel 1: Achtergrond

Als protocol voor de uitvoering van deze taak werd aanvankelijk OpenVPN gekozen, omdat het, ten eerste, een tap-apparaat kan creëren dat gemakkelijk aan een brug kan worden toegevoegd, en ten tweede, omdat OpenVPN TCP-ondersteuning heeft, wat ook belangrijk was, aangezien er in geen van de appartementen een vast IP-adres beschikbaar was. Bovendien lukte het me niet om STUN te gebruiken, omdat mijn provider om de een of andere reden inkomende UDP-verbindingen vanuit zijn netwerken blokkeert. Het TCP-protocol stelde me echter in staat om de VPN-serverpoort op een gehuurde VPS via SSH door te geven. Ja, deze aanpak brengt een hogere belasting met zich mee, omdat de gegevens dubbel worden versleuteld, maar ik wilde de VPS niet in mijn privé-netwerk opnemen, omdat het risico bestond dat derden controle over deze VPS kregen. Het was dus uiterst ongewenst om zo'n apparaat in mijn thuisnetwerk te hebben, en besloot om voor veiligheid een hogere overhead te betalen.

Voor het doorkoppelen van de poort op de router waarop de server zou worden opgezet, werd het programma sshtunnel gebruikt. Ik zal de details van de configuratie niet beschrijven — dat is vrij eenvoudig te doen, ik wil gewoon opmerken dat het de taak had om TCP-poort 1194 van de router naar de VPS door te geven. Vervolgens werd de OpenVPN-server op het tap0-apparaat ingesteld, die in de brug br-lan werd opgenomen. Nadat ik de verbinding met de net zojuist opgezette server vanaf mijn laptop had gecontroleerd, werd duidelijk dat het idee van het doorgeven van de poort succesvol was en dat mijn laptop lid was geworden van het netwerk van de router, hoewel deze daar fysiek niet was.

Het enige wat nog restte was het toewijzen van IP-adressen in de verschillende appartementen zodat ze niet conflicteerden en het instellen van de routers als OpenVPN-clients.
De volgende IP-adressen voor de routers en de DHCP-server bereik werden gekozen:

  • 192.168.10.1 met het bereik 192.168.10.2 — 192.168.10.80 voor de server
  • 192.168.10.100 met het bereik 192.168.10.101 — 192.168.10.149 voor de router in appartement №2
  • 192.168.10.150 met het bereik 192.168.10.151 — 192.168.10.199 voor de router in appartement №3

Het was ook noodzakelijk om juist deze adressen aan te wijzen voor de OpenVPN-server clientrouters, door de volgende regel aan de configuratie toe te voegen:

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

en de volgende regels toe te voegen aan het bestand /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

waar flat1_id en flat2_id de namen zijn van de apparaten die worden opgegeven bij het maken van certificaten voor verbinding met OpenVPN

Vervolgens werden de OpenVPN-clients op de routers ingesteld, apparaten tap0 werden aan beide zijden aan de brug br-lan toegevoegd. Op dat moment leek alles in orde, aangezien alle drie de netwerken elkaar zagen en als één geheel werkten. Echter, er bleek een onaangename detail te zijn: soms konden apparaten een IP-adres krijgen dat niet van hun eigen router kwam, met alle gevolgen van dien. Om een of andere reden kon de router in een van de appartementen niet op tijd reageren op DHCPDISCOVER en kreeg het apparaat niet zijn eigen adres. Ik besefte dat ik dergelijke aanvragen in tap0 op elke router moest filteren, maar zoals bleek kon iptables niet werken met een apparaat dat deel uitmaakt van een brug en ik zou de hulp van ebtables nodig hebben. Tot mijn spijt zat het er niet in mijn firmware en moest ik de afbeeldingen voor elk apparaat opnieuw samenstellen. Toen ik dit deed en dergelijke regels toevoegde aan /etc/rc.local van elke router, was het probleem opgelost:

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

Deze configuratie heeft drie jaar standgehouden.

Deel 2: Kennismaking met WireGuard

De laatste tijd wordt er steeds vaker gesproken over WireGuard op het internet, bewonderend over de eenvoud van de configuratie, de hoge overdrachtssnelheid en de lage ping bij vergelijkbare veiligheid. Het zoeken naar aanvullende informatie hierover maakte duidelijk dat noch het functioneren als een lid van een brug, noch werken over het TCP-protocol wordt ondersteund, wat me deed afvragen of er nog steeds geen alternatieven voor OpenVPN voor mij waren. Zo stelde ik het kennismaken met WireGuard uit.

Enkele dagen geleden verscheen er op verschillende IT-gerelateerde platforms het nieuws dat WireGuard eindelijk in de Linux-kernel zal worden opgenomen, te beginnen met versie 5.6. Nieuwsartikelen prezen, zoals altijd, WireGuard. Ik dook opnieuw in de zoektocht naar vervangingen voor het oude vertrouwde OpenVPN. Deze keer stuitte ik op dit artikel. Er werd gesproken over het opzetten van een Ethernet-tunnel boven L3 met behulp van GRE. Dit artikel gaf me hoop. Het bleef onduidelijk wat te doen met het UDP-protocol. Mijn zoektocht leidde me naar artikelen over het gebruik van socat in combinatie met een SSH-tunnel om een UDP-poort door te geven, maar daarin werd opgemerkt dat deze aanpak alleen werkte in de modus van één verbinding, wat zou betekenen dat het gebruik van meerdere VPN-clients onmogelijk zou zijn. Ik kreeg het idee om een VPN-server op een VPS op te zetten en GRE voor de clients in te stellen, maar al snel bleek dat GRE geen encryptie ondersteunt, wat ertoe zou leiden dat als derden toegang krijgen tot de server, zij al het verkeer tussen mijn netwerken in handen zouden krijgen, iets wat me in principe niet aanstond.

Er werd opnieuw gekozen voor overmatige encryptie door VPN boven VPN te gebruiken volgens het volgende schema:

VPN van de eerste laag:
VPS is server met intern adres 192.168.30.1
MC is client VPS met intern adres 192.168.30.2
MC2 is client VPS met intern adres 192.168.30.3
MC3 is client VPS met intern adres 192.168.30.4

VPN van de tweede laag:
MC is server met extern adres 192.168.30.2 en intern 192.168.31.1
MC2 is client MC met adres 192.168.30.2 en intern IP 192.168.31.2
MC3 is client MC met adres 192.168.30.2 en intern IP 192.168.31.3

* MC — router-server in appartement 1, MC2 — router in appartement 2, MC3 — router in appartement 3
* Apparatuurconfiguraties zijn aan het einde van het artikel in een spoiler gepost.

En zo, de pings tussen de knooppunten van het netwerk 192.168.31.0/24 gaan door, het is tijd om GRE-tunnel in te stellen. Voordat we dat doen, is het raadzaam om SSH-tunnels in te stellen om poort 22 op de VPS door te geven, zodat, bijvoorbeeld, de router uit appartement 2 beschikbaar is op poort 10022, en de router uit appartement 3 op poort 11122 toegankelijk is. Het is het beste om de doorsturing in te stellen met sshtunnel, aangezien deze de tunnel herstelt in het geval van een storing.

Tunnel is ingesteld, u kunt verbinding maken met SSH via de doorgestuurde poort:

ssh root@MIJN_VPS -p 10022

Daarna kunnen we OpenVPN uitschakelen:

/etc/init.d/openvpn stop

Laten we nu een GRE-tunnel instellen op de router in appartement 2:

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

En we voegen de gemaakte interface toe aan de brug:

brctl addif br-lan grelan0

We voeren een soortgelijke procedure uit op de router-server:

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

En ook, we voegen de gemaakte interface toe aan de brug:

brctl addif br-lan grelan0

Vanaf dit moment beginnen pings succesvol naar het nieuwe netwerk te lopen en ik ga tevreden koffie drinken. Om te beoordelen hoe het netwerk aan de andere kant van de kabel werkt, probeer ik via SSH verbinding te maken met een van de computers in appartement 2, maar de ssh-client 'hangt', zonder me een wachtwoord te laten invoeren. Ik probeer verbinding te maken met die computer via telnet op poort 22 en zie een regel waaruit duidelijk wordt dat de verbinding wordt gemaakt, de SSH-server antwoordt, maar om een of andere reden vraagt het me niet om in te loggen.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Ik probeer verbinding te maken via VNC en zie een zwart scherm. Ik probeer mezelf te overtuigen dat het probleem bij de remote computer ligt, want ik kan zonder problemen verbinding maken met de router vanuit dit appartement via het interne adres. Toch besluit ik verbinding te maken via SSH naar die computer via de router en ontdek tot mijn verbazing dat de verbinding lukt, en de remote computer werkt prima, maar deze kan ook niet verbinding maken met mijn computer.

Ik haal het apparaat grelan0 uit de brug en start OpenVPN op de router in appartement 2 en zorg ervoor dat het netwerk weer goed werkt en de verbindingen niet worden verbroken. Tijdens het zoeken kom ik op forums waar mensen klagen over dezelfde problemen, waar hen wordt aangeraden de MTU te verhogen. Gezegd is gedaan. Echter, totdat de MTU niet groot genoeg was ingesteld — 7000 voor gretap apparaten, waren er ofwel onderbrekingen in de TCP-verbindingen, ofwel lage overdrachtssnelheden. Vanwege de hoge MTU voor gretap — werd de MTU voor de WireGuard-verbindingen van de eerste en tweede niveaus ingesteld op respectievelijk 8000 en 7500.

Ik heb een soortgelijke configuratie uitgevoerd op de router in appartement 3, met als enige verschil dat er op de router-server een tweede gretap-interface met de naam grelan1 is toegevoegd, die ook aan de brug br-lan is toegevoegd.

Alles werkt. Nu kan de gretap-configuratie in de opstartprocedure worden geplaatst. Hiervoor:

Ik heb deze regels in \/etc\/rc.local op de router in appartement 2 geplaatst:

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

Ik heb dit toegevoegd aan /etc/rc.local op de router in het appartement 3:

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

En op de 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

Na het herstarten van de clientrouters ontdekte ik dat ze om een of andere reden geen verbinding met de server konden maken. Toen ik via SSH met hen verbinding maakte (waarvoor ik gelukkig eerder een sshtunnel had ingesteld), bleek dat WireGuard om de een of andere reden een route voor de endpoint aanmaakte, maar deze was incorrect. Voor 192.168.30.2 stond in de routeringstabel een route via de interface pppoe-wan, dat wil zeggen via het internet, terwijl de route ernaartoe via de interface wg0 moest gaan. Na het verwijderen van deze route werd de verbinding hersteld. Ik heb geen instructies kunnen vinden over hoe ik WireGuard kon dwingen om deze routes niet aan te maken. Bovendien begreep ik niet of dit een specifieke eigenschap van OpenWRT of van WireGuard zelf was. Zonder er te lang over na te denken, heb ik gewoon op beide routers een regel toegevoegd aan het script dat in een lus draait, waarin deze route werd verwijderd:

route del 192.168.30.2

Samenvattend

Ik heb nog geen volledige afschakeling van OpenVPN bereikt, omdat ik soms verbinding moet maken met een nieuw netwerk vanaf mijn laptop of telefoon, en de configuratie van een gretap-apparaat daarop meestal onmogelijk is. Desondanks heb ik een voordeel gekregen in de datasnelheid tussen de appartementen en bijvoorbeeld, het gebruik van VNC is nu comfortabeler. De ping is iets verminderd, maar is stabieler geworden:

Bij gebruik van 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-statistieken ---
20 pakketten verzonden, 20 ontvangen, 0% pakketverlies, tijd 19006ms
rtt min/avg/max/mdev = 124.722/126.152/136.907/3.065 ms

Bij gebruik van 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-statistieken ---
20 pakketten verzonden, 20 ontvangen, 0% pakketverlies, tijd 19003ms
rtt min/avg/max/mdev = 123.954/124.423/126.708/0.675 ms

Dit wordt in het grootste deel beïnvloed door de hoge ping naar de VPS, die ongeveer 61,5 ms bedraagt.

De snelheid is echter aanzienlijk gestegen. In een appartement met een serverrouter heb ik een internetsnelheid van 30 Mbit/s, terwijl de andere appartementen 5 Mbit/s hebben. Tijdens het gebruik van OpenVPN kon ik echter geen datasnelheid tussen netwerken hoger dan 3,8 Mbit/s behalen volgens de metingen van iperf, terwijl WireGuard deze naar dezelfde 5 Mbit/s bracht.

WireGuard-configuratie op VPS[Interface]
Adres = 192.168.30.1/24
LuisterPoort = 51820
PrivéSleutel =

[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-configuratie op MK (toegevoegd aan /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-configuratie op MK2 (toegevoegd aan /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-configuratie op MK3 (toegevoegd aan /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 de beschreven configuraties voor VPN van het tweede niveau geef ik WireGuard-klanten poort 51821. Dit is eigenlijk niet nodig, aangezien de cliënt verbinding maakt vanaf elke beschikbare niet-privileged poort, maar ik heb het zo gedaan dat alle binnenkomende verbindingen op de interfaces wg0 van alle routers kunnen worden geblokkeerd, behalve inkomende UDP-verbindingen op poort 51821.

Ik hoop dat het artikel voor iemand nuttig zal zijn.

P.S. Ook wil ik mijn script delen dat me een PUSH-melding op mijn telefoon stuurt in de WirePusher-app wanneer er een nieuw apparaat in mijn netwerk verschijnt. Hier is de link naar het script: github.com/r0ck3r/device_discover.

UPDATE: OpenVPN-server- en klantconfiguratie

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-klant

client
tls-client
dev tap
proto tcp
remote VPS_IP 1194 # Verander naar het externe IP van je router
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

Voor het genereren van certificaten heb ik easy-rsa gebruikt.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster