Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní

Ahoj všem,

mám Raspberry PI s Linuxem a několika síťovými rozhraními (eth0, wlan0, wlan1). Jedno wifi rozhraní (wlan1) potřebuji izolovat tak, abych:

  • se s ním mohl připojit na jiné AP
  • mohl získat IP adresu z tamního dhcp serveru
  • mohl odeslat nějaké pakety na tamní síť (a pak se zase odpojit, je to jednorázová konfigurační operace)

Adresaci předem neznám a je reálné, že bude kolidovat s existující adresací ostatních síťových rozhraní (wlan1 typicky dostane 192.168.0.0/24 adresu která bude dost pravděpodobně kolidovat s existujícím připojením do lokální sítě na eth0 rozhraní). Jak toho nejelegantněji docílit? Zatím mě napadla virtualizace (kvm - na raspberry os zatím nefunguje, lxc - nezkoušel jsem a nejsem si jist, čeho všeho tam lze docílit). Existuje nějaké praktičtější kanonické řešení? Jde mi o řešení pro ipv4, síťová rozhraní jsou všechna typu ethernet a wifi.

Děkuji za podněty  :)
« Poslední změna: 08. 02. 2021, 16:56:10 od Petr Krčmář »


Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #1 kdy: 08. 02. 2021, 17:05:42 »
Na linuxu se dají používat pravidla (ip rule) pro výběr routovací tabulky. Pokud dokážete sestavit pravidla, která budou schopna rozlišit komunikaci pro to jedno rozhraní, můžete použít to. Nenapsal jste, čím bude ta komunikace na tom jednom rozhraní specifická – zda třeba dokážete určit zdrojovou IP adresu, proces apod.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #2 kdy: 08. 02. 2021, 18:16:20 »
Na linuxu se dají používat pravidla (ip rule) pro výběr routovací tabulky. Pokud dokážete sestavit pravidla, která budou schopna rozlišit komunikaci pro to jedno rozhraní, můžete použít to. Nenapsal jste, čím bude ta komunikace na tom jednom rozhraní specifická – zda třeba dokážete určit zdrojovou IP adresu, proces apod.

Bingo, to by mohlo být ono.

Pravidlo je možná takto: Vše co jde ze systému na cílovou adresu 192.168.0.0/16 a má cílový tcp port 9999 nebo je to icmp ping do tohoto rozsahu (+ možná ještě udp broadcast na 192.168.0.0/16), tak má jít přes wlan1, jinak dle výchozích rout případně na bránu.  K tomu bych tedy asi navíc potřeboval, aby dhcp klient nenastavoval výchozí bránu pro wlan1.  Při použití ip rule si musím pakety značkovat ve firewallu a tu značku pak použít v ip rule pravidlech nebo pravidla na port, proces atd. umí ip rule přímo?

Je ovšem otázka, zda se ta pravidla do budoucna nezkomplikují (a ony se určitě zkomplikují, jak se bude přidávat podpora pro další IOT zařízení). Pak by bylo možná lepší volit nějaký obecnější filtr. Pokud by se na danou komunikaci vyhradil například separátní proces, mohlo by se vše z toho procesu směřovat na wlan1 - což by se pak asi podobalo té mnou zmíněné virtualizaci, tj. proces by na tcp/ip úrovni komunikoval pouze a jen prostřednictvím wlan1. S procesem by se muselo nějak komunikovat, nejlépe mechanismem nezávislým na tcp/ip, takže třeba RMI over Unix Sockets - junixsocket (ty procesy jsou java)?

PS: V praxi jde o úkol zapojit IOT zařízení do zásuvky, připojit se na něj wlan1 wifinou (IOT funguje při prvním zapnutí jako AP) a nakonfigurovat ho pro připojení na wlan0 našeho systému, které je v AP režimu a kde běží dhcp server. Tím pádem se zařízení přepne do wifi client režimu a přeadresuje dle našeho dhcp. Dhcp je pod kontrolou a tím pádem bude pod kontrolou i zařízení a půjde ze systému přes tcp/ip dále ovládat. Těch zařízení tam bude samosebou více a tímto mechanismem si je postupně „přivlastním“.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #3 kdy: 08. 02. 2021, 18:27:32 »
V kombinaci s "ip rule" jsem svého času používal CONNMARK na příchozí relace. Když přijde paket zvenčí konkrétním rozhraním (první ve streamu/relaci), dostane konkrétní interní značku - a kernel zařídí, že tutéž interní značku budou mít pakety, které jdou "zpátky" a patří k téže komunikační relaci.

Jinak na virtualizaci/oddělení IP stacků by měl stačit Docker (chroot on steroids). Zdá se, že na RPi funguje. Jakákoli virtualizace znamená, že si v systému vyrobíte více "písečků", které na sebe navzájem přímo nevidí, a je to tak naschvál - ovšem je mi otázkou, zda je toto žádoucí / použitelné pro Váš use case.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #4 kdy: 09. 02. 2021, 09:29:15 »
pokial to ma byt jednorazovka, tak by som skor isiel cestou samostatne rpi, ktore by nerobilo nic ine, len periodicky hladalo tie ap,  a nastavovalo zariadenia.
Najlacnejsie rpi sa da zohnat za par eur a usetris si kopec casu nastavovanim a ladenim, najma, ked mozu kolidovat ip.


SB

  • ***
  • 193
    • Zobrazit profil
    • E-mail
Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #5 kdy: 09. 02. 2021, 10:07:26 »
Síťování moc nerozumím, takže zkusím:

Jestli to chápu, tak problémem je přidělení potenciálně kolidující adresy rozhraní wifi, jinak vše ostatní je řešitelné. Nedalo by se pomocí iptables nastavit dstnat v preroutingu a srcnat v postroutingu výhradně pro to jedno rozhraní wifi, čímž by bylo dosaženo vlastní, nekolizní adresy/podsítě?

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #6 kdy: 09. 02. 2021, 10:40:26 »
Při použití ip rule si musím pakety značkovat ve firewallu a tu značku pak použít v ip rule pravidlech nebo pravidla na port, proces atd. umí ip rule přímo?
Podívejte se na man ip-rule. Samo ip rule umí rozhodovat na základě IP adresy nebo rozhraní. A nebo pak může používat právě značky z firewallu.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #7 kdy: 09. 02. 2021, 16:06:08 »
Tohle je přímo ukázkový příklad pro network namespaces. Jednoduše příslušnou síťovou kartu přestěhuješ do samostatného namespace a v něm spustíš třeba shell, v něm třeba DHCP klienta, či cokoli jiného. Uvnitř daného namespace bude existovat jen tahle jedna síťová karta a prázdná směrovací tabulka. Všechno ostatní ale bude sdílené s hostitelským systémem, takže je snadné předávat si data třeba přes filesystém.

Kód: [Vybrat]
# ip netns add testovani
# ip link set eth0 netns testovani
# ip netns exec testovani bash

# ip netns delete testovani

Pokud je potřeba přesunout Wi-Fi kartu, je to trochu komplikovanější, je potřeba přesunou jí odpovídající phy rozhraní:

Kód: [Vybrat]
iw phy phy0 set ns name testovani

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #8 kdy: 09. 02. 2021, 20:05:12 »
Tohle je přímo ukázkový příklad pro network namespaces. Jednoduše příslušnou síťovou kartu přestěhuješ do samostatného namespace a v něm spustíš třeba shell, v něm třeba DHCP klienta, či cokoli jiného. Uvnitř daného namespace bude existovat jen tahle jedna síťová karta a prázdná směrovací tabulka. Všechno ostatní ale bude sdílené s hostitelským systémem, takže je snadné předávat si data třeba přes filesystém.

...

No vida, člověk se pořád učí, tohle vidím poprvé a nejspíš je to hotové řešení přesně mého problému  :D Ono totiž přepínat směrovací tabulky pomocí ip rule by vyžadovalo spravovat ta pravidla, kdežto namespace vypadá že bude stačit nastavit jednou pro vždy a je to přesně k tomuto účelu určené!

Teď se jen podívat jak je to integrované do systému v Raspberry OS. Používám na všechna síťová rozhraní jednu instanci dhcpcd a jednu instanci wpa_supplicant. Dále tam mám pdnsd a udhcpd, ale to jen na wlan0. Podle řečeného to vypadá, že budu muset spustit od dhcpcd i wpa_supplicant dvě instance, v jednom namespace bude eth0 + wlan0 a v druhém wlan1.

Ty namespace se budou muset vytvořit při startu. V každém namespace poběží jedna instance komunikačního software, všechno bude nakonec komunikovat přes mqtt takže by tak mohly komunikovat i obě instance komunikačního software (za předpokladu že najdu vhodnou implementaci podporující unix sockety, nebo přes unix sockety rmi).


Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #9 kdy: 10. 02. 2021, 00:19:50 »
všechno bude nakonec komunikovat přes mqtt takže by tak mohly komunikovat i obě instance komunikačního software (za předpokladu že najdu vhodnou implementaci podporující unix sockety, nebo přes unix sockety rmi).
Pro komunikaci mezi netns se používají veth rozhraní. Pomocí
Kód: [Vybrat]
ip link add veth1 type veth peer name veth2si vytvoříte pár rozhaní, který funguje tak, že paket, který se odešle přes jedno z nich, se objeví jako příchozí na druhém. Jedno rozhraní necháte v init netns a druhé přesunete do toho druhého.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #10 kdy: 10. 02. 2021, 08:02:19 »
Pro komunikaci mezi netns se používají veth rozhraní. Pomocí
Kód: [Vybrat]
ip link add veth1 type veth peer name veth2si vytvoříte pár rozhaní, který funguje tak, že paket, který se odešle přes jedno z nich, se objeví jako příchozí na druhém. Jedno rozhraní necháte v init netns a druhé přesunete do toho druhého.

A dvě instance MQTT brokera, každého v jednom namespace, a navzájem propojit nad veth linkem... až na to, že publisher/subscriber jsou klientské role, broker je jenom "prostředníkem" mezi nimi. Takže pokud nechceme vytvářet na koleně "dvojitého slava", je to řešitelné na bázi MQTT clusteringu dvou brokerů?

Neznám MQTT - váhám, jak se bude cluster na své úrovni adresace tvářit na klienty přišedší z překrývajících se subnetů (resp. jednotlivých /32 IP adres)... Pokud cluster interně řeší jenom "topics" a nesynchronizuje si tabulky IP adres živých klientů (= těm servíruje každý uzel sám za sebe), nemusel by nastat průser.

BTW o "namespaces" jsem slyšel, ale žil jsem v nesprávném domnění, že jde o "kernel API pro podporu dockeru", že to samostatně namazat na chleba nelze. Vida, člověk se pořád učí :-) Děkuji.

Hm tak mě napadá, jaká je souvislost mezi namespaces a VRF... Aha.

SB

  • ***
  • 193
    • Zobrazit profil
    • E-mail
Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #11 kdy: 10. 02. 2021, 10:32:50 »
Nechci vás rušit ve vašem klábosení, ale na můj vkus je to už docela složité, takže jsem byl zvědavý, zda je mnou výše navržené řešení s NAT (či masquerade) proveditelné.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #12 kdy: 10. 02. 2021, 10:38:41 »
Hm tak mě napadá, jaká je souvislost mezi namespaces a VRF... Aha.
VRF je v Linuxu taky, ale nepřišel jsem na žádné smysluplné využití, pokud tedy zrovna nepůjde o linuxový router/switch. Hlavní rozdíl je v tom, že VRF odděluje síťové karty jen od třetí vrstvy výš, takže třeba takový démon pro LLDP může běžet jen jeden a obsluhovat všechna rozhraní, přestože jsou součástí jiných virtuálních routerů.

Z pohledu konfigurace je to ale proti namespaces hrozný guláš.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #13 kdy: 10. 02. 2021, 10:45:00 »
Teď se jen podívat jak je to integrované do systému v Raspberry OS. Používám na všechna síťová rozhraní jednu instanci dhcpcd a jednu instanci wpa_supplicant. Dále tam mám pdnsd a udhcpd, ale to jen na wlan0. Podle řečeného to vypadá, že budu muset spustit od dhcpcd i wpa_supplicant dvě instance, v jednom namespace bude eth0 + wlan0 a v druhém wlan1.
Ano, vypadá to tak, tohle může být případně kámen úrazu, pokud některé aplikace nepočítají s tím, že by běžely na jednom systému ve více instancích a budou si přepisovat stavové soubory.

Stejně tak je problém s DNS resolvingem, kde soubor /etc/resolv.conf je jen jeden, takže se klidně může stát, že v jednom z namespaces nebude DNS fungovat. Řešit se to samozřejmě dá třeba použitím mount namespace, ale tím se začne situace trochu komplikovat a postupně se dostáváme spíše k plnohodnotnému kontejneru.

Re:Jak oddělit a nezávisle adresovat jedno Wi-Fi rozhraní
« Odpověď #14 kdy: 10. 02. 2021, 11:05:26 »
Na zaklade odpovedi od p. Caletky jsem si zkusil vyhledat pouziti pro haproxy, nebot tam potrebuji kvuli mpls pristupu VRF (resim to tedy via ip rule atd...)

https://cloudnull.io/2019/04/running-services-in-network-name-spaces-with-systemd/

Podle tohoto clanku je to teda dost narocnejsi nez pouhych par radku v systemd-networkd konfiguracich...