Oczekujesz interfejsu tunelu, szukasz go, a w zaporze nie ma nic do dopasowania. To normalne dla bramy opartej na politykach: zaszyfrowana wymiana przychodzi na interfejs fizyczny, a odszyfrowany pakiet wewnętrzny, który następnie jest przekazywany, również jest obserwowany jako przychodzący na ten sam interfejs. Nie ma tun0, bo nic go nie utworzyło.

Żądanie wewnętrzne nadal jest osobnym pakietem z własnym źródłem, celem i usługą, a jądro wie, z której asocjacji bezpieczeństwa wyszedł. Właśnie tę wiedzę może dopasować reguła zapory.

Dwa pakiety, jeden interfejs

Wyobraź sobie kierunek przychodzący. Przychodzi pakiet enkapsulowany w ESP lub UDP, jądro znajduje pasującą politykę, odszyfrowuje go i przekazuje czysty pakiet ścieżce przekazywania. Reguła, która patrzy tylko na nazwę interfejsu, nie odróżni tego pakietu od innego ruchu przychodzącego tym samym przewodem.

Odróżnia go kontekst przychodzącej ścieżki bezpieczeństwa dołączony do pakietu. nftables udostępnia go jako meta ipsec exists, co jest prawdą, gdy pakiet przyszedł ścieżką bezpieczeństwa IPsec. Połącz go z pulą klientów, celem i usługą, a reguła stanie się wystarczająco konkretna, by była bezpieczna.

Pominięcie kontekstu to częsty błąd i jest to błąd bezpieczeństwa, a nie kosmetyczny. Reguła, która akceptuje wszystko pochodzące z puli klientów, równie chętnie akceptuje sfałszowany pakiet z sieci lokalnej, bo adres źródłowy sam w sobie nie jest dowodem na nic. Kontekst ścieżki bezpieczeństwa to najtańszy sposób nadania źródłu znaczenia. Pisz regułę z nim od początku, zamiast dodawać go po audycie.

Napisz regułę przekazywania

Załóżmy uwierzytelnioną usługę dostępu zdalnego IPv4 z klientami w 10.90.0.0/24 i jeden zatwierdzony cel pod 203.0.113.40. Fragment reguły dla tego przepływu wygląda tak.

meta ipsec exists ip saddr 10.90.0.0/24 \
  ip daddr 203.0.113.40 tcp dport 443 \
  oifname "eth0" counter accept

Adresy i interfejs to przykłady do zastąpienia. Umieść sprawdzony odpowiednik w polityce przekazywania przed regułą, która w przeciwnym razie odrzuciłaby przepływ, i nie opróżniaj istniejącego zestawu reguł, aby go zainstalować; brama nie jest eksperymentem w czystym pomieszczeniu.

Termin oifname warto zachować. Dokumentuje decyzję o wyjściu i zapobiega dopasowaniu reguły w kierunku, którego nie zamierzałeś, co ma znaczenie na bramie z kilkoma drogami do internetu. Na maszynie testowej z jednym łączem termin wygląda zbędnie i właśnie dlatego usuwa się go, zanim maszyna dostanie drugie łącze.

Uprawnienia do wymiany zewnętrznej są osobne. Ścieżka wejściowa bramy potrzebuje portów IKE i ESP lub enkapsulacji UDP, których naprawdę używa, a te uprawnienia niczego nie zezwalają w kwestii odszyfrowanego pakietu w środku. Mieszanie obu to droga, którą działający tunel kończy z zaporą przekazującą wszystko.

Kontekst przychodzący to nie kontekst wychodzący

Ta sama rodzina wyrażeń obejmuje drugi kierunek przez rt ipsec, który opisuje wychodzącą asocjację bezpieczeństwa, której użyje pakiet. Odpowiada na inne pytanie: nie skąd przyszedł ten pakiet, ale czy będzie chroniony na następnym odcinku.

Ten podział ma znaczenie na bramie, która jednocześnie kończy jeden tunel i przekazuje do drugiego. Pakiet może przyjść odszyfrowany i mimo to musieć wyjść zaszyfrowany, a akceptacja napisana tylko dla kontekstu przychodzącego nic nie mówi o wymogu wychodzącym. Jeśli polityka wymaga tej ochrony, zestaw reguł powinien ją wyrazić, a nie zakładać, że routing to załatwi.

Trzymaj oba pytania w osobnych regułach, aby czytelnik widział, które jest egzekwowane. Jedna sprytna reguła sprawdzająca oba jest trudniejsza do przejrzenia i znacznie trudniejsza do debugowania, gdy jedna jej połowa przestaje pasować. Dwie reguły z licznikami mówią też, który wymóg zawodzi, czego jedna połączona reguła nigdy nie zrobi.

NAT nie jest decyzją zapory

Ruch do internetu z prywatnej puli klientów zwykle wymaga tłumaczenia źródła, aby odpowiedź znalazła drogę powrotną. Ale ruch wybrany dla innej wychodzącej polityki IPsec musi zachować wymagane wyłączenie, a maskowanie każdego prywatnego źródła bez myślenia o następnej decyzji ochronnej to psuje.

Akceptacja wewnątrz łańcucha NAT też nie jest ogólnym zezwoleniem. NAT i filtrowanie mają różne zadania, a łańcuch NAT nie bada każdego późniejszego pakietu ustalonego przepływu, i właśnie dlatego poleganie na nim w kwestii bezpieczeństwa daje reguły, które wyglądają na działające w teście i zawodzą pod obciążeniem.

Odwrotność też jest prawdziwa i zaskakuje ludzi: akceptacja gdzieś w jednym łańcuchu bazowym filtrowania nic nie waży wobec późniejszego odrzucenia w innym obowiązującym łańcuchu. Wynik rozstrzygają kolejność i zakres łańcucha, a nie obecność akceptacji w pliku.

Zweryfikuj dokładną usługę wewnętrzną

Przetestuj konkretny cel i port, które autoryzowałeś, z prawdziwego klienta, i potwierdź, że odpowiedź wraca. Następnie przetestuj coś, czego nie autoryzowałeś, i sprawdź, że to nie przechodzi, bo zbyt szeroka reguła przechodzi pierwszy test równie dobrze jak poprawna. Żądanie, które nigdy nie opuszcza klienta, też nie jest wynikiem zapory, więc czytaj liczniki, aby zobaczyć, czy pakiet został w ogóle oceniony. Dwa testy i jeden odczyt licznika powiedzą ci więcej niż całe popołudnie czytania zestawu reguł.

Dokumentacja nftables opisuje meta ipsec, rt ipsec i wyrażenia właściwe dla kierunku, i tam właśnie sprawdza się składnię względem zainstalowanej wersji. I utrzymuj zakres jawnie: to jest przykład IPv4, nic nie mówi o IPv6 i nie zamienia dowolnego przekazywania portów publicznych w część usługi VPN.

Powiązane artykuły