Perekhod s OpenVPN apie WireGuard sujungti tinklus į vieną L2 tinklą

Perekhod s OpenVPN apie WireGuard sujungti tinklus į vieną L2 tinklą

Norėčiau pasidalinti savo patirtimi, kaip sujungti tinklus trijuose geografiškai nutolusiuose butuose, kurių kiekvienas naudoja maršrutizatorius su OpenWRT kaip vartais, į vieną bendrą tinklą. Renkantis metodą tinklų sujungimui tarp L3 su potinklio maršruto parinkimu ir L2 su tiltu, kai visi tinklo mazgai bus tame pačiame potinklyje, pirmenybė buvo teikiama antrajam metodui, kurį sunkiau konfigūruoti, bet suteikia daugiau galimybių, nes skaidrus. sukurtame tinkle Wake-on-Lan ir DLNA buvo numatytas technologijų panaudojimas.

1 dalis: Fonas

Iš pradžių šiai užduočiai įgyvendinti buvo pasirinktas protokolas OpenVPN, nes, pirma, tai gali sukurti čiaupo įrenginį, kurį galima be jokių problemų pridėti prie tilto, ir, antra, OpenVPN Jis palaiko TCP, o tai taip pat buvo svarbu, nes nė vienas butas neturėjo dedikuoto IP adreso. Negalėjau naudoti STUN, nes mano interneto paslaugų teikėjas dėl kažkokių priežasčių blokuoja įeinančius UDP ryšius iš savo tinklų. TCP leido man peradresuoti VPN serverio prievadą į nuomojamą VPS naudojant SSH. Nors šis metodas sukuria dideles išlaidas, nes duomenys yra dvigubai šifruojami, nenorėjau integruoti VPS į savo privatų tinklą, nes buvo rizika, kad trečiosios šalys jį kontroliuos. Todėl turėti tokį įrenginį savo namų tinkle buvo labai nepageidautina, todėl nusprendžiau sumokėti dideles išlaidas už saugumą.

Norėdamas peradresuoti maršrutizatoriaus, kuriame planavau dislokuoti serverį, prievadą, panaudojau „sshtunnel“ programą. Nesileisiu į jos konfigūracijos detales – tai gana paprasta. Tiesiog pažymėsiu, kad jos paskirtis buvo peradresuoti TCP 1194 prievadą iš maršrutizatoriaus į VPS. Toliau sukonfigūravau serverį. OpenVPN „Tap0“ įrenginyje, kuris buvo prijungtas prie „br-lan“ tilto. Išbandžius ryšį su naujai sukurtu serveriu iš mano nešiojamojo kompiuterio, paaiškėjo, kad prievadų peradresavimo idėja suveikė, ir mano nešiojamasis kompiuteris tapo maršrutizatoriaus tinklo nariu, nors fiziškai jame nebuvo.

Beliko tik paskirstyti IP adresus skirtinguose butuose, kad jie nekonfliktuotų, ir sukonfigūruoti maršrutizatorius taip, kad OpenVPN-klientai.
Buvo pasirinkti šie maršrutizatoriaus IP adresai ir DHCP serverio diapazonai:

  • 192.168.10.1 su diapazonu 192.168.10.2 - 192.168.10.80 serveriui
  • 192.168.10.100 su diapazonu 192.168.10.101 - 192.168.10.149 už maršrutizatorių bute Nr.2
  • 192.168.10.150 su diapazonu 192.168.10.151 - 192.168.10.199 už maršrutizatorių bute Nr.3

Taip pat reikėjo šiuos adresus priskirti klientų maršrutizatoriams. OpenVPN-server, pridėdami šią eilutę prie jo konfigūracijos:

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

ir į /etc/openvpn/ipp.txt failą pridėkite šias eilutes:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

kur flat1_id ir flat2_id yra įrenginių pavadinimai, nurodyti kuriant sertifikatus prisijungimui prie OpenVPN

Toliau buvo sukonfigūruoti maršrutizatoriai OpenVPN- prie br-lan tilto buvo pridėti abiejų įrenginių „tap0“ klientai. Šiuo metu viskas atrodė gerai, nes visi trys tinklai galėjo matyti vienas kitą ir funkcionuoti kaip vienas vienetas. Tačiau išryškėjo gana nemaloni detalė: kartais įrenginiai gaudavo IP adresą iš netinkamo maršrutizatoriaus su visomis iš to kylančiomis pasekmėmis. Dėl kažkokių priežasčių vieno iš butų maršrutizatorius laiku neatsakė į DHCPDISCOVER, ir įrenginys gavo neteisingą adresą. Supratau, kad tokias užklausas reikia filtruoti kiekvieno maršrutizatoriaus „tap0“ programoje, bet, kaip paaiškėjo, „iptables“ negali veikti su įrenginiu, jei jis yra tilto dalis, todėl man reikėjo naudoti „ebtables“. Deja, mano programinėje įrangoje jos nebuvo, todėl turėjau iš naujo sukurti kiekvieno įrenginio atvaizdus. Tai padarius ir pridėjus šias eilutes į kiekvieno maršrutizatoriaus /etc/rc.local failą, problema buvo išspręsta:

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

Ši konfigūracija truko trejus metus.

2 dalis: Pažintis WireGuard

Pastaruoju metu internete vis dažniau kalbama apie WireGuard, žavėdamasis jo konfigūravimo paprastumu, dideliu perdavimo greičiu, mažu ping ir panašiu saugumu. Ieškant papildomos informacijos apie jį paaiškėjo, kad jis nepalaiko nei tilto nario, nei TCP protokolo palaikymo, todėl susidariau įspūdį, kad alternatyvos nėra. OpenVPN man to vis dar nėra. Todėl atidėliojau pažintį WireGuard.

Prieš kelias dienas per su IT susijusius išteklius pasklido žinia, kad vienaip ar kitaip WireGuard pagaliau bus įtrauktas į branduolį Linux, pradedant nuo 5.6 versijos. Naujienų straipsniai, kaip visada, buvo giriami WireGuardVėl pasinėriau į būdų, kaip pakeisti seną gerą OpenVPNŠį kartą susidūriau Šis straipsnis. Jame buvo kalbama apie Ethernet tunelio sukūrimą per L3 naudojant GRE. Šis straipsnis suteikė man vilties. Liko neaišku, ką daryti su UDP protokolu. Paieška privedė mane prie straipsnių apie „socat“ naudojimą kartu su SSH tuneliu UDP prievadui persiųsti, tačiau jie pažymėjo, kad šis metodas veikia tik vieno ryšio režimu, o tai reiškia, kad keli VPN klientai būtų neįmanomi. Aš sugalvojau nustatyti VPN serverį VPS ir nustatyti GRE klientams, tačiau, kaip paaiškėjo, GRE nepalaiko šifravimo, o tai lems tai, kad jei trečiosios šalys gaus prieigą prie serverio , visas srautas tarp mano tinklų yra jų rankose, o tai man visiškai netiko.

Vėlgi, buvo priimtas sprendimas pertekliniam šifravimui naudojant VPN per VPN pagal šią schemą:

XNUMX sluoksnio VPN:
VPS yra serveris su vidiniu adresu 192.168.30.1
MS yra klientas VPS su vidiniu adresu 192.168.30.2
МК2 yra klientas VPS su vidiniu adresu 192.168.30.3
МК3 yra klientas VPS su vidiniu adresu 192.168.30.4

XNUMX sluoksnio VPN:
MS yra serveris su išoriniu adresu 192.168.30.2 ir vidiniu adresu 192.168.31.1
МК2 yra klientas MS kurio adresas yra 192.168.30.2 ir vidinis IP yra 192.168.31.2
МК3 yra klientas MS kurio adresas yra 192.168.30.2 ir vidinis IP yra 192.168.31.3

* MS - maršrutizatorius-serveris 1 bute, МК2 - maršrutizatorius 2 bute, МК3 - Maršrutizatorius 3 bute
* Įrenginių konfigūracijos skelbiamos spoileryje straipsnio pabaigoje.

Taigi, pingas tarp tinklo 192.168.31.0/24 mazgų vyksta, laikas pereiti prie GRE tunelio nustatymo. Prieš tai, kad neprarastumėte prieigos prie maršrutizatorių, verta nustatyti SSH tunelius 22 prievadui persiųsti į VPS, kad, pavyzdžiui, maršrutizatorius iš 10022 buto būtų pasiekiamas VPS 2 prievade ir maršrutizatorius iš buto 11122 bus pasiekiamas VPS prievade 3. Maršrutizatorius iš buto XNUMX. Geriausia sukonfigūruoti persiuntimą su tuo pačiu sshtuneliu, nes jis atkurs tunelį, jei jis nukris.

Tunelis sukonfigūruotas, prie SSH galite prisijungti per persiųstą prievadą:

ssh root@МОЙ_VPS -p 10022

Toliau turėtumėte išjungti OpenVPN:

/etc/init.d/openvpn stop

Dabar nustatykime GRE tunelį maršrutizatoriuje iš 2 buto:

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

Ir pridėkite sukurtą sąsają prie tilto:

brctl addif br-lan grelan0

Atlikime panašią procedūrą serverio maršrutizatoriuje:

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

Taip pat pridėkite sukurtą sąsają prie tilto:

brctl addif br-lan grelan0

nuo šios akimirkos pingai pradeda sėkmingai pereiti į naują tinklą ir aš su pasitenkinimu einu gerti kavos. Tada, norėdamas pamatyti, kaip veikia tinklas kitame laido gale, bandau SSH įvesti į vieną iš 2 buto kompiuterių, tačiau ssh klientas užšąla neprašydamas įvesti slaptažodžio. Bandau prisijungti prie šio kompiuterio per telnet per 22 prievadą ir matau eilutę, iš kurios galima suprasti, kad ryšys užmezgamas, SSH serveris reaguoja, bet kažkodėl nesiūlo įeiti.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Bandau prisijungti prie jo per VNC ir matau juodą ekraną. Įtikinu save, kad reikalas yra nuotoliniame kompiuteryje, nes iš šio buto galiu lengvai prisijungti prie maršrutizatoriaus, naudodamas vidinį adresą. Tačiau nusprendžiu SSH prisijungti prie šio kompiuterio per maršruto parinktuvą ir nustebau pastebėjęs, kad prisijungti pavyko, o nuotolinis kompiuteris veikia gerai, bet nepavyksta prisijungti ir prie mano kompiuterio.

Iš tilto išimu „grelan0“ įrenginį ir jį paleidžiu. OpenVPN Antrame bute esančiame maršrutizatoriuje patvirtinau, kad tinklas vėl veikia tinkamai ir ryšiai nenutrūksta. Ieškodamas aptikau forumus, kuriuose žmonės skundėsi tomis pačiomis problemomis ir patarė padidinti MTU. Vos tik pasakyta, padaryta. Tačiau kol MTU nebuvo nustatytas pakankamai didelis – 7000 „gretap“ įrenginiams – nutrūkdavo TCP ryšiai arba sumažėdavo perdavimo greitis. Dėl didelio „gretap“ MTU, ryšių MTU... WireGuard Pirmasis ir antrasis lygiai buvo nustatyti atitinkamai ties 8000 ir 7500.

Panašiai nustatiau maršrutizatorių iš 3 buto, vienintelis skirtumas yra tas, kad prie serverio maršrutizatoriaus buvo pridėta antroji gretap sąsaja, pavadinta grelan1, kuri taip pat buvo pridėta prie br-lan tilto.

Viskas veikia. Dabar galite įdėti gretap agregatą į automatinį įkėlimą. Už tai:

Įdėjote šias eilutes į /etc/rc.local maršrutizatoriuje 2 bute:

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

Pridėta tai prie /etc/rc.local maršrutizatoriuje 3 bute:

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

Ir serverio maršrutizatoriuje:

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

Perkrovęs klientų maršrutizatorius, aptikau, kad dėl kažkokios priežasties jie neprisijungia prie serverio. Prisijungęs prie jų SSH (laimei, anksčiau tam buvau sukonfigūravę „sshtunnel“), aptikau, kad WireGuard Dėl kažkokios priežasties sukuriamas maršrutas galiniam taškui, bet jis neteisingas. Pavyzdžiui, 192.168.30.2 atveju maršrutų lentelėje nurodytas maršrutas per pppoe-wan sąsają, t. y. per internetą, nors maršrutas į jį turėjo būti nukreiptas per wg0 sąsają. Ištrynus šį maršrutą, ryšys buvo atkurtas. Ar galiu kur nors rasti instrukcijas, kaip priversti... WireGuard Negalėjau išvengti šių maršrutų kūrimo. Be to, net nesupratau, ar tai buvo „OpenWRT“ funkcija, ar... WireGuardNegaišdamas daug laiko problemos sprendimui, tiesiog pridėjau eilutę prie laikmačio pagrindu veikiančio scenarijaus abiejuose maršrutizatoriuose, kuri ištrynė šį maršrutą:

route del 192.168.30.2

Apibendrinant

Visiškas atmetimas OpenVPN Man dar nepavyko to pasiekti, nes kartais reikia prisijungti prie naujo tinklo iš nešiojamojo kompiuterio ar telefono, o nustatyti „gretap“ įrenginį juose paprastai neįmanoma. Tačiau nepaisant to, įgijau duomenų perdavimo greičio pranašumą tarp butų, o, pavyzdžiui, VNC naudojimas dabar yra be rūpesčių. „Ping“ šiek tiek sumažėjo, bet tapo stabilesnis:

kai naudojant 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

kai naudojant 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

Jai daugiausia įtakos turi didelis ping į VPS, kuris yra maždaug 61.5 ms

Tačiau greitis gerokai padidėjo. Taigi, bute su maršrutizatoriumi-serveriu interneto ryšio greitis yra 30 Mbps, o kituose butuose – 5 Mbps. Be to, naudojimo metu... OpenVPN Remiantis „iPerf“ rodmenimis, man nepavyko pasiekti didesnio nei 3,8 Mbps duomenų perdavimo greičio tarp tinklų, nors WireGuard „pakėlė“ jį iki tų pačių 5 Mbit/sek.

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

[Bendraamžis]
Viešas raktas = <VPN_1_MS_PUBLIC_KEY>
Leistini IP = 192.168.30.2/32

[Bendraamžis]
Viešas raktas = <VPN_2_MK2_VISUOMENIS_KEY>
Leistini IP = 192.168.30.3/32

[Bendraamžis]
Viešas raktas = <VPN_2_MK3_VISUOMENIS_KEY>
Leistini IP = 192.168.30.4/32

Konfigūravimas WireGuard MS sistemoje (pridėta prie /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'

Konfigūravimas WireGuard MK2 (pridėta prie /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'

Konfigūravimas WireGuard MK3 (pridėta prie /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'

Aprašytose antrojo lygio VPN konfigūracijose klientams nurodau WireGuard 51821 prievadas. To neturėtų reikėti, nes klientas užmegs ryšį iš bet kurio laisvo, neprivilegijuoto prievado, bet aš tai padariau taip, kad galėčiau uždrausti visus įeinančius ryšius visų maršrutizatorių wg0 sąsajose, išskyrus įeinančius UDP ryšius į 51821 prievadą.

Tikiuosi, kad straipsnis bus kam nors naudingas.

PS Taip pat noriu pasidalinti savo scenarijumi, kuris siunčia man PUSH pranešimą į mano telefoną programoje WirePusher, kai tinkle pasirodo naujas įrenginys. Čia yra nuoroda į scenarijų: github.com/r0ck3r/device_discover.

UPDATE: Konfigūravimas OpenVPN- serveriai ir klientai

OpenVPN- serveris

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

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

Sertifikatams generuoti naudojau easy-rsa.

Šaltinis: www.habr.com

Pirkite patikimą prieglobą svetainėms su DDoS apsauga, VPS VDS serveriais 🔥 Įsigykite patikimą svetainių talpinimą su DDoS apsauga, VPS VDS serveriais | ProHoster