Perėjimas iš OpenVPN į WireGuard, kad tinklai būtų sujungti į vieną L2 tinklą

Perėjimas iš OpenVPN į WireGuard, kad tinklai būtų sujungti į 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

OpenVPN iš pradžių buvo pasirinktas kaip šios užduoties įgyvendinimo protokolas, nes, pirma, jis gali sukurti čiaupo įrenginį, kurį be problemų galima pridėti prie tilto, antra, OpenVPN palaiko veikimą per TCP protokolą, o tai taip pat buvo svarbu, nes nė vienas butas neturėjo specialaus IP adreso ir negalėjau naudotis STUN, nes mano IPT kažkodėl blokuoja įeinančius UDP ryšius iš jų tinklų, o TCP protokolas leido persiųsti VPN serverio prievadą nuomojamame VPS naudojant SSH. Taip, šis metodas suteikia didelę apkrovą, nes duomenys užšifruojami du kartus, bet aš nenorėjau įvesti VPS į savo privatų tinklą, nes vis tiek buvo rizika, kad trečiosios šalys jį perims, todėl turint tokį įrenginį namų tinkle buvo labai nepageidautina ir buvo nuspręsta už saugumą mokėti su didelėmis pridėtinėmis išlaidomis.

Norėdami persiųsti maršrutizatoriaus prievadą, kuriame buvo planuojama įdiegti serverį, buvo naudojama sshtunnel programa. Neapibūdinsiu jo konfigūracijos subtilybių – tai daroma gana lengvai, tik atkreipiu dėmesį, kad jo užduotis buvo TCP 1194 prievadą persiųsti iš maršrutizatoriaus į VPS. Tada OpenVPN serveris buvo sukonfigūruotas tap0 įrenginyje, kuris buvo prijungtas prie br-lan tilto. Patikrinus ryšį su naujai sukurtu serveriu iš nešiojamojo kompiuterio, paaiškėjo, kad prievado persiuntimo idėja pasiteisino ir mano nešiojamasis kompiuteris tapo maršrutizatoriaus tinklo nariu, nors fiziškai jame nebuvo.

Reikalas liko nedidelis: reikėjo paskirstyti IP adresus skirtinguose butuose, kad jie neprieštarautų, ir sukonfigūruoti maršrutizatorius kaip „OpenVPN“ klientus.
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 tiksliai šiuos adresus priskirti „OpenVPN“ serverio klientų maršrutizatoriams, pridedant 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 generuojant prisijungimo prie OpenVPN sertifikatus

Tada „OpenVPN“ klientai buvo sukonfigūruoti maršrutizatoriuose, abiejų „tap0“ įrenginiai buvo pridėti prie „br-lan“ tilto. Šiame etape viskas atrodė tvarkoje, nes visi trys tinklai mato vienas kitą ir veikia kaip visuma. Tačiau paaiškėjo ne itin maloni detalė: kartais įrenginiai gali gauti IP adresą ne iš savo maršrutizatoriaus, su visomis iš to išplaukiančiomis pasekmėmis. Kažkodėl maršrutizatorius viename bute nespėjo laiku atsakyti į DHCPDISCOVER ir įrenginys gavo neteisingą adresą. Supratau, kad turiu filtruoti tokias užklausas kiekvieno maršrutizatoriaus tap0, bet kaip paaiškėjo, iptables negali dirbti su įrenginiu, jei jis yra tilto dalis ir ebtables turėtų man padėti. Apgailestauju, jo nebuvo mano programinėje įrangoje ir turėjau iš naujo sukurti kiekvieno įrenginio vaizdus. Tai padarius ir įtraukus šias eilutes prie kiekvieno maršrutizatoriaus /etc/rc.local, 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: „WireGuard“ pristatymas

Pastaruoju metu internetas vis dažniau kalba apie „WireGuard“, žavėdamasis jo konfigūracijos paprastumu, dideliu perdavimo greičiu, mažu ping ir panašiu saugumu. Ieškant daugiau informacijos apie tai paaiškėjo, kad jis nepalaiko nei tilto nario, nei darbo su TCP protokolu, todėl susimąsčiau, kad man vis dar nėra alternatyvų OpenVPN. Taigi atidėjau pažintį su „WireGuard“.

Prieš kelias dienas per išteklius pasklido žinia, vienaip ar kitaip susijusi su IT, kad WireGuard pagaliau bus įtrauktas į Linux branduolį, pradedant nuo 5.6 versijos. Naujienų straipsniai, kaip visada, gyrė „WireGuard“. Vėl pasinėriau į paieškas, kaip pakeisti seną gerą OpenVPN. Šį kartą pabėgau Š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

Tada išjunkite 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štraukiu grelan0 įrenginį iš tilto ir paleidžiu OpenVPN maršrutizatoriuje 2 bute ir įsitikinu, kad tinklas vėl veikia tinkamai, o ryšiai nenutrūksta. Ieškodama aptinku forumus, kuriuose žmonės skundžiasi tomis pačiomis problemomis, kur jiems patariama kelti MTU. Ne anksčiau pasakyta, nei padaryta. Tačiau kol MTU nebuvo nustatytas pakankamai didelis iki 7000 gretap įrenginiams, buvo stebimas arba nutrūkęs TCP ryšys, arba lėtas perdavimas. Dėl didelio gretap MTU, pirmojo ir antrojo lygio WireGuard jungčių MTU buvo atitinkamai nustatyti 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 kliento maršrutizatorius, radau, kad jie kažkodėl neprisijungė prie serverio. Prisijungus prie jų SSH (laimei, anksčiau tam sukonfigūravau sshtunnel), buvo nustatyta, kad „WireGuard“ dėl kokių nors priežasčių sukuria maršrutą galutiniam taškui, nors jis yra neteisingas. Taigi 192.168.30.2 maršruto lentelė maršruto lentelėje buvo nurodyta per pppoe-wan sąsają, tai yra per internetą, nors maršrutas į ją turėjo būti nukreiptas per wg0 sąsają. Ištrynus šį maršrutą, ryšys buvo atkurtas. Niekur neradau instrukcijų, kaip priversti WireGuard nekurti šių maršrutų. Be to, aš net nesupratau, ar tai yra OpenWRT, ar paties WireGuard funkcija. Ilgai nespręsdamas šios problemos, aš tiesiog pridėjau prie abiejų maršrutizatorių scenarijuje, kurį sukūrė laikmatis, eilutę, kuri ištrynė šį maršrutą:

route del 192.168.30.2

Apibendrinant

Dar nepasiekiau visiško „OpenVPN“ atmetimo, nes kartais man reikia prisijungti prie naujo tinklo iš nešiojamojo kompiuterio ar telefono, o „gretap“ įrenginio nustatymas juose paprastai neįmanomas, tačiau nepaisant to, gavau pranašumą perduodant duomenis. greitis tarp butų ir, pavyzdžiui, VNC naudojimas nebėra nepatogus. Ping šiek tiek sumažėjo, bet tapo stabilesnis:

Kai naudojate 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 naudojate „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, kuriame yra maršrutizatorius-serveris, interneto ryšio greitis yra 30 Mbps, o kituose butuose - 5 Mbps. Tuo pačiu metu, naudodamas „OpenVPN“, negalėjau pasiekti didesnio nei 3,8 Mbps duomenų perdavimo spartos tarp tinklų pagal „iperf“, o „WireGuard“ jį „išpumpavo“ iki tų pačių 5 Mbps.

„WireGuard“ konfigūracija 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“ konfigūracija MS (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'

„WireGuard“ konfigūracija 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'

„WireGuard“ konfigūracija 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'

Apibūdintose antrojo lygio VPN konfigūracijose WireGuard klientams nurodau prievadą 51821. Teoriškai tai nėra būtina, nes klientas užmegs ryšį iš bet kurio nemokamo neprivilegijuoto prievado, bet aš padariau taip, kad visi įeinantys ryšiai gali būti uždraustas visų maršrutizatorių wg0 sąsajose, išskyrus įeinančius UDP ryšius per 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: OpenVPN serverio ir klientų konfigūracija

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

Добавить комментарий