Migrace z OpenVPN na WireGuard za účelem konsolidace sítí do jedné sítě L2

Migrace z OpenVPN na WireGuard za účelem konsolidace sítí do jedné sítě L2

Rád bych se podělil o své zkušenosti se spojením sítí ve třech geograficky vzdálených bytech, z nichž každý používá routery s OpenWRT jako bránu, do jedné společné sítě. Při výběru metody pro kombinaci sítí mezi L3 se směrováním podsítě a L2 s přemostěním, kdy všechny síťové uzly budou ve stejné podsíti, byla dána přednost druhému způsobu, který je obtížnější na konfiguraci, ale poskytuje více příležitostí, protože transparentní využití technologií bylo plánováno ve vytvořené síti Wake-on-Lan a DLNA.

Část 1: Pozadí

OpenVPN byl původně vybrán jako protokol pro implementaci tohoto úkolu, protože za prvé dokáže vytvořit tap zařízení, které lze bez problémů přidat do mostu, a za druhé OpenVPN podporuje provoz přes protokol TCP, což bylo také důležité, protože žádný z apartmánů neměl vyhrazenou IP adresu a nemohl jsem použít STUN, protože můj ISP z nějakého důvodu blokuje příchozí UDP spojení ze svých sítí, zatímco protokol TCP mi umožňoval přesměrovat port serveru VPN na pronajatém VPS pomocí SSH. Ano, tento přístup dává velké zatížení, protože data jsou šifrována dvakrát, ale nechtěl jsem zavést VPS do své privátní sítě, protože stále existovalo riziko, že nad ním získají kontrolu třetí strany, a proto mít takové zařízení na domácí síti bylo krajně nežádoucí a bylo rozhodnuto platit za bezpečnost velkou režii.

K předání portu na routeru, na kterém bylo plánováno nasazení serveru, byl použit program sshtunnel. Nebudu popisovat záludnosti jeho konfigurace – to se provádí celkem jednoduše, jen podotýkám, že jeho úkolem bylo předat TCP port 1194 z routeru do VPS. Dále byl nakonfigurován server OpenVPN na zařízení tap0, které bylo připojeno k mostu br-lan. Po kontrole připojení k nově vytvořenému serveru z notebooku bylo jasné, že myšlenka přesměrování portů se opodstatnila a můj notebook se stal členem sítě routeru, ačkoliv v ní fyzicky nebyl.

Záležitost zůstala malá: bylo nutné distribuovat IP adresy v různých bytech tak, aby nebyly v konfliktu, a nakonfigurovat routery jako klienty OpenVPN.
Byly vybrány následující adresy IP routeru a rozsahy serverů DHCP:

  • 192.168.10.1 s rozsahem 192.168.10.2 - 192.168.10.80 pro server
  • 192.168.10.100 s rozsahem 192.168.10.101 - 192.168.10.149 pro router v bytě č. 2
  • 192.168.10.150 s rozsahem 192.168.10.151 - 192.168.10.199 pro router v bytě č. 3

Bylo také nutné přiřadit přesně tyto adresy klientským routerům OpenVPN serveru přidáním řádku do jeho konfigurace:

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

a přidáním následujících řádků do souboru /etc/openvpn/ipp.txt:

flat1_id 192.168.10.100
flat2_id 192.168.10.150

kde flat1_id a flat2_id jsou názvy zařízení zadané při generování certifikátů pro připojení k OpenVPN

Dále byli klienti OpenVPN nakonfigurováni na routerech, zařízení tap0 na obou byla přidána do br-lan bridge. V této fázi se zdálo být vše v pořádku, protože všechny tři sítě se navzájem vidí a fungují jako celek. Ukázalo se však nepříliš příjemný detail: někdy zařízení mohla získat IP adresu nikoli ze svého routeru, se všemi z toho vyplývajícími důsledky. Router v jednom z bytů z nějakého důvodu nestihl včas zareagovat na DHCPDISCOVER a zařízení obdrželo špatnou adresu. Uvědomil jsem si, že takové požadavky musím filtrovat v tap0 na každém z routerů, ale jak se ukázalo, iptables neumí pracovat se zařízením, pokud je součástí mostu a na pomoc by mi měly přijít ebtables. K mé lítosti to nebylo v mém firmwaru a musel jsem znovu sestavit obrázky pro každé zařízení. Tím a přidáním těchto řádků do /etc/rc.local každého routeru byl problém vyřešen:

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

Tato konfigurace vydržela tři roky.

Část 2: Představení WireGuard

Internet v poslední době stále častěji mluví o WireGuard, obdivuje jednoduchost jeho konfigurace, vysokou přenosovou rychlost, nízký ping při srovnatelném zabezpečení. Hledání dalších informací o něm ukázalo, že není podporována ani práce jako člen mostu, ani práce na protokolu TCP, což mě přimělo k tomu, že pro mě stále neexistují žádné alternativy k OpenVPN. Takže jsem odložil seznámení s WireGuardem.

Před několika dny se prostřednictvím zdrojů tak či onak souvisejících s IT rozšířila zpráva, že WireGuard bude konečně zahrnut do linuxového jádra, počínaje verzí 5.6. Zpravodajské články jako vždy chválily WireGuard. Znovu jsem se vrhl do hledání způsobů, jak nahradit staré dobré OpenVPN. Tentokrát jsem narazil tento článek. Mluvilo se o vytvoření ethernetového tunelu přes L3 pomocí GRE. Tento článek mi dal naději. Zůstalo nejasné, co dělat s protokolem UDP. Hledání mě přivedlo k článkům o použití socatu ve spojení s tunelem SSH k předávání portu UDP, ale poznamenali, že tento přístup funguje pouze v režimu jednoho připojení, což znamená, že více klientů VPN by nebylo možné. Přišel jsem s nápadem nastavit VPN server na VPS a nakonfigurovat GRE pro klienty, ale jak se ukázalo, GRE nepodporuje šifrování, což povede k tomu, že pokud třetí strany získají přístup k serveru, veškerý provoz mezi mými sítěmi je v jejich rukou, což mi vůbec nevyhovovalo.

Opět bylo rozhodnuto ve prospěch redundantního šifrování pomocí VPN přes VPN podle následujícího schématu:

VPN vrstvy XNUMX:
VPS to je server s interní adresou 192.168.30.1
MS to je klient VPS s interní adresou 192.168.30.2
MK2 to je klient VPS s interní adresou 192.168.30.3
MK3 to je klient VPS s interní adresou 192.168.30.4

Vrstva XNUMX VPN:
MS to je server s externí adresou 192.168.30.2 a vnitřní 192.168.31.1
MK2 to je klient MS s adresou 192.168.30.2 a má vnitřní IP 192.168.31.2
MK3 to je klient MS s adresou 192.168.30.2 a má vnitřní IP 192.168.31.3

* MS - router-server v bytě 1, MK2 - router v bytě 2, MK3 - router v bytě 3
* Konfigurace zařízení jsou zveřejněny ve spoileru na konci článku.

A tak, pingy mezi uzly sítě 192.168.31.0/24 probíhají, je čas přejít k nastavení GRE tunelu. Předtím, aby nedošlo ke ztrátě přístupu k routerům, se vyplatí nastavit SSH tunely pro předávání portu 22 na VPS, takže např. router z bytu 10022 bude dostupný na portu 2 VPS a router z bytu 11122 bude dostupný na portu 3 routeru VPS z bytu XNUMX. Nejlepší je nakonfigurovat přesměrování se stejným sshtunelem, protože v případě pádu tunel obnoví.

Tunel je nakonfigurován, můžete se připojit k SSH přes přesměrovaný port:

ssh root@МОЙ_VPS -p 10022

Dále vypněte OpenVPN:

/etc/init.d/openvpn stop

Nyní nastavíme GRE tunel na routeru z bytu 2:

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

A přidejte vytvořené rozhraní do mostu:

brctl addif br-lan grelan0

Provedeme podobný postup na routeru serveru:

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

A také přidejte vytvořené rozhraní do mostu:

brctl addif br-lan grelan0

od tohoto okamžiku začínají pingy úspěšně odcházet do nové sítě a já spokojeně jdu pít kávu. Poté, abych zjistil, jak funguje síť na druhém konci drátu, se pokusím připojit SSH do jednoho z počítačů v bytě 2, ale klient ssh zamrzne, aniž by mě požádal o heslo. Zkouším se připojit k tomuto počítači přes telnet na portu 22 a vidím řádek, ze kterého můžete pochopit, že se navazuje spojení, SSH server odpovídá, ale z nějakého důvodu mi nenabízí vstup.

$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1

Zkouším se k němu připojit přes VNC a vidím černou obrazovku. Přesvědčuji sám sebe, že věc je ve vzdáleném počítači, protože z tohoto bytu se mohu snadno připojit k routeru pomocí interní adresy. Rozhodnu se však pro SSH do tohoto počítače přes router a jsem překvapen, když zjišťuji, že připojení je úspěšné a vzdálený počítač funguje dobře, ale nepřipojuje se ani k mému počítači.

Vyndám zařízení grelan0 z mostu a spustím OpenVPN na routeru v bytě 2 a ujistím se, že síť opět funguje správně a připojení neklesají. Při hledání narážím na fóra, kde si lidé stěžují na stejné problémy, kde se doporučuje zvýšit MTU. Sotva řečeno, než uděláno. Dokud však nebylo MTU nastaveno na dostatečně velkou hodnotu 7000 pro zařízení gretap, bylo pozorováno buď přerušení TCP spojení nebo pomalé přenosy. Kvůli vysoké MTU pro gretap byly MTU pro WireGuard připojení první a druhé úrovně nastaveny na 8000 a 7500, v tomto pořadí.

Udělal jsem podobné nastavení na routeru z bytu 3, jen s tím rozdílem, že k routeru serveru bylo přidáno druhé rozhraní gretap s názvem grelan1, které bylo také přidáno do br-lan bridge.

Všechno funguje. Nyní můžete dát sestavu gretap do automatického načítání. Pro tohle:

Umístěte tyto řádky do /etc/rc.local na routeru v bytě 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

Toto bylo přidáno do /etc/rc.local na routeru v bytě 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

A na routeru serveru:

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

Po restartu klientských routerů jsem zjistil, že se z nějakého důvodu nepřipojily k serveru. Při připojení k jejich SSH (naštěstí jsem pro to předtím nakonfiguroval sshtunnel) bylo zjištěno, že WireGuard z nějakého důvodu vytváří trasu pro koncový bod, i když je nesprávná. Takže pro 192.168.30.2 byla směrovací tabulka specifikována ve směrovací tabulce přes rozhraní pppoe-wan, tedy přes internet, ačkoli cesta k ní měla směřovat přes rozhraní wg0. Po smazání této trasy bylo spojení obnoveno. Nikde jsem nenašel návod, jak donutit WireGuard, aby tyto trasy nevytvářel. Navíc jsem ani nepochopil, jestli je to funkce OpenWRT nebo samotného WireGuardu. Aniž bych se tímto problémem musel dlouho zabývat, jednoduše jsem do obou routerů ve skriptu zacykleném časovačem přidal řádek, který tuto trasu smazal:

route del 192.168.30.2

Shrnutí

Ještě jsem nedosáhl úplného odmítnutí OpenVPN, protože se někdy potřebuji připojit k nové síti z notebooku nebo telefonu a nastavit na nich zařízení gretap je obecně nemožné, ale přesto jsem získal výhodu v přenosu dat rychlost mezi byty a např. použití VNC již není nepohodlné. Ping se mírně snížil, ale stal se stabilnější:

Při použití 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

Při použití 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

Nejvíce je ovlivněno vysokým pingem na VPS, který je přibližně 61.5 ms

Rychlost se však výrazně zvýšila. Takže v bytě s routerem-serverem mám rychlost připojení k internetu 30 Mbps a v ostatních bytech 5 Mbps. Přitom při používání OpenVPN jsem nemohl dosáhnout rychlosti přenosu dat mezi sítěmi podle iperf větší než 3,8 Mbps, zatímco WireGuard to „napumpoval“ až na stejných 5 Mbps.

Konfigurace WireGuard na 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

Konfigurace WireGuard na MS (přidáno do /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'

Konfigurace WireGuard na MK2 (přidáno do /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'

Konfigurace WireGuard na MK3 (přidáno do /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'

V popsaných konfiguracích pro VPN druhé úrovně udávám klientům WireGuard port 51821. Teoreticky to není nutné, protože klient naváže spojení z libovolného volného neprivilegovaného portu, ale udělal jsem to tak, že všechna příchozí spojení lze zakázat na rozhraních wg0 všech směrovačů, kromě příchozích UDP připojení na portu 51821.

Doufám, že článek bude pro někoho užitečný.

PS Také chci sdílet svůj skript, který mi v aplikaci WirePusher posílá PUSH upozornění na můj telefon, když se v mé síti objeví nové zařízení. Zde je odkaz na skript: github.com/r0ck3r/device_discover.

AKTUALIZOVAT: Konfigurace OpenVPN serveru a klientů

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

Klient 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

Ke generování certifikátů jsem použil easy-rsa.

Zdroj: www.habr.com

Přidat komentář