Migrering från OpenVPN till WireGuard för att konsolidera nätverk till ett L2-nätverk

Migrering från OpenVPN till WireGuard för att konsolidera nätverk till ett L2-nätverk

Jag skulle vilja dela med mig av min erfarenhet av att kombinera nätverk i tre geografiskt avlägsna lägenheter, som var och en använder routrar med OpenWRT som gateway, till ett gemensamt nätverk. När man valde en metod för att kombinera nätverk mellan L3 med subnät routing och L2 med bryggning, när alla nätverksnoder kommer att vara i samma subnät, föredrogs den andra metoden, som är svårare att konfigurera, men ger fler möjligheter, eftersom transparent användning av teknik planerades i det skapade nätverket Wake-on-Lan och DLNA.

Del 1: Bakgrund

OpenVPN valdes initialt som protokoll för att implementera denna uppgift, eftersom det för det första kan skapa en tappenhet som kan läggas till i bryggan utan problem, och för det andra stöder OpenVPN drift över TCP-protokollet, vilket också var viktigt, eftersom ingen av lägenheterna hade en dedikerad IP-adress, och jag kunde inte använda STUN, eftersom min internetleverantör av någon anledning blockerar inkommande UDP-anslutningar från deras nätverk, medan TCP-protokollet tillät mig att vidarebefordra VPN-serverporten på hyrd VPS med SSH. Ja, det här tillvägagångssättet ger en stor belastning, eftersom datan är krypterad två gånger, men jag ville inte introducera VPS i mitt privata nätverk, eftersom det fortfarande fanns en risk för att tredje part skulle få kontroll över det, därför att ha en sådan enhet på hemnätverket var extremt oönskat och det beslutades att betala för säkerheten med en stor omkostnad.

För att vidarebefordra porten på routern som det var planerat att distribuera servern på användes programmet sshtunnel. Jag kommer inte att beskriva krångligheterna i dess konfiguration - detta görs ganska enkelt, jag noterar bara att dess uppgift var att vidarebefordra TCP-port 1194 från routern till VPS. Därefter konfigurerades OpenVPN-servern på tap0-enheten, som var ansluten till br-lan-bryggan. Efter att ha kontrollerat anslutningen till den nyskapade servern från den bärbara datorn, blev det klart att idén om portvidarebefordran motiverade sig och min bärbara dator blev medlem i routerns nätverk, även om den inte fysiskt fanns i den.

Saken förblev liten: det var nödvändigt att distribuera IP-adresser i olika lägenheter så att de inte kom i konflikt och konfigurera routrar som OpenVPN-klienter.
Följande router-IP-adresser och DHCP-serverintervall valdes:

  • 192.168.10.1 med räckvidd 192.168.10.2 - 192.168.10.80 för servern
  • 192.168.10.100 med räckvidd 192.168.10.101 - 192.168.10.149 för en router i lägenhet nr 2
  • 192.168.10.150 med räckvidd 192.168.10.151 - 192.168.10.199 för en router i lägenhet nr 3

Det var också nödvändigt att tilldela exakt dessa adresser till klientroutrarna på OpenVPN-servern genom att lägga till raden i dess konfiguration:

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

och lägga till följande rader i filen /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

där flat1_id och flat2_id är enhetsnamnen som anges när certifikat genereras för anslutning till OpenVPN

Därefter konfigurerades OpenVPN-klienter på routrarna, tap0-enheterna på båda lades till br-lan-bryggan. I det här skedet verkade allt vara i sin ordning, eftersom alla tre nätverken ser varandra och fungerar som en helhet. Det visade sig dock en inte särskilt trevlig detalj: ibland kunde enheter få en IP-adress som inte kom från sin router, med alla följder av det. Av någon anledning hann routern i en av lägenheterna inte svara på DHCPDISCOVER i tid och enheten fick fel adress. Jag insåg att jag måste filtrera sådana förfrågningar i tap0 på var och en av routrarna, men som det visade sig, kan iptables inte fungera med en enhet om den är en del av en bro och ebtables skulle komma till min hjälp. Till min ånger fanns det inte i min firmware och jag var tvungen att bygga om bilderna för varje enhet. Genom att göra detta och lägga till dessa rader till /etc/rc.local för varje router, löstes problemet:

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

Denna konfiguration varade i tre år.

Del 2: Vi introducerar WireGuard

På senare tid har Internet alltmer pratat om WireGuard och beundrat enkelheten i dess konfiguration, hög överföringshastighet, låg ping med jämförbar säkerhet. Att söka efter mer information om det gjorde det klart att varken arbete som bryggmedlem eller arbete över TCP-protokollet stöds av det, vilket fick mig att tro att det fortfarande inte finns några alternativ till OpenVPN för mig. Så jag skjuter upp att lära känna WireGuard.

För några dagar sedan spreds nyheten genom resurser på ett eller annat sätt relaterat till IT att WireGuard äntligen kommer att inkluderas i Linux-kärnan, från och med version 5.6. Nyhetsartiklar, som alltid, hyllade WireGuard. Jag kastade mig återigen in i sökandet efter sätt att ersätta det gamla goda OpenVPN. Den här gången sprang jag på denna artikel. Det talade om att skapa en Ethernet-tunnel över L3 med GRE. Den här artikeln gav mig hopp. Det förblev oklart vad man skulle göra med UDP-protokollet. Sökandet ledde mig till artiklar om att använda socat i samband med en SSH-tunnel för att vidarebefordra en UDP-port, men de noterade att detta tillvägagångssätt bara fungerar i enkel anslutningsläge, vilket innebär att flera VPN-klienter skulle vara omöjliga. Jag kom på idén att sätta upp en VPN-server på en VPS och konfigurera GRE för klienter, men det visade sig att GRE inte stöder kryptering, vilket kommer att leda till att om tredje part får tillgång till servern, all trafik mellan mina nätverk ligger i deras händer vilket inte passade mig alls.

Återigen togs beslutet till förmån för redundant kryptering, genom att använda VPN över VPN enligt följande schema:

Layer XNUMX VPN:
VPS är server med intern adress 192.168.30.1
MS är klient VPS med intern adress 192.168.30.2
MK2 är klient VPS med intern adress 192.168.30.3
MK3 är klient VPS med intern adress 192.168.30.4

Layer XNUMX VPN:
MS är server med extern adress 192.168.30.2 och intern 192.168.31.1
MK2 är klient MS med adressen 192.168.30.2 och har en intern IP på 192.168.31.2
MK3 är klient MS med adressen 192.168.30.2 och har en intern IP på 192.168.31.3

* MS - router-server i lägenhet 1, MK2 - router i lägenhet 2, MK3 - router i lägenhet 3
* Enhetskonfigurationer publiceras i spoilern i slutet av artikeln.

Och så, pingar mellan noderna i nätverket 192.168.31.0/24 go, det är dags att gå vidare till att sätta upp GRE-tunneln. Innan dess, för att inte tappa tillgången till routrar, är det värt att sätta upp SSH-tunnlar för att vidarebefordra port 22 till VPS, så att till exempel en router från lägenhet 10022 kommer att finnas tillgänglig på port 2 i VPS, och en router från lägenhet 11122 kommer att finnas tillgänglig på port 3 på VPS.router från lägenhet XNUMX. Det är bäst att konfigurera vidarebefordran med samma sshtunnel, eftersom den kommer att återställa tunneln om den skulle falla.

Tunneln är konfigurerad, du kan ansluta till SSH via den vidarebefordrade porten:

ssh root@МОЙ_VPS -p 10022

Inaktivera sedan OpenVPN:

/etc/init.d/openvpn stop

Låt oss nu sätta upp en GRE-tunnel på routern från lägenhet 2:

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

Och lägg till det skapade gränssnittet till bryggan:

brctl addif br-lan grelan0

Låt oss utföra en liknande procedur på serverroutern:

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

Och lägg också till det skapade gränssnittet till bryggan:

brctl addif br-lan grelan0

från och med det här ögonblicket börjar plingar framgångsrikt gå till det nya nätverket och jag, med tillfredsställelse, går för att dricka kaffe. Sedan, för att se hur nätverket i andra änden av tråden fungerar, försöker jag att SSH till en av datorerna i lägenhet 2, men ssh-klienten fryser utan att fråga mig om ett lösenord. Jag försöker ansluta till den här datorn via telnet på port 22 och ser en linje från vilken du kan förstå att anslutningen upprättas, SSH-servern svarar, men av någon anledning erbjuder den mig inte att komma in.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Jag försöker ansluta till den via VNC och jag ser en svart skärm. Jag övertygar mig själv om att saken ligger i fjärrdatorn, eftersom jag enkelt kan ansluta till routern från den här lägenheten med den interna adressen. Jag bestämmer mig dock för att SSH till den här datorn via routern och är förvånad över att upptäcka att anslutningen lyckas och att fjärrdatorn fungerar bra men inte heller kan ansluta till min dator.

Jag tar ut grelan0-enheten från bryggan och startar OpenVPN på routern i lägenhet 2 och ser till att nätverket fungerar som det ska igen och att anslutningarna inte släpps. När jag söker stöter jag på forum där folk klagar på samma problem, där de rekommenderas att höja MTU. Inte tidigare sagt än gjort. Men tills MTU var inställd på ett tillräckligt stort värde på 7000 för gretap-enheter, observerades antingen tappade TCP-anslutningar eller långsamma överföringar. På grund av den höga MTU för gretap, sattes MTU:erna för WireGuard-anslutningar på första och andra nivån till 8000 respektive 7500.

Jag gjorde en liknande installation på routern från lägenhet 3, med den enda skillnaden att ett andra gretap-gränssnitt med namnet grelan1 lades till serverroutern, som också lades till br-lan-bryggan.

Allt fungerar. Nu kan du sätta gretap-enheten i autoload. För detta:

Placerade dessa rader i /etc/rc.local på routern i lägenhet 2:

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

Lade till detta i /etc/rc.local på routern i lägenhet 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

Och på serverroutern:

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

Efter att ha startat om klientroutrarna upptäckte jag att de av någon anledning inte kopplade till servern. När jag ansluter till deras SSH (lyckligtvis hade jag tidigare konfigurerat sshtunnel för detta), upptäcktes det att WireGuard av någon anledning skapar en rutt för slutpunkten, samtidigt som den är felaktig. Så för 192.168.30.2 specificerades rutttabellen i rutttabellen via pppoe-wan-gränssnittet, det vill säga via Internet, även om vägen till den borde ha dirigerats genom wg0-gränssnittet. Efter att den här rutten tagits bort återställdes anslutningen. Jag kunde inte hitta instruktioner någonstans om hur man tvingar WireGuard att inte skapa dessa rutter. Dessutom förstod jag inte ens om detta är en funktion hos OpenWRT, eller hos WireGuard själv. Utan att behöva ta itu med det här problemet under en lång tid lade jag helt enkelt till båda routrarna i ett skript som loopas av en timer, en rad som raderade den här rutten:

route del 192.168.30.2

Summera

Jag har ännu inte uppnått ett fullständigt avslag på OpenVPN, eftersom jag ibland behöver ansluta till ett nytt nätverk från en bärbar dator eller telefon, och det är i allmänhet omöjligt att sätta upp en gretap-enhet på dem, men trots detta fick jag en fördel i dataöverföring hastighet mellan lägenheter och till exempel att använda VNC är inte längre obekvämt. Ping minskade något, men blev mer stabil:

När du använder 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

När du använder 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

Det påverkas mestadels av hög ping till VPS som är cirka 61.5 ms

Hastigheten har dock ökat rejält. Så i en lägenhet med en router-server har jag en internetuppkopplingshastighet på 30 Mbps och i andra lägenheter 5 Mbps. Samtidigt, när jag använde OpenVPN, kunde jag inte uppnå en dataöverföringshastighet mellan nätverk på mer än 3,8 Mbps enligt iperf, medan WireGuard "pumpade" upp det till samma 5 Mbps.

WireGuard-konfiguration på 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 på MS (läggs till i /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 på MK2 (läggs till i /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 på MK3 (läggs till i /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'

I de beskrivna konfigurationerna för VPN på andra nivån anger jag port 51821 till WireGuard-klienter. I teorin är detta inte nödvändigt, eftersom klienten kommer att upprätta en anslutning från valfri ledig port utan privilegier, men jag gjorde det så att alla inkommande anslutningar kan nekas på wg0-gränssnitten för alla routrar, förutom inkommande UDP-anslutningar på port 51821.

Jag hoppas att artikeln kommer att vara användbar för någon.

PS Jag vill också dela mitt skript som skickar mig ett PUSH-meddelande till min telefon i WirePusher-appen när en ny enhet dyker upp i mitt nätverk. Här är en länk till skriptet: github.com/r0ck3r/device_discover.

UPPDATERING: OpenVPN-server och klientkonfiguration

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

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

Jag använde easy-rsa för att generera certifikat.

Källa: will.com

Lägg en kommentar