Temat: Bug w AR724X/AR933X
Dawno temu miałem problem z bridgowaniem 2 vlanów: https://eko.one.pl/forum/viewtopic.php?id=19288 . Problemu nie rozwiązałem, ustawiłem nietagowane vlany i podmieniłem po prostu switcha na tp-linka. Niestety, dziś na moim Archerze d7 na Owrt musiałem ustawić coś bardzo podobnego, bridgowanie dwóch vlanowych sieci na tym samym switchu (gościnna i bezpieczna), co dało dokładnie takie same rezultaty jak na WR740: przez bridge przechodzą tylko ramki z dest mac broadcast. Jako, że w tym przypadku nie mogłem sobie pozwolić na zwykły nietagowany vlan (potrzebna mi była funkcjonalność ebtables) postanowiłem trochę problem pokopać i udało mi się dojść do jego źródła: wadliwa implementacja tablic arl w switchach atherosu.
Od początku:
Wyobraźmy sobie bardzo hipotetyczny router z 1 ifejsem sieciowym eth0 i jednym 3-portowym (do dyspozycji mamy 2) switechm switch0 z obsługą 802.11q podłączonym pod eth0. Chcemy, aby porty 1 i 2 działały w ramach L2, proste: nie robimy nic albo ustawiamy jeden globalny vlan. Natomiast teraz trochę komplikujemy: nadal chcemy switch L2, ale pomiędzy portami ma nie przechodzić jakiś dany adres mac. Teraz trzeba ustawić 2 różne vlany i je zbridgować na L2, jednocześnie ustawiając odpowiednią zasadę w ebtables. Też porste, prawda? No, jak się okazuje, nie do końca. Teraz z jakiegoś powodu pomiędzy sieciami nie przechodzi unicast. Ok, zepsuliśmy firewall, czyścimy tablicę z ebtables... nadal nic. Na wszelki wypadek czyścimy iptables... też nic. Czyli nie firewall.
Dla testów ustawiamy następującą sieć:
192.168.1.10 (eth10) <----Port 1 (eth0.10)----> router <----Port 2 (eth0.20)----> (eth20) 192.168.1.20
Dla łatwości uznajemy, że router ten nie bierze udziału w tej sieci, tj. albo kontrolujemy go z innej (wyimaginowanej w tej sytuacji), albo przez uart, na br0 nie ma żadnego adresu (unmanaged). Odpalamy sniffery na interfejsach: eth10, eth0.10, eth0, eth0.20, eth20 i otrzymujemy następujące rezultaty:
1. Przy zapytaniu arp o adres 192.168.1.20 z adresu 192.168.1.10 (zapytanie bcast, odpowiedź ucast):
eth10: zapytanie brak odpowiedzi | x
SWITCH | x(?)
eth0: tagowane zapytanie tagowana odpowiedź v ^
eth0.10: zapytanie odpowiedź | | Droga pakietów
br0 | |
eth0.20: zapytanie odpowiedź v ^
eth0: tagowane zapytanie tagowana odpowiedź | |
SWITCH | |
eth20: zapytanie odpowiedź ->----->-
Foto, gdyby się wszystko rozjechało:
Zauważmy, że pomiędzy eth0, eth0.10 i eth0.20 odpowiedzi są przekazywane prawidłowo, czyli problemów w softwarowym bridgu nie ma. Z resztą, jak zauważył @Cezary, gdyby były, to:
[...]żaden router z openwrt by nie działał gdzie domyślnie robiony jest bridge z lanu i wifi.
Coś jest nie tak pomiędzy wysłaniem tagowanej ramki z eth0 (eth0.20) do eth20. Chyba nietrudno zauważyć, że jedyną rzeczą pomiędzy eth0 a eth20 jest SWITCH.
Dla pewności zprawdzamy config vlanów switcha switch0: swconfig dev switch0 show i przypadkiem zauważamy anomailę w sekcji arl_table:
Port 0: MAC (mac eth0)
Port 0: MAC (mac eth20)
Port 0: MAC (mac eth10)
Na pierwszy rzut oka powinno być:
Port 0: MAC (mac eth0)
Port 2: MAC (mac eth20)
Port 1: MAC (mac eth10)
Po chwili zastanowienia dochodzimy jednak do wniosku, że obecność macu eth20 na porcie 0 jest porządana i logiczna, gdyż router bridgując vlany 10 i 20 (interfejsy eth0.10 i eth0.20) bazując na swojej softwarowej tablicy arl, którą można podpatrzeć w brforward, otrzymawszy pakiet na 10 wysyła go na 20 i odwrotnie, spowrotem do switcha z takimi samymi adresami mac. Switch z kolei, widząc przychodzący tagowany pakiet z adresem eth10/eth20 na porcie 0 (tam, gdzie jest eth0), uznaje, że rzeczywiście jest on na porcie 0 i tak to ma działać, w przeciwnym wypadku switch nie wiedziałby gdzie przekierować odpowiedź. A więc poprawna tablica:
Port 0: MAC (mac eth0)
Port 0: MAC (mac eth20)
Port 0: MAC (mac eth10)
Port 2: MAC (mac eth20)
Port 1: MAC (mac eth10)
Dlaczego więc arl_table tak nie wygląda? Moja teoria była taka, że z jakiegoś powodu arl nawet przy 2 oddzielnych vlanach jest nadal wspólny dla całego switcha, tj. nie ma oddzielnego arl dla vlanu 10 i 20. Byłoby to wyjaśnieniem dziwnego wyglądu arl: zastanówmy się co by było, gdyby switch miał wyłączoną obsługę vlan. Gdyby switch dostał 2 takie same pakiety z 2 takimi samymi adresami src na 2 różnych portach, to by zgłupiał: coś takiego w topologii ethernet nie powinno mieć miejsca. Jedynym *sensownym* wytłumaczeniem takiego zjawiska jest przepięcie komputera z jednego portu do drugiego. Z tego powodu, biorąc pod uwagę kolejność występowania naszych przesyłanych pakietów, lądują one w porcie 0 i nie są przekazywane do portów 1 i 2, bo switch uznał, że komputer został przepięty właśnie na port routera, gdy router z kolei po prosu wysyła forwardowany pakiet. Stąd brak komunikacji unicast. Broadcast nie potrzebuje mapowania, więc nie ma go w arl, bo wysyłany jest wszędzie.
Przy braku izolacji tablicy arl rodzi się więc zagrożenie. Co jeżeli (jak ja) mamy na takim niedopracowanym switchu sieć gościnną i własną? Po krótkim namyśle uznałem, że zgodnie z działaniem takiego switcha można spróbować przeprowadzić atak DoS z sieci gościnnej na własną i odwrotnie, aby sprawdzić, czy problemem jest właśnie to, o czym już tak bardzo się rozpisałem. Kluczem w takim wypadku jest tak częstę spamowanie switcha, aby co najmniej jeden pakiet z zespoofowanym adresem src ofiary od atakującego (nas) docierał do switcha POMIĘDZY wysłaniem przez switch pakietu od ofiary adresowanego gdzieś a otrzymaniem odpowiedzi przez switch z kądś adresowanego do ofiary (w przypadku naszego bridga wygląda to tak, że switch JUŻ UZNAŁ za port wychodzący port 0 ZANIM pakiet o zapytanie w ogóle dotarł do dest, więc gdy odpowiedź przychodzi, zgodnie z tablicą arp wyszłaby z tego samego portu, co jest głupie i podejrzewam, że logika switcha po prostu ten pakiet ignoruje, bo nie widzimy żadnych nietagowanych ramek w snifferze na eth0). Wtedy odpowiedź z sieci własnej na vlanie 10 powędruje na port sieci gościnnej o vlanie 20, gdzie zostanie odrzucona. Więc do dzieła!
Atakujący w kablowej sieci gościnnej obrał sobie za ofiarę bramę główną sieci własnej. Wtedy żaden klient w sieci własnej nie będzie mieć dostępu do WAN, bo odpowiedzi bramy głównej będą dropowane na poziome L2 w switchu. Zakładając, że zna adres mac tej bramy, a zna, bo jest jej adminem
, odpala to, jako atakujący, na PC wpiętym do sieci gościnnej:
nping -e eth0 -HNc0 --source-mac ad:re:so:fi:ar:y0 --dest-mac ad:re:so:fi:ar:y0 --delay 1ms --arp 0.0.0.0(destmac można ustawić jakikolwiek, ja ustawiłem taki sam, żeby nie robić szumu w sieci.)
i, już jako admin, to na niedopracowanym switchu:
while : ; do sleep 1; clear; swconfig dev switch0 show | grep MAC; doneaby zobaczyć czy switch zgłupieje zgodnie z przewidywaniami (dany mac raz będzie na porcie atakującego, bo spamuje, a raz na porcie ofiary, która czasem wysyła jakieś inne pakiety). Jeżeli pakiet zwrotny trafi do switcha w czasie, gdy mac jest na porcie atakującego, mamy upragniony DoS.
Patrzymy na konsolkę i switch zdurniał, bo widać naprzemiennie:
Port 0: MAC (mac eth0)
Port 0: MAC (mac eth20)
i
Port 0: MAC (mac eth0)
Port 2: MAC (mac eth20)
a internetu w mojej sieci nie ma, chociażże tcpdump na bramie głównej mówi co innego ![]()
Piszę ten post z prośbą do forumowiczów, by sprawdzili to u siebie. Chyba najłatwiej będzie zbridgować 2 rózne vlany i na utworzonym bridgu postawić serwer dhcp. Niezależnie od lokacji, komunikacja klientów i routera (serwera dhcp) będzie działać ok, bo nie jest przekazywana do 2 portu, natomiast nie będą mogli wysyłać pakietów między sobą, chyba że na bcast. Jeżeli okaże się, że na waszym switchu też występuje ten problem, to napiszcie w poście model takiego switcha. Bo jeżeli nie ma problemu u nikogo, to nie zdurniał switch a ja.
Nie chcę dłużej szkodzić innym i zabierać cenny czas, tak więc dzięki za wytrwałość!
R.Ł.