
Chcel by som sa podeliť o skúsenosti s prepojením sietí v troch geograficky vzdialených bytoch, kde sa ako brána používajú smerovače s OpenWRT, do jednej spoločnej siete. Pri výbere spôsobu prepojenia sietí medzi L3 s smerovaním podsietí a L2 s bridgingom, keď všetky uzly siete budú v jednej podsieti, bola uprednostnená druhá metóda, ktorá je zložitejšia na nastavenie, ale ponúka väčšie možnosti, pretože v plánovanej sieti sa zamýšľalo o transparentnom používaní technológií Wake-on-Lan a DLNA.
Časť 1: Predhistória
Ako protokol na realizáciu tejto úlohy bol pôvodne zvolený OpenVPN, pretože, po prvé, dokáže vytvárať zariadenie tap, ktoré je bez problémov pridané do mosta, a po druhé, OpenVPN podporuje prácu podľa protokolu TCP, čo bolo tiež dôležité, pretože v žiadnom z bytov nebola k dispozícii vyhradená IP adresa, a použiť STUN sa mi nepodarilo, pretože môj poskytovateľ z nejakého dôvodu blokuje prichádzajúce pripojenia podľa protokolu UDP zo svojich sietí, pričom protokol TCP mi umožnil presmerovať port VPN servera na prenajímaný VPS pomocou SSH. Áno, taký prístup spôsobuje väčšiu záťaž, pretože údaje sa šifrujú dvakrát, ale nechcel som zahrnúť VPS do svojej súkromnej siete, pretože existovalo riziko, že nad ním získajú kontrolu tretie strany, a teda mať také zariadenie v domácej sieti bolo extrémne nežiaduce, a rozhodlo sa zaplatiť za bezpečnosť väčším overheadom.
Na presmerovanie portu na smerovači, na ktorom sa plánovalo rozbehnúť server, bola použitá aplikácia sshtunnel. Nechcem sa zaoberať detailmi jej konfigurácie — to sa robí pomerne jednoducho, len dodám, že jej úlohou bolo presmerovanie TCP portu 1194 zo smerovača na VPS. Následne bol nastavený server OpenVPN na zariadení tap0, ktoré bolo zahrnuté do mosta br-lan. Po overení pripojenia k práve vytvorenému serveru z notebooku — bolo jasné, že nápad s presmerovaním portu bol oprávnený a môj notebook sa stal členom siete smerovača, hoci fyzicky v nej nebol.
Ostávalo už len málo: bolo potrebné rozdistribuovať IP adresy v rôznych bytoch tak, aby sa nekolidovali, a nastaviť smerovače ako OpenVPN klientov.
Boli zvolené také IP adresy smerovačov a rozsahy DHCP serverov:
- 192.168.10.1 s rozsahom 192.168.10.2 — 192.168.10.80 pre server
- 192.168.10.100 s rozsahom 192.168.10.101 — 192.168.10.149 pre router in apartment №2
- 192.168.10.150 s rozsahom 192.168.10.151 — 192.168.10.199 pre router in apartment №3
It was also necessary to assign these addresses specifically for the OpenVPN server client routers by adding the following line to its configuration:
ifconfig-pool-persist /etc/openvpn/ipp.txt 0and adding the following lines to the file /etc/openvpn/ipp.txt:
flat1_id 192.168.10.100
flat2_id 192.168.10.150
where flat1_id and flat2_id are the names of the devices specified when creating certificates for connecting to OpenVPN
Next, OpenVPN clients were configured on the routers, with tap0 devices being added to the br-lan bridge on both of them. At this stage, it seemed that everything was fine since all three networks could see each other and functioned as a single entity. However, an unpleasant detail emerged: sometimes devices could receive an IP address not from their own router, with all the ensuing consequences. For some reason, the router in one of the apartments was not responding in time to DHCPDISCOVER, and the device received an incorrect address. I realized I needed to filter such requests in tap0 on each of the routers, but, as it turned out, iptables cannot work with a device if it is part of a bridge, and I would need ebtables to assist. Unfortunately, it was not present in my firmware, so I had to rebuild the images for each device. After doing this and adding these lines to /etc/rc.local of each router, the problem was solved:
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
This configuration lasted for three years.
Part 2: Getting to Know WireGuard
Recently, there has been increasing talk about WireGuard on the Internet, praising its ease of configuration, high transmission speed, and low ping while maintaining comparable security. Searching for additional information made it clear that neither functioning as a bridge member nor operating over TCP is supported, which led me to believe that there are still no alternatives to OpenVPN for me. Thus, I kept postponing an acquaintance with WireGuard.
Pred niekoľkými dňami sa v IT zdrojoch objavila správa, že WireGuard konečne bude zahrnutý v jadre Linuxu, počnúc verziou 5.6. Novinové články, ako vždy, chválili WireGuard. Znovu som sa ponoril do hľadania spôsobov, ako nahradiť starý dobrý OpenVPN. Tentoraz som narazil na . V nej sa hovorilo o vytvorení Ethernet tunela nad L3 pomocou GRE. Tento článok vo mne vzbudil nádej. Ostávalo nejasné, čo robiť s protokolom UDP. Hľadanie ma priviedlo k článkom o použití socat v kombinácii so SSH tunelom na presmerovanie UDP portu, avšak bolo v nich uvedené, že takýto prístup funguje iba v režime jedného pripojenia, to znamená, že fungovanie viacerých VPN klientov by bolo nemožné. Napadlo mi vytvoriť VPN server na VPS a pre klientov nastaviť GRE, ale ako sa ukázalo, GRE nepodporuje šifrovanie, čo by viedlo k tomu, že v prípade prístupu k serveru tretími stranami by sa dostali do rúk celý prenos medzi mojimi sieťami, čo ma v zásade neuspokojovalo.
Znovu bolo rozhodnuté v prospech nadbytočného šifrovania, prostredníctvom použitia VPN nad VPN podľa nasledujúcej schémy:
VPN prvej úrovne:
VPS je serverom s internou adresou 192.168.30.1
MS je klientom VPS s internou adresou 192.168.30.2
MK2 je klientom VPS s internou adresou 192.168.30.3
MK3 je klientom VPS s internou adresou 192.168.30.4
VPN druhej úrovne:
MS je serverom s vonkajšou adresou 192.168.30.2 a internou 192.168.31.1
MK2 je klientom MS s adresou 192.168.30.2 a má interný IP 192.168.31.2
MK3 je klientom MS s adresou 192.168.30.2 a má interný IP 192.168.31.3
* MS — router-server v byte 1, MK2 — router v byte 2, MK3 — router v byte 3
* Konfigurácie zariadení sú zverejnené v spoliere na konci článku.
Takže, pingi medzi uzlami siete 192.168.31.0/24 prechádzajú, je čas prejsť k nastaveniu GRE tunela. Predtým, aby som neztratil prístup k routerom, stojí za to nastaviť SSH tunely na presmerovanie portu 22 na VPS, tak, že napríklad na porte 10022 bude VPS prístupný router z bytu 2, a na porte 11122 bude VPS prístupný router z bytu 3. Najlepšie je vykonať nastavenie presmerovania pomocou sshtunnel, pretože obnoví tunel v prípade jeho pádu.
Tunel je nastavený, môžete sa pripojiť k SSH cez presmerovaný port:
ssh root@MOJ_VPS -p 10022Potom je potrebné vypnúť OpenVPN:
/etc/init.d/openvpn stopTeraz nastavíme GRE tunel na routeri 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 pridáme vytvorený rozhraní do mosta:
brctl addif br-lan grelan0
Podobný postup vykonáme na smerovači-serveri:
ip link add grelan0 type gretap remote 192.168.31.2 local 192.168.31.1
ip link set grelan0 up
A taktiež pridáme vytvorený rozhraní do mosta:
brctl addif br-lan grelan0
Od tohoto okamihu začnú pingi úspešne chodiť do novej siete a ja s radosťou odchádzam na kávu. Potom, aby som ohodnotil, ako funguje sieť na druhom konci kábla, pokúšam sa pripojiť cez SSH k jednému z počítačov v byte 2, ale ssh-klient 'zamrzne', nenabízajúc možnosť zadať heslo. Skúšam sa pripojiť k tomuto počítaču cez telnet na porte 22 a vidím riadok, z ktorého môžem pochopiť, že spojenie sa nadväzuje, SSH-server odpovedá, ale z nejakého dôvodu mi nenabízajú prihlásenie.
$ telnet 192.168.10.110 22
SSH-2.0-OpenSSH_8.1
Pokúšam sa pripojiť k nemu aj cez VNC a vidím čiernu obrazovku. Uisťujem sa, že problém je na vzdialenom počítači, pretože k smerovaču z tohto bytu sa môžem bez problémov pripojiť cez internú adresu. Napriek tomu sa rozhodujem pripojiť k SSH tohto počítača cez smerovač a s prekvapením zistím, že pripojenie je úspešné a vzdialený počítač funguje celkom normálne, ale zároveň sa nemôže pripojiť k môjmu počítaču.
Odpojujem zariadenie grelan0 z mosta a spúšťam OpenVPN na smerovači v byte 2 a uisťujem sa, že sieť opäť funguje tak, ako má a spojenia sa neprerušujú. Na internete natrafím na fóra, kde sa sťažujú na rovnaké problémy, kde im radia zvýšiť MTU. Povedané — urobili sme. Avšak, kým MTU nebolo nastavené dosť veľké — 7000 pre zariadenia gretap, pozorovali sa buď prerušenia TCP spojení, alebo nízka prenosová rýchlosť. V dôsledku vysokého MTU pre gretap — MTU pre spojenia WireGuard prvého a druhého stupňa boli nastavené na 8000 a 7500 resp.
Podobnú konfiguráciu som vykonal aj na smerovači v byte 3, s tou len rozdielom, že na smerovači-serveri bol pridaný druhý rozhraní gretap s názvom grelan1, ktorý bol taktiež pridaný do mosta br-lan.
Všetko funguje. Teraz môžeme dať zbernicu gretap do automatického štartu. Na to:
Umiesnil som tieto riadky do /etc/rc.local na smerovači v byte 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
Pridal som to do /etc/rc.local na smerovači v byte 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 smerovači-serveri:
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 reštarte klientských smerovačov som zistil, že sa z nejakého dôvodu nepripojujú k serveru. Po pripojení cez SSH (našťastie som si na to predtým nastavil sshtunnel) sa zistilo, že WireGuard bezdôvodne vytvára trasu pre endpoint, navyše chybnú. Takže pre 192.168.30.2 bola v tabuľke trás uvedená trasa cez rozhranie pppoe-wan, teda cez internet, hoci trasa k nemu mala byť smerovaná cez rozhranie wg0. Po odstránení tejto trasy sa pripojenie obnovilo. Nepodarilo sa mi nájsť inštrukcie, ako prinútiť WireGuard nevytvárať tieto trasy. Navyše, ani som nepochopil, či je to vlastnosť OpenWRT alebo samotného WireGuard. Aby som sa dlhšie netrápil s touto otázkou, jednoducho som pridal na oba smerovače do skriptu s cyklickým časovačom riadok, ktorý odstraňuje túto trasu:
route del 192.168.30.2
Zhrnutie
Úplného zrieknutia sa OpenVPN som zatiaľ nedosiahol, pretože sa občas potrebujem pripojiť k novej sieti z laptopu alebo mobilu, pričom nastavenie gretap zariadenia na nich je vo všeobecnosti nemožné. Napriek tomu som získal výhodu v rýchlosti prenosu dát medzi bytmi a používanie VNC teraz nespôsobuje žiadne nepríjemnosti. Ping sa znížil mierne, ale stal sa stabilnejším:
Pri používaní 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
Pri používaní 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 neho má väčší vplyv vysoký ping do VPS, ktorý je približne 61.5 ms
Avšak rýchlosť sa výrazne zvýšila. Takže v byte s routerom-serverom mám rýchlosť pripojenia na Internet 30 Mbit/s, zatiaľ čo v ostatných bytoch po 5 Mbit/s. Pri tom, počas používania OpenVPN som nedokázal dosiahnuť rýchlosť prenosu dát medzi sieťami vyššiu ako 3,8 Mbit/s podľa údajov iperf, zatiaľ čo WireGuard ju „vytiahol“ až na rovnakých 5 Mbit/s.
Konfigurácia WireGuard na VPS[Interface]
Adresa = 192.168.30.1/24
PortPočúvania = 51820
SúkromnýKľúč =
[Peer]
PublicKey =
AllowedIPs = 192.168.30.2/32
[Peer]
PublicKey =
AllowedIPs = 192.168.30.3/32
[Peer]
PublicKey =
AllowedIPs = 192.168.30.4/32
Konfigurácia WireGuard na MS (pridáva sa 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'
Konfigurácia WireGuard na MK2 (pridáva sa 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'
Konfigurácia WireGuard na MK3 (pridáva sa 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 opísaných konfiguráciách pre VPN druhej úrovne uvádzam klientom WireGuard port 51821. Teoreticky to nie je potrebné, pretože klient sa pripojí z ktoréhokoľvek voľného neprivilegovaného portu, ale urobil som to tak, aby som mohol zakázať všetky prichádzajúce pripojenia na rozhraniach wg0 všetkých routerov, okrem prichádzajúcich UDP pripojení na port 51821.
Dúfam, že článok bude niekomu užitočný.
P.S. Takisto sa chcem podeliť o svoj skript, ktorý mi posiela PUSH-notifikáciu na telefón do aplikácie WirePusher, keď sa v mojej sieti objaví nové zariadenie. Tu je odkaz na skript: .
AKTUALIZÁCIA: Konfigurácia OpenVPN-servera a klientov
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-lzoOpenVPN-klient
client
tls-client
dev tap
proto tcp
remote VPS_IP 1194 # Zmeňte na externú IP vášho routera
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 Na generovanie certifikátov som použil easy-rsa.
Zdroj: habr.com
