Dlaczego nftables nie widzi ruchu OpenVPN między klientami
Ruch między równorzędnymi węzłami jest dostarczany wewnątrz procesu VPN, więc liczniki przekazywania nigdy się nie ruszają. Aby go policzyć, trzeba wybrać między ścieżką jądra a ścieżką procesu.
Dwaj klienci na jednym serwerze wymieniają pliki, transfer się udaje, a każda reguła przekazywania skierowana na tunel zgłasza zero pakietów. Reguły nie są zepsute i łańcuch nie stoi w złym miejscu. Gdy przekazywanie między węzłami jest włączone, pakiet jest dostarczany wewnątrz procesu serwera, a stos gospodarza nigdy nie staje się routerem, więc zaporze jądra nie ma czego liczyć. Zrozumienie tego podziału decyduje, czy zachowasz skrót, czy odbudujesz ścieżkę przez jądro.
Prześledź jeden pakiet przez serwer
W tunelu routowanym demon przekazuje odszyfrowany pakiet każdego klienta do urządzenia tunelowego. Stamtąd gospodarz go trasuje, uruchamia się hak przekazywania, a reguła pasująca do urządzenia tunelowego może ruch policzyć lub odrzucić. To ścieżka, którą zakłada większość przykładów zapory.
| Forwarding path | Who decides | What the host firewall sees |
|---|---|---|
| Kernel routing between clients | Host routing table and forward rules | Every inner packet, with interface names |
| Peer forwarding inside the server process | The VPN daemon's own peer table | Only the outer encrypted transport |
Skrót usuwa gospodarza ze środka. Odszyfrowany pakiet jednej sesji jest przekazywany innej sesji wewnątrz demona, a pakiet wewnętrzny nigdy nie jest wysyłany na urządzenie tunelowe ani trasowany przez gospodarza. Ruch enkapsulowany nadal przekracza interfejs fizyczny, więc zewnętrzny zapis wygląda na zajęty, podczas gdy reguły wewnętrzne milczą. Zapis wykonany na urządzeniu tunelowym nie pokazuje zupełnie nic, co zaskakuje każdego, kto spodziewa się tam zobaczyć transfer. Ta asymetria to najszybszy sposób rozpoznania skrótu z zewnątrz demona.
Test licznika, który rozstrzyga, która ścieżka została użyta
Podłącz licznik do reguły, która powinna zadziałać, uruchom transfer między dwoma klientami, które ta reguła powinna zablokować, a potem odczytaj licznik.
sudo nft list ruleset
sudo nft add rule inet filter forward iifname "tun0" oifname "tun0" counter accept
sudo nft list chain inet filter forward
Jeśli transfer się uda, a licznik pozostanie na zerze, jądro nigdy nie obsłużyło tych pakietów i żadna edycja reguł tego nie zmieni. Powtórz ten sam test wobec usługi na samym serwerze, bo ten przepływ rzeczywiście przechodzi przez stos gospodarza i jego licznik się porusza. To porównanie obu wyników daje odpowiedź.
Dwa szczegóły zapobiegają błędnemu odczytowi. Nazwa interfejsu wpisana w etykietę łańcucha sama niczego nie filtruje, bo dopasowanie odbywa się na polach interfejsu wewnątrz reguł. A konstrukcja mostkowana warstwy 2 zachowuje się jeszcze inaczej: tam klienci dzielą jedną domenę rozgłaszania, więc wykrywanie węzłów jest oczekiwane, a nie usterką trasowania.
Przełącznik to nie lista dostępu
To jest ta część, która kosztuje pół dnia. Przekazywanie między węzłami to jedno ustawienie włączone albo wyłączone, a dopóki jest włączone, demon jest jedynym punktem przekazywania. Zapora gospodarza nie potrafi wyrazić, kto kogo może osiągnąć, a pliki na klienta nie zamieniają przełącznika w matrycę polityki.
Jeśli potrzebujesz reguł na węzeł, wybór jest między rezygnacją ze skrótu a rezygnacją z zapory gospodarza jako narzędzia kontroli. Wyłączenie jej przywraca przekazywanie w jądrze, co wymaga włączonego przekazywania IP na serwerze i jawnych reguł dla pożądanych przepływów. Pozostawienie jej włączonej oznacza, że polityka żyje w konfiguracji demona, co w praktyce oznacza wszystkie węzły albo żaden.
Osobne procesy serwera z własnymi pulami adresów i portami to wykonalna droga środka. Każdy proces niesie dokładnie jedną decyzję o dostępie, więc dwie grupy mogą mieć różne reguły bez matrycy polityki. Gospodarz może trasować między pulami, gdy to zamierzone, a wtedy zapora widzi te przepływy, bo przekraczają gospodarza. Koszt to dodatkowe porty, dodatkowe certyfikaty i profil na grupę.
Wybór punktu przekazywania
Wybierz przekazywanie w jądrze, gdy zapora jest silnikiem polityki, gdy potrzebujesz rejestracji na przepływ lub gdy rozliczanie ma znaczenie. Koszt to przepustowość przez stos gospodarza i więcej reguł do utrzymania. Korzyść jest taka, że każde istniejące narzędzie, od liczników po eksportery przepływów, znów opisuje ruch. Na małym serwerze ten koszt jest niewidoczny; na zajętym przekaźniku nie.
Wybierz przekazywanie w procesie, gdy ruch między węzłami jest albo całkowicie dozwolony, albo całkowicie zabroniony i serwer jest do tego zwymiarowany. Koszt to fakt, że liczniki, dyscypliny kolejek i śledzenie połączeń nie opisują już przepływów wewnętrznych; jest to do przyjęcia tylko wtedy, gdy nikt później na nich nie polega.
Cokolwiek wybierzesz, zapisz to obok reguł zapory. Zbiór reguł, który wygląda, jakby zezwalał na ruch między węzłami, podczas gdy demon i tak decyduje, wprowadza w błąd następną osobę, która będzie debugować nieudany transfer. Kto czyta tylko reguły, uzna, że bramą jest jądro.
Co sprawdzić przed zmianą reguł
Czytaj konfigurację, którą serwer rzeczywiście wczytał, a nie plik, który pamiętasz jako edytowany, i potwierdź, czy opcja węzłów jest obecna. Jeśli ją zmieniłeś, upewnij się, że usługa wczytała się ponownie, a nie tylko nadpisała plik na dysku.
Potem powtórz test z przepływem od klienta do serwera, aby dowieść, że reguła w ogóle pasuje, i sprawdź wypychane trasy, bo brakująca trasa wygląda ze strony klienta dokładnie jak blokada zapory. Kolejność reguł zmieniaj dopiero wtedy, gdy wiesz, który punkt przekazywania ma decyzję.