Přechod z OpenVPN na WireGuard pro sloučení sítí do jedné sítě L2

Přechod z OpenVPN na WireGuard pro sloučení sítí do jedné sítě L2

Rád bych se podělil o zkušenosti se sloučením sítí ve třech geograficky vzdálených bytech, v každém z nichž jsou jako brány použity routery s OpenWRT, do jedné společné sítě. Při výběru metody spojující sítě mezi L3 s routováním podsítí a L2 s bridgovaním, kdy budou všechny uzly sítě v jedné podsíti, byla upřednostněna druhá, složitější metodika, která nabízí větší možnosti, neboť v nové síti se plánovalo bezproblémové využívání technologií Wake-on-Lan a DLNA.

Část 1: Pozadí

Jako protokol pro realizaci tohoto úkolu byl původně vybrán OpenVPN, protože, za prvé, může vytvářet zařízení tap, které je bez problémů přidatelné do mostu, a za druhé, OpenVPN podporuje práci přes protokol TCP, což bylo rovněž velmi důležité, protože v žádném z bytů nebyla k dispozici veřejná IP adresa, a použít STUN se mi nepodařilo, protože můj poskytovatel z nějakého důvodu blokuje příchozí připojení přes protokol UDP z jeho sítí, zatímco protokol TCP mi umožnil přesměrovat port VPN serveru na pronajatý VPS pomocí SSH. Ano, tento přístup znamená větší zátěž, protože jsou data šifrována dvakrát, ale nechtěl jsem zapojit VPS do své soukromé sítě, protože existovalo riziko, že třetí strany získají kontrolu nad ním, a tudíž mít takové zařízení v domácí síti bylo krajně ne žádoucí, a bylo rozhodnuto zaplatit za bezpečnost zvýšenou zátěží.

Pro přesměrování portu na routeru, na kterém se plánovalo nasazení serveru, byl použit program sshtunnel. Nebudu popisovat detaily jeho konfigurace — to se dělá dost snadno, jen poznamenám, že jeho úkolem bylo přesměrování TCP portu 1194 z routeru na VPS. Dále byl nastaven server OpenVPN na zařízení tap0, které bylo vloženo do mostu br-lan. Po ověření připojení k právě vytvořenému serveru z notebooku — bylo jasné, že myšlenka s přesměrováním portu se osvědčila a můj notebook se stal členem sítě routeru, ačkoliv fyzicky v ní nebyl.

Teď šlo o to, rozdělit IP adresy v různých bytech tak, aby se navzájem nekolidovaly, a nastavit routery jako OpenVPN klienty.
Byly vybrány tyto IP adresy routerů a rozsahy DHCP serverů:

  • 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 právě tyto adresy pro klientské routery OpenVPN serveru přidáním následujícího řá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í uváděné při vytváření certifikátů pro připojení k OpenVPN

Dále byly na routerech nakonfigurovány klienti OpenVPN, zařízení tap0 na obou byla zahrnuta do mostu br-lan. V této fázi se zdálo, že je vše v pořádku, protože všechny tři sítě se navzájem vidí a fungují jako celek. Avšak se ukázal nepříjemný detail: někdy zařízení mohla získat IP adresu ne od svého routeru, s veškerými důsledky. Z nějakého důvodu router v některém z bytů nestíhal včas odpovědět na DHCPDISCOVER a zařízení dostávalo nesprávnou adresu. Uvědomil jsem si, že musím filtrovat takové požadavky v tap0 na každém z routerů, ale jak se ukázalo, iptables nemůže pracovat s zařízením, pokud je součástí mostu, a tak mi musel pomoci ebtables. K mému zklamání, v mých firmwarech nebyl a musel jsem přestavět obrazy pro každé zařízení. Po tom jsem přidal tyto řádky do /etc/rc.local každého routeru a problém byl 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 po dobu tří let.

Část 2: Seznámení s WireGuard

V poslední době se na internetu čím dál více mluví o WireGuard, chválí se jeho jednoduchost konfigurace, vysoká rychlost přenosu a nízký ping při srovnatelné bezpečnosti. Hledání dalších informací o něm ukázalo, že ani práce v režimu mostu, ani práce podle protokolu TCP nejsou podporovány, což mě přivádělo k myšlenkám, že alternativy k OpenVPN pro mě stále neexistují. Tak jsem odkládal seznámení s WireGuard.

Před několika dny se v IT médiích objevila zpráva, že WireGuard bude konečně začleněn do jádra Linuxu, počínaje verzí 5.6. Novinové články jako vždy vychvalovaly WireGuard. Opět jsem se ponořil do hledání způsobu, jak nahradit starý dobrý OpenVPN. Tentokrát jsem narazil na tento článek. V něm se hovořilo o vytvoření Ethernetového tunelu nad L3 pomocí GRE. Tento článek ve mně vzbudil naději. Zůstávalo nejasné, co dělat s protokolem UDP. Hledání mě přivedlo k článkům o použití socat v kombinaci se SSH tunelováním pro přeposílání UDP portu, avšak v nich se uvádělo, že tento přístup funguje pouze v režimu jedné relace, což by znemožnilo současnou práci několika VPN klientů. Napadlo mě vybudovat VPN server na VPS a pro klienty nastavit GRE, ale jak se ukázalo, GRE nepodporuje šifrování, což by vedlo k tomu, že v případě přístupu třetích osob k serveru by měli k dispozici veškerý provoz mezi mými sítěmi, což mi v zásadě nevyhovovalo.

Opět padlo rozhodnutí ve prospěch nadbytečného šifrování, pomocí VPN nad VPN podle následujícího schématu:

VPN první úrovně:
VPS je serverem s interní adresou 192.168.30.1
MC je klientem VPS s interní adresou 192.168.30.2
MK2 je klientem VPS s interní adresou 192.168.30.3
MK3 je klientem VPS s interní adresou 192.168.30.4

VPN druhé úrovně:
MC je serverem s externí adresou 192.168.30.2 a interní 192.168.31.1
MK2 je klientem MC s adresou 192.168.30.2 a má interní IP 192.168.31.2
MK3 je klientem MC s adresou 192.168.30.2 a má interní IP 192.168.31.3

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

A takže, pingi mezi uzly sítě 192.168.31.0/24 fungují, je čas přejít na konfiguraci GRE tunelu. Než tak učiníme, abychom neztratili přístup k směrovačům, je dobré nastavit SSH tunely pro přeposílání portu 22 na VPS, tak, že například na portu 10022 bude VPS přístupný směrovač z bytu 2, a na portu 11122 bude VPS přístupný směrovač z bytu 3. Konfiguraci přeposílání je nejlepší provést pomocí sshtunnel, protože obnoví tunel v případě jeho výpadku.

Tunel je nastaven, můžeme se připojit k SSH přes přeposílaný port:

ssh root@MŮJ_VPS -p 10022

Nyní odpojte OpenVPN:

/etc/init.d/openvpn stop

Nyní nastavíme GRE tunel na směrovači 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řidáme vytvořené rozhraní do mostu:

brctl addif br-lan grelan0

Podobný postup provedeme na serverovém routeru:

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

A také přidáme vytvořené rozhraní do mostu:

brctl addif br-lan grelan0

Od tohoto momentu začínají pingy úspěšně chodit do nové sítě a já se spokojeně vydávám na kávu. Poté, co vyhodnotím, jak funguje síť na druhém konci drátu, se pokouším připojit přes SSH k jednomu z počítačů v bytě 2, ale SSH klient „zasekne“, aniž by mi nabídl zadat heslo. Zkouším se k tomuto počítači připojit přes telnet na port 22 a vidím řádek, ze kterého lze pochopit, že se vytváří 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

Pokouším se připojit i přes VNC a vidím černou obrazovku. Ujišťuji se, že problém je na vzdáleném počítači, neboť se k routeru z tohoto bytu mohu pohodlně připojit přes interní adresu. Rozhoduji se však připojit přes SSH na tento počítač přes router a s překvapením zjišťuji, že připojení se zdařilo, a vzdálený počítač funguje naprosto normálně, avšak zároveň se také nemůže připojit k mému počítači.

Vytahuji zařízení grelan0 z mostu a spouštím OpenVPN na routeru v bytě 2 a ujistím se, že síť znovu funguje, jak má, a spojení se přerušují. Při hledání narazím na fóra, kde lidé si stěžují na stejné problémy, kde jim radí zvýšit MTU. Řečeno — učiněno. Nicméně, dokud MTU nebylo nastaveno dostatečně velké — 7000 pro zařízení gretap, objevovaly se buď přerušení TCP spojení, nebo nízká rychlost přenosu. Kvůli vysokému MTU pro gretap — MTU pro připojení WireGuard prvního a druhého stupně byly nastaveny na 8000 a 7500 včetně.

Provedl jsem podobné nastavení také na routeru v bytě 3, s jedním rozdílem, že na serverovém routeru byl přidán druhý rozhraní gretap s názvem grelan1, které bylo také přidáno do mostu br-lan.

Všechno funguje. Teď můžeme umístit sestavení gretap do automatického spouštění. K tomu:

Umístil jsem 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

Přidal jsem to do /etc/rc.local na routeru ve třetím patře:

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 restartování klientských routerů jsem zjistil, že se z nějakého důvodu nepřipojují k serveru. Když jsem se připojil k jejich SSH (naštěstí jsem to předem nastavil pomocí sshtunnel), zjistil jsem, že WireGuard nějak vytváří trasu pro endpoint, a to nesprávně. Takže pro 192.168.30.2 byla v tabulce trasování uvedena trasa přes rozhraní pppoe-wan, tedy přes internet, i když trasa k němu měla být nasměrována přes rozhraní wg0. Po odstranění této trasy se připojení obnovilo. Nepodařilo se mi najít nějaké instrukce o tom, jak přimět WireGuard, aby tyto trasy nevytvářel. Navíc jsem ani nepochopil, zda je to zvláštnost OpenWRT, nebo WireGuard. Neměl jsem moc času zabývat se touto problematikou, takže jsem jednoduše přidal do skriptu na obou routerech cyklickou řádku, která tuto trasu odstraňovala:

route del 192.168.30.2

Shrnutí

Zatím jsem se úplného opuštění OpenVPN nedočkal, protože se občas potřebuji připojit k nové síti z notebooku nebo telefonu a nastavení gretap zařízení na nich je obecně nemožné, ale i přesto jsem ziskal zvýšení rychlosti přenosu dat mezi byty a například používání VNC nyní nezpůsobuje žádné potíže. Ping se mírně snížil, ale stal se stabilnějším:

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

Na to v větší míře ovlivňuje vysoký ping do VPS, který činí přibližně 61,5 ms

Nicméně, rychlost se výrazně zvýšila. Tak, v bytě s routerem-serverem mám rychlost připojení k internetu 30 Mbit/s, zatímco v ostatních bytech po 5 Mbit/s. Přitom, při používání OpenVPN se mi nepodařilo dosáhnout rychlosti přenosu dat mezi sítěmi větší než 3,8 Mbit/s podle měření iperf, zatímco WireGuard ji „dovedl“ na stejných 5 Mbit/s.

Konfigurace WireGuard na VPS[Interface]
Adresa = 192.168.30.1/24
PoslouchacíPort = 51820
SoukromýKlíč =

[Peer]
PublicKey =
AllowedIPs = 192.168.30.2/32

[Peer]
PublicKey =
AllowedIPs = 192.168.30.3/32

[Peer]
PublicKey =
AllowedIPs = 192.168.30.4/32

Konfigurace WireGuard na MS (přidává se 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ává se 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ává se 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ě uvádím klientům WireGuard port 51821. Teoreticky to není nutné, protože klient se připojí z libovolného volného neprivilegovaného portu, ale udělal jsem to tak, aby bylo možné zakázat všechna příchozí připojení na rozhraních wg0 všech routerů, kromě příchozích UDP připojení na port 51821.

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

P.S. Také bych se chtěl podělit o svůj skript, který mi posílá PUSH oznámení na telefon do aplikace WirePusher, když se v mé síti objeví nové zařízení. Zde je odkaz na skript: github.com/r0ck3r/device_discover.

AKTUALIZACE: Konfigurace OpenVPN serveru a klientů

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 # Změňte na externí IP vašeho routeru
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

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

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster