Trecerea de la OpenVPN la WireGuard pentru a combina rețelele într-o singură rețea L2

Trecerea de la OpenVPN la WireGuard pentru a combina rețelele într-o singură rețea L2

Aș dori să împărtășesc experiența mea de a combina rețele în trei apartamente îndepărtate geografic, fiecare dintre ele utilizând routere cu OpenWRT ca gateway, într-o singură rețea comună. La alegerea unei metode de combinare a rețelelor între L3 cu rutare subrețea și L2 cu punte, când toate nodurile de rețea vor fi în aceeași subrețea, s-a acordat preferință celei de-a doua metode, care este mai dificil de configurat, dar oferă oportunități mai mari, deoarece utilizarea transparentă a tehnologiilor a fost planificată în rețeaua fiind creată Wake-on-Lan și DLNA.

Partea 1: Context

OpenVPN a fost ales inițial ca protocol pentru implementarea acestei sarcini, deoarece, în primul rând, poate crea un dispozitiv de atingere care poate fi adăugat la bridge fără probleme, iar în al doilea rând, OpenVPN acceptă operarea prin protocolul TCP, ceea ce a fost de asemenea important, deoarece niciunul dintre apartamente aveau o adresă IP dedicată și nu am putut folosi STUN, deoarece furnizorul meu blochează din anumite motive conexiunile UDP de intrare din rețelele lor, în timp ce protocolul TCP îmi permitea să redirecționez portul serverului VPN către VPS închiriat folosind SSH. Da, această abordare oferă o sarcină mare, deoarece datele sunt criptate de două ori, dar nu am vrut să introduc un VPS în rețeaua mea privată, deoarece mai exista riscul ca terți să obțină controlul asupra acestuia, prin urmare, având un astfel de dispozitiv pe rețeaua mea de acasă a fost extrem de nedorit și sa decis să plătească pentru securitate cu o suprasolicitare mare.

Pentru a redirecționa portul de pe router-ul pe care a fost planificat să implementeze serverul, a fost folosit programul sshtunnel. Nu voi descrie complexitățile configurației sale - se face destul de ușor, voi reține doar că sarcina sa a fost să redirecționeze portul TCP 1194 de la router la VPS. Apoi, serverul OpenVPN a fost configurat pe dispozitivul tap0, care a fost conectat la podul br-lan. După ce am verificat conexiunea la serverul nou creat de pe laptop, a devenit clar că ideea de redirecționare a porturilor era justificată și laptopul meu a devenit membru al rețelei routerului, deși nu era fizic în ea.

A mai rămas un singur lucru mic de făcut: a fost necesar să se distribuie adrese IP în diferite apartamente, astfel încât acestea să nu intre în conflict și să configureze routerele ca clienți OpenVPN.
Au fost selectate următoarele adrese IP ale routerului și intervale de server DHCP:

  • 192.168.10.1 cu raza de actiune 192.168.10.2 - 192.168.10.80 pentru server
  • 192.168.10.100 cu raza de actiune 192.168.10.101 - 192.168.10.149 pentru routerul din apartamentul nr. 2
  • 192.168.10.150 cu raza de actiune 192.168.10.151 - 192.168.10.199 pentru routerul din apartamentul nr. 3

De asemenea, a fost necesar să se atribuie exact aceste adrese routerelor client ale serverului OpenVPN adăugând linia la configurația sa:

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

și adăugând următoarele linii în fișierul /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

unde flat1_id și flat2_id sunt numele dispozitivelor specificate la crearea certificatelor pentru conectarea la OpenVPN

Apoi, clienții OpenVPN au fost configurați pe routere, dispozitivele tap0 de pe ambele au fost adăugate la podul br-lan. În această etapă, totul părea să fie bine, deoarece toate cele trei rețele se puteau vedea și funcționa ca una. Cu toate acestea, a apărut un detaliu nu foarte plăcut: uneori dispozitivele puteau primi o adresă IP nu de la routerul lor, cu toate consecințele care decurg. Din anumite motive, routerul din unul dintre apartamente nu a avut timp să răspundă la DHCPDISCOVER la timp, iar dispozitivul a primit o adresă care nu a fost destinată. Mi-am dat seama că trebuie să filtrez astfel de solicitări în tap0 pe fiecare dintre routere, dar după cum sa dovedit, iptables nu poate funcționa cu dispozitivul dacă face parte dintr-un bridge și ebtables trebuie să-mi vină în ajutor. Spre regretul meu, nu era în firmware-ul meu și a trebuit să reconstruiesc imaginile pentru fiecare dispozitiv. Făcând acest lucru și adăugând aceste linii în /etc/rc.local al fiecărui router, problema a fost rezolvată:

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

Această configurație a durat trei ani.

Partea 2: Prezentarea WireGuard

Recent, oamenii de pe Internet au început să vorbească din ce în ce mai mult despre WireGuard, admirând simplitatea configurației sale, viteza mare de transmisie, ping scăzut cu securitate comparabilă. Căutând mai multe informații despre acesta, a arătat clar că nici lucrul ca membru al bridge-ului, nici lucrul peste protocolul TCP nu este susținut de acesta, ceea ce m-a făcut să cred că încă nu există alternative la OpenVPN pentru mine. Așa că am amânat să cunosc WireGuard.

În urmă cu câteva zile, știrile s-au răspândit în resurse într-un fel sau altul legate de IT că WireGuard va fi în sfârșit inclus în kernel-ul Linux, începând cu versiunea 5.6. Articolele de știri, ca întotdeauna, l-au lăudat pe WireGuard. M-am cufundat din nou în căutarea modalităților de a înlocui vechiul OpenVPN. De data asta am dat peste acest articol. Se vorbea despre crearea unui tunel Ethernet peste L3 folosind GRE. Acest articol mi-a dat speranță. A rămas neclar ce să facă cu protocolul UDP. Căutarea m-a condus la articole despre utilizarea socat împreună cu un tunel SSH pentru a redirecționa un port UDP, totuși, ei au observat că această abordare funcționează doar în modul de conexiune unică, adică munca mai multor clienți VPN ar fi imposibilă. Mi-a venit ideea de a instala un server VPN pe un VPS și de a configura GRE pentru clienți, dar după cum s-a dovedit, GRE nu acceptă criptarea, ceea ce va duce la faptul că, dacă terții vor obține acces la server , tot traficul dintre rețelele mele va fi în mâinile lor , ceea ce nu mi se potrivea deloc.

Încă o dată, decizia a fost luată în favoarea criptării redundante, prin utilizarea VPN peste VPN folosind următoarea schemă:

VPN de nivel XNUMX:
VPS este Server cu adresa internă 192.168.30.1
MS este client VPS cu adresa internă 192.168.30.2
МК2 este client VPS cu adresa internă 192.168.30.3
МК3 este client VPS cu adresa internă 192.168.30.4

VPN de al doilea nivel:
MS este Server cu adresa externă 192.168.30.2 și internă 192.168.31.1
МК2 este client MS cu adresa 192.168.30.2 și are un IP intern 192.168.31.2
МК3 este client MS cu adresa 192.168.30.2 și are un IP intern 192.168.31.3

* MS — router-server în apartamentul 1, МК2 - router în apartamentul 2, МК3 - router in apartamentul 3
* Configurațiile dispozitivului sunt publicate în spoilerul de la sfârșitul articolului.

Și astfel, ping-urile rulează între nodurile de rețea 192.168.31.0/24, este timpul să trecem la configurarea unui tunel GRE. Înainte de aceasta, pentru a nu pierde accesul la routere, merită să configurați tuneluri SSH pentru a transmite portul 22 către VPS, astfel încât, de exemplu, routerul din apartamentul 10022 să fie accesibil pe portul 2 al VPS-ului, iar routerul din apartamentul 11122 va fi accesibil pe portul 3 routerul din apartamentul XNUMX. Cel mai bine este să configurați redirecționarea folosind același sshtunnel, deoarece va restabili tunelul dacă nu reușește.

Tunelul este configurat, vă puteți conecta la SSH prin portul redirecționat:

ssh root@МОЙ_VPS -p 10022

În continuare, ar trebui să dezactivați OpenVPN:

/etc/init.d/openvpn stop

Acum să instalăm un tunel GRE pe routerul din apartamentul 2:

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

Și adăugați interfața creată la punte:

brctl addif br-lan grelan0

Să efectuăm o procedură similară pe routerul serverului:

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

Și adăugați, de asemenea, interfața creată la punte:

brctl addif br-lan grelan0

incepand din acest moment, ping-urile incep sa mearga cu succes in noua retea si eu, cu satisfactie, merg sa beau cafea. Apoi, pentru a evalua modul în care funcționează rețeaua la celălalt capăt al liniei, încerc să fac SSH într-unul dintre computerele din apartamentul 2, dar clientul ssh se blochează fără a cere o parolă. Încerc să mă conectez la acest computer prin telnet pe portul 22 și văd o linie de la care pot înțelege că se stabilește conexiunea, serverul SSH răspunde, dar din anumite motive pur și simplu nu mă solicită să mă înregistrez în.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Încerc să mă conectez la el prin VNC și văd un ecran negru. Mă conving că problema este la computerul de la distanță, pentru că mă pot conecta cu ușurință la router din acest apartament folosind adresa internă. Cu toate acestea, decid să mă conectez la SSH-ul acestui computer prin router și sunt surprins să constat că conexiunea este reușită, iar computerul de la distanță funcționează destul de normal, dar nici nu se poate conecta la computerul meu.

Scot dispozitivul grelan0 de pe bridge și rulez OpenVPN pe routerul din apartamentul 2 și mă asigur că rețeaua funcționează din nou conform așteptărilor și conexiunile nu sunt întrerupte. Căutând dau peste forumuri în care oamenii se plâng de aceleași probleme, unde sunt sfătuiți să ridice MTU. Făcut repede şi foarte bine. Cu toate acestea, până când MTU a fost setat suficient de mare - 7000 pentru dispozitivele gretap, fie scăderea conexiunilor TCP, fie s-au observat rate de transfer scăzute. Datorită MTU-ului mare pentru gretap, MTU-urile pentru conexiunile WireGuard Layer 8000 și Layer 7500 au fost setate la XNUMX și, respectiv, XNUMX.

Am efectuat o configurare similară pe routerul din apartamentul 3, singura diferență fiind că la router-ul serverului a fost adăugată o a doua interfață gretap numită grelan1, care a fost adăugată și la podul br-lan.

Totul merge. Acum puteți pune ansamblul gretap la pornire. Pentru aceasta:

Am plasat aceste linii în /etc/rc.local pe routerul din apartamentul 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

Am adăugat acest lucru la /etc/rc.local pe routerul din apartamentul 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

Și pe routerul serverului:

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

După ce am repornit routerele client, am descoperit că din anumite motive nu se conectează la server. După ce se conectează la SSH-ul lor (din fericire, configurasem anterior sshtunnel pentru asta), s-a descoperit că WireGuard, dintr-un motiv oarecare, crea o rută pentru punctul final, dar era incorectă. Deci, pentru 192.168.30.2, tabelul de rute a indicat o rută prin interfața pppoe-wan, adică prin Internet, deși ruta către acesta ar fi trebuit direcționată prin interfața wg0. După ștergerea acestei rute, conexiunea a fost restabilită. Nu am putut găsi nicăieri instrucțiuni despre cum să forțez WireGuard să nu creeze aceste rute. Mai mult, nici măcar nu am înțeles dacă aceasta era o caracteristică a OpenWRT sau a WireGuard în sine. Fără a fi nevoit să mă ocup de această problemă mult timp, am adăugat pur și simplu o linie la ambele routere într-un script temporizat care a șters această rută:

route del 192.168.30.2

Rezumând

Nu am reușit încă o abandonare completă a OpenVPN, deoarece uneori trebuie să mă conectez la o nouă rețea de pe un laptop sau telefon, iar configurarea unui dispozitiv gretap pe ele este în general imposibilă, dar, în ciuda acestui fapt, am primit un avantaj în viteză. a transferului de date între apartamente și, de exemplu, utilizarea VNC nu mai este incomod. Ping-ul a scăzut ușor, dar a devenit mai stabil:

Când utilizați 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

Când utilizați 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

Este mai afectat de ping-ul ridicat la VPS, care este de aproximativ 61.5 ms

Cu toate acestea, viteza a crescut semnificativ. Deci, intr-un apartament cu router server am o viteza de conectare la Internet de 30 Mbit/sec, iar in alte apartamente este de 5 Mbit/sec. În același timp, în timp ce foloseam OpenVPN, nu am reușit să obțin o viteză de transfer de date între rețele mai mare de 3,8 Mbit/sec conform citirilor iperf, în timp ce WireGuard l-a „amplificat” la aceeași 5 Mbit/sec.

Configurare WireGuard pe 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

Configurare WireGuard pe MS (adăugat la /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'

Configurare WireGuard pe MK2 (adăugat la /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'

Configurare WireGuard pe MK3 (adăugat la /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'

În configurațiile descrise pentru VPN de nivel al doilea, îndrept clienții WireGuard către portul 51821. În teorie, acest lucru nu este necesar, deoarece clientul va stabili o conexiune de la orice port liber neprivilegiat, dar am făcut-o astfel încât să fie posibil să interzic toate conexiunile de intrare pe interfețele wg0 ale tuturor routerelor, cu excepția conexiunilor UDP de intrare la portul 51821.

Sper ca articolul sa fie de folos cuiva.

PS De asemenea, vreau să partajez scriptul meu care îmi trimite o notificare PUSH către telefonul meu în aplicația WirePusher atunci când apare un dispozitiv nou în rețeaua mea. Iată link-ul către script: github.com/r0ck3r/device_discover.

ACTUALIZAȚI: Configurarea serverului și clienților OpenVPN

Server OpenVPN

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

Client OpenVPN

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

Am folosit easy-rsa pentru a genera certificate

Sursa: www.habr.com

Adauga un comentariu