Bytte fra OpenVPN til WireGuard for å kombinere nettverk til ett L2-nettverk

Bytte fra OpenVPN til WireGuard for å kombinere nettverk til ett L2-nettverk

Jeg vil gjerne dele min erfaring med å kombinere nettverk i tre geografisk avsidesliggende leiligheter, som hver bruker OpenWRT-rutere som en gateway, til ett felles nettverk. Ved valg av metode for å kombinere nettverk mellom L3 med subnettruting og L2 med brobygging, når alle nettverksnoder vil være i samme subnett, ble den andre metoden foretrukket, som er vanskeligere å konfigurere, men gir større muligheter, siden transparent bruk av teknologier var planlagt i nettverket som ble opprettet Wake-on-Lan og DLNA.

Del 1: Bakgrunn

OpenVPN ble opprinnelig valgt som protokollen for å implementere denne oppgaven, siden den for det første kan lage en trykkenhet som kan legges til broen uten problemer, og for det andre støtter OpenVPN drift over TCP-protokollen, noe som også var viktig, fordi ingen av leilighetene hadde en dedikert IP-adresse, og jeg kunne ikke bruke STUN, siden min leverandør av en eller annen grunn blokkerer innkommende UDP-forbindelser fra nettverkene deres, mens TCP-protokollen tillot meg å videresende VPN-serverporten til leid VPS ved hjelp av SSH. Ja, denne tilnærmingen gir en stor belastning, siden dataene er kryptert to ganger, men jeg ønsket ikke å introdusere en VPS i mitt private nettverk, siden det fortsatt var en risiko for at tredjeparter får kontroll over det, og derfor har en slik enhet på mitt hjemmenettverk var ekstremt uønsket, og det ble besluttet å betale for sikkerhet med en stor overhead.

For å videresende porten på ruteren som det var planlagt å distribuere serveren på, ble sshtunnel-programmet brukt. Jeg vil ikke beskrive vanskelighetene med konfigurasjonen - det gjøres ganske enkelt, jeg vil bare merke at oppgaven var å videresende TCP-port 1194 fra ruteren til VPS. Deretter ble OpenVPN-serveren konfigurert på tap0-enheten, som var koblet til br-lan-broen. Etter å ha sjekket tilkoblingen til den nyopprettede serveren fra den bærbare datamaskinen, ble det klart at ideen om portvideresending var berettiget, og den bærbare datamaskinen min ble medlem av ruterens nettverk, selv om den ikke var fysisk i den.

Det var bare en liten ting igjen å gjøre: det var nødvendig å distribuere IP-adresser i forskjellige leiligheter slik at de ikke kom i konflikt og konfigurere ruterne som OpenVPN-klienter.
Følgende ruter-IP-adresser og DHCP-serverområder ble valgt:

  • 192.168.10.1 med rekkevidde 192.168.10.2 - 192.168.10.80 for serveren
  • 192.168.10.100 med rekkevidde 192.168.10.101 - 192.168.10.149 for ruteren i leilighet nr. 2
  • 192.168.10.150 med rekkevidde 192.168.10.151 - 192.168.10.199 for ruteren i leilighet nr. 3

Det var også nødvendig å tilordne nøyaktig disse adressene til klientruterne til OpenVPN-serveren ved å legge til linjen i konfigurasjonen:

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

og legger til følgende linjer i filen /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

der flat1_id og flat2_id er enhetsnavnene som er spesifisert når du oppretter sertifikater for tilkobling til OpenVPN

Deretter ble OpenVPN-klienter konfigurert på ruterne, tap0-enheter på begge ble lagt til br-lan-broen. På dette stadiet så alt ut til å være bra ettersom alle tre nettverkene kunne se hverandre og fungere som ett. En ikke særlig hyggelig detalj dukket imidlertid opp: noen ganger kunne enheter motta en IP-adresse som ikke var fra ruteren, med alle de påfølgende konsekvensene. Av en eller annen grunn hadde ikke ruteren i en av leilighetene tid til å svare på DHCPDISCOVER i tide, og enheten fikk en adresse som ikke var tiltenkt. Jeg innså at jeg må filtrere slike forespørsler i tap0 på hver av ruterne, men som det viste seg, kan ikke iptables fungere med enheten hvis den er en del av en bro, og ebtables må komme meg til hjelp. Til min beklagelse var det ikke i fastvaren min, og jeg måtte bygge om bildene for hver enhet. Ved å gjøre dette og legge til disse linjene til /etc/rc.local for hver ruter, ble problemet lø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

Denne konfigurasjonen varte i tre år.

Del 2: Vi introduserer WireGuard

Nylig har folk på Internett i økende grad begynt å snakke om WireGuard, og beundrer enkelheten i konfigurasjonen, høy overføringshastighet, lav ping med sammenlignbar sikkerhet. Å søke etter mer informasjon om det gjorde det klart at verken å jobbe som bromedlem eller jobbe over TCP-protokollen ble støttet av den, noe som fikk meg til å tenke at det fortsatt ikke var noen alternativer til OpenVPN for meg. Så jeg utsetter å bli kjent med WireGuard.

For noen dager siden spredte nyheter på ressurser på en eller annen måte relatert til IT at WireGuard endelig ville bli inkludert i Linux-kjernen, fra og med versjon 5.6. Nyhetsartikler, som alltid, berømmet WireGuard. Jeg kastet meg igjen ut i letingen etter måter å erstatte den gode gamle OpenVPN. Denne gangen traff jeg denne artikkelen. Den snakket om å lage en Ethernet-tunnel over L3 ved å bruke GRE. Denne artikkelen ga meg håp. Det forble uklart hva de skulle gjøre med UDP-protokollen. Søket førte meg til artikler om bruk av socat i forbindelse med en SSH-tunnel for å videresende en UDP-port, men de bemerket at denne tilnærmingen bare fungerer i enkelt tilkoblingsmodus, det vil si at arbeidet til flere VPN-klienter ville være umulig. Jeg kom på ideen om å installere en VPN-server på en VPS og sette opp GRE for klienter, men som det viste seg, støtter ikke GRE kryptering, noe som vil føre til at hvis tredjeparter får tilgang til serveren , vil all trafikk mellom nettverkene mine være i deres hender, noe som ikke passet meg i det hele tatt.

Nok en gang ble avgjørelsen tatt til fordel for redundant kryptering, ved å bruke VPN over VPN ved å bruke følgende skjema:

Nivå XNUMX VPN:
VPS er server med intern adresse 192.168.30.1
MS er klient VPS med intern adresse 192.168.30.2
MK2 er klient VPS med intern adresse 192.168.30.3
MK3 er klient VPS med intern adresse 192.168.30.4

Andre nivå VPN:
MS er server med ekstern adresse 192.168.30.2 og intern 192.168.31.1
MK2 er klient MS med adressen 192.168.30.2 og har en intern IP 192.168.31.2
MK3 er klient MS med adressen 192.168.30.2 og har en intern IP 192.168.31.3

* MS — ruter-server i leilighet 1, MK2 - ruter i leilighet 2, MK3 - ruter i leilighet 3
* Enhetskonfigurasjoner er publisert i spoileren på slutten av artikkelen.

Og så, ping kjører mellom nettverksnoder 192.168.31.0/24, det er på tide å gå videre til å sette opp en GRE-tunnel. Før dette, for ikke å miste tilgangen til rutere, er det verdt å sette opp SSH-tunneler for å videresende port 22 til VPS, slik at for eksempel ruteren fra leilighet 10022 vil være tilgjengelig på port 2 til VPS, og ruter fra leilighet 11122 vil være tilgjengelig på port 3 ruter fra leilighet XNUMX. Det er best å konfigurere videresending med samme sshtunnel, siden den vil gjenopprette tunnelen hvis den svikter.

Tunnelen er konfigurert, du kan koble til SSH via den videresendte porten:

ssh root@МОЙ_VPS -p 10022

Deretter bør du deaktivere OpenVPN:

/etc/init.d/openvpn stop

La oss nå sette opp en GRE-tunnel på ruteren fra leilighet 2:

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

Og legg til det opprettede grensesnittet til broen:

brctl addif br-lan grelan0

La oss utføre en lignende prosedyre på serverruteren:

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

Og legg også til det opprettede grensesnittet til broen:

brctl addif br-lan grelan0

fra og med dette øyeblikket begynner pings å gå til det nye nettverket, og jeg, med tilfredshet, drar for å drikke kaffe. Deretter, for å evaluere hvordan nettverket fungerer på den andre enden av linjen, prøver jeg å SSH inn i en av datamaskinene i leilighet 2, men ssh-klienten fryser uten å spørre om et passord. Jeg prøver å koble til denne datamaskinen via telnet på port 22, og jeg ser en linje som jeg kan forstå at tilkoblingen blir opprettet fra, SSH-serveren svarer, men av en eller annen grunn ber den meg bare ikke om å logge i.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Jeg prøver å koble til den via VNC og ser en svart skjerm. Jeg overbeviser meg selv om at problemet er med den eksterne datamaskinen, fordi jeg enkelt kan koble til ruteren fra denne leiligheten ved å bruke den interne adressen. Imidlertid bestemmer jeg meg for å koble til SSH-en til denne datamaskinen gjennom ruteren og er overrasket over å finne at tilkoblingen er vellykket, og den eksterne datamaskinen fungerer ganske normalt, men den kan heller ikke koble til datamaskinen min.

Jeg fjerner grelan0 enheten fra broen og kjører OpenVPN på ruteren i leilighet 2 og sørger for at nettverket fungerer som forventet igjen og at forbindelsene ikke faller ut. Ved å søke kommer jeg over fora der folk klager over de samme problemene, hvor de blir anbefalt å heve MTU. Ikke før sagt enn gjort. Men inntil MTU-en ble satt høyt nok - 7000 for gretap-enheter, ble enten tapte TCP-forbindelser eller lave overføringshastigheter observert. På grunn av den høye MTU for gretap, ble MTUene for Layer 8000 og Layer 7500 WireGuard-tilkoblinger satt til henholdsvis XNUMX og XNUMX.

Jeg utførte et lignende oppsett på ruteren fra leilighet 3, med den eneste forskjellen at et andre gretap-grensesnitt kalt grelan1 ble lagt til serverruteren, som også ble lagt til br-lan-broen.

Alt fungerer. Nå kan du sette gretap-enheten til oppstart. For dette:

Jeg plasserte disse linjene i /etc/rc.local på ruteren i leilighet 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

Lagt dette til /etc/rc.local på ruteren i leilighet 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

Og på serverruteren:

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

Etter å ha startet klientruterne på nytt, oppdaget jeg at de av en eller annen grunn ikke koblet til serveren. Etter å ha koblet til deres SSH (heldigvis hadde jeg tidligere konfigurert sshtunnel for dette), ble det oppdaget at WireGuard av en eller annen grunn laget en rute for endepunktet, men den var feil. Så for 192.168.30.2 indikerte rutetabellen en rute gjennom pppoe-wan-grensesnittet, det vil si gjennom Internett, selv om ruten til den burde vært rutet gjennom wg0-grensesnittet. Etter å ha slettet denne ruten, ble forbindelsen gjenopprettet. Jeg kunne ikke finne instruksjoner noe sted om hvordan jeg tvinge WireGuard til å ikke opprette disse rutene. Dessuten forsto jeg ikke engang om dette var en funksjon i OpenWRT eller WireGuard selv. Uten å måtte håndtere dette problemet over lang tid, la jeg ganske enkelt en linje til begge ruterne i et tidsstyrt skript som slettet denne ruten:

route del 192.168.30.2

Oppsummering

Jeg har ennå ikke oppnådd en fullstendig forlatelse av OpenVPN, siden jeg noen ganger trenger å koble til et nytt nettverk fra en bærbar datamaskin eller telefon, og å sette opp en gretap-enhet på dem er generelt umulig, men til tross for dette fikk jeg en fordel i hastigheten av dataoverføring mellom leiligheter og for eksempel bruk av VNC er ikke lenger upraktisk. Ping avtok litt, men ble mer stabil:

Når du bruker 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 bruker 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

Den er mer påvirket av den høye ping til VPS, som er omtrent 61.5 ms

Hastigheten har imidlertid økt betraktelig. Så i en leilighet med serverruter har jeg en Internett-tilkoblingshastighet på 30 Mbit/sek, og i andre leiligheter er den 5 Mbit/sek. Samtidig, mens jeg brukte OpenVPN, klarte jeg ikke å oppnå en dataoverføringshastighet mellom nettverk på mer enn 3,8 Mbit/sek i henhold til iperf-avlesninger, mens WireGuard «boost» den til de samme 5 Mbit/sek.

WireGuard-konfigurasjon 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-konfigurasjon på MS (lagt til /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-konfigurasjon på MK2 (lagt til /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-konfigurasjon på MK3 (lagt til /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 beskrevne konfigurasjonene for VPN på andre nivå peker jeg WireGuard-klienter til port 51821. I teorien er dette ikke nødvendig, siden klienten vil etablere en forbindelse fra en hvilken som helst ledig uprivilegert port, men jeg gjorde det slik at det var mulig å forby alle innkommende tilkoblinger på wg0-grensesnittene til alle rutere unntatt innkommende UDP-tilkoblinger til port 51821.

Jeg håper at artikkelen vil være nyttig for noen.

PS Jeg vil også dele skriptet mitt som sender meg et PUSH-varsel til telefonen min i WirePusher-applikasjonen når en ny enhet dukker opp på nettverket mitt. Her er linken til manuset: github.com/r0ck3r/device_discover.

UPDATE: Konfigurasjon av OpenVPN-server og klienter

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

Jeg brukte easy-rsa for å generere sertifikater

Kilde: www.habr.com

Legg til en kommentar