Routing źródłowy dla dwóch pul VPN: czego twoja reguła nie zauważa
Reguła postaci from pasuje do adresu klienta, zanim SNAT go przepisze, a test z bramy nie pasuje do żadnego z nich. Wykonaj wyszukiwanie dla każdej puli i czytaj priorytety.
Dwie pule klientów, jedna brama i plan wygląda banalnie: jedna reguła wypuszcza pierwszą pulę szybkim łączem, druga wypuszcza drugą pulę przez tunel partnerski. Potem reguły są na miejscu, a druga pula nadal wychodzi domyślną trasą. Reguła nie jest zepsuta. Źródło pakietu nie jest tym, czego autor oczekiwał w chwili wyszukiwania, bo tłumaczenie i wyszukiwanie odbywają się w różnych punktach podróży tego samego pakietu, a kolejność jest odwrotna do schematu, który większość rysuje.
Wyszukiwanie odbywa się, zanim źródło zostanie przepisane
Dla pakietu przekazywanego od klienta VPN jądro wykonuje ustaloną sekwencję. Pakiet trafia na interfejs tunelu, przechodzi przez prerouting, gdzie mieszkają conntrack i DNAT, następnie podejmowana jest decyzja routingu, potem przekazanie, potem postrouting, gdzie SNAT jest stosowany jako ostatni. Reguła postaci from jest sprawdzana podczas tej decyzji routingu, czyli widzi pierwotny adres klienta, a nie przetłumaczony.
Dodanie reguły masquerade nie zmienia więc tego, która polityka pasuje do ruchu wychodzącego. Zmienia to, co widzi drugi koniec, a więc jaka ścieżka powrotna istnieje. To dwa różne skutki, a przeglądy zmian stale je mieszają. Rozdziel je, a projekt zwykle staje się jasny w ciągu minuty.
To w kierunku odpowiedzi przetłumaczony adres pojawia się w regułach. Pakiet wracający do bramy jest adresowany na przetłumaczony adres, a jeśli masz reguły polityki oparte na celu lub na interfejsie, przez który przyszedł, to właśnie tej wartości będziesz dopasowywać. To samo połączenie, w każdym kierunku inne źródło prawdy.
| Stage | Source the kernel sees | What it means for your rule |
|---|---|---|
| Prerouting | Client address, 172.31.7.42 | Where marks and DNAT are applied |
| Routing decision | Still 172.31.7.42 | This is where from rules match |
| Postrouting | Becomes 198.51.100.9 | What the far end and its return route see |
Dwie pule o różnych źródłach rzeczywiście potrzebują różnych tabel, a projekt jest poprawny. To, co wyklucza powyższa tabela, to skrót polegający na debugowaniu przez patrzenie, co odebrała strona zdalna, i wywnioskowanie z tego reguły.
Test z bramy nie jest testem puli
Ruch generowany przez samą bramę nigdy nie przechodzi przez prerouting, bo nie dotarł na żaden interfejs. Jest routowany w ścieżce wyjściowej, ze źródłem w postaci adresu samej bramy, a reguła from oparta na zakresie klientów nie będzie pasować. Każde zgłoszenie w tej dziedzinie mówiące, że działa z pudełka, ale nie od klienta, jest powtórzeniem tego samego faktu.
Symuluj klienta zamiast go aproksymować. O wyszukiwanie routingu można zapytać wprost, podając źródło i interfejs wejściowy:
ip route get 198.51.100.9 from 172.31.7.42 iif tun0
ip route get 198.51.100.9 from 172.31.8.42 iif tun0
ip route show table 201
Uruchom to raz na pulę. Jeśli oba polecenia zwrócą ten sam interfejs, reguły nie rozdzielają pul, a przyczyną jest albo brakująca reguła, albo reguła o wyższym priorytecie pasująca do obu. Jeśli zwrócą różne interfejsy, ale klient nadal zawodzi, błąd jest za wyszukiwaniem i możesz przestać patrzeć na reguły.
Priorytet, a nie pozycja w pliku
Reguły są oceniane w rosnącej kolejności priorytetu, a liczy się liczba, nie kolejność wpisania. Tabela local jest na priorytecie 0, tabela main na 32766, a reguła domyślna na 32767, dlatego reguła dodana z domyślnym priorytetem ląduje blisko końca listy i przegrywa z niemal wszystkim.
ip rule show
ip rule add from 172.31.8.0/24 lookup 201 priority 1000
ip -4 route show table 201
Jawny priorytet czyni zamierzony porządek widocznym w pliku i w przeglądzie. Zapobiega też temu, by późniejsze dodanie po cichu wyprzedziło istniejącą regułę, co jest najczęstszą przyczyną tego, że działająca polityka przestaje działać po niepowiązanej zmianie.
Pasująca reguła wskazująca na niekompletną tabelę to druga pułapka. Jeśli tabela 201 zawiera trasę domyślną, ale nie trasę do celu, pakiet jest odrzucany lub wysyłany w złe miejsce, a reguła w izolacji wygląda całkowicie poprawnie. Czytaj tabelę, nie tylko regułę. Reguła to wskaźnik, a pusta tabela to wskaźnik donikąd.
Ścieżka powrotna nadal musi istnieć
Polityka źródła wybiera wyjście. Nie tworzy ścieżki powrotnej. Jeśli druga pula wychodzi przez tunel partnerski, partner musi wiedzieć, jak dotrzeć do 172.31.8.0/24, albo trasą powrotną do bramy, albo otrzymując przetłumaczone adresy, które już zna.
Wybór między tym jest decyzją projektową o widocznych skutkach. Routowanie zakresu klientów z powrotem zachowuje tożsamość każdego klienta u partnera i wymaga, by zaakceptował twój prefiks. Tłumaczenie ukrywa pulę za jednym adresem i wymaga, by partner akceptował tylko ten adres, za cenę tego, że twoje i jego logi nie są już zgodne co do tego, kto się połączył.
Cokolwiek wybierzesz, zapisz to obok definicji puli. Trasa powrotna istniejąca tylko w czyjejś pamięci to dokładnie ten rodzaj rzeczy, który przetrwa do momentu, gdy partner zmieni zaporę, a potem zajmuje dzień na odtworzenie.
Nie łap własnego tunelu bramy w polityce
Reguły, które piszesz dla klientów, dotyczą także ruchu generowanego przez bramę, chyba że go wykluczysz. Szeroka reguła oparta na znaczniku lub na interfejsie wyjściowym może złapać własne połączenie bramy z partnerem, i wtedy tunel niosący politykę jest routowany przez politykę. To daje pętlę lub awarię wyglądającą jak błąd dostawcy.
Ogranicz każdą regułę tak wąsko, jak pozwala projekt: prefiks źródła, interfejs wejściowy i, gdzie to obsługiwane, znacznik noszony tylko przez pakiety klientów. Potem testuj własną łączność bramy po każdej zmianie reguł, bo awaria jest samoodnosząca się i nie pojawia się w teście od klienta.
Strona podręcznika ip-rule dokumentuje semantykę selektora i priorytetu. Połącz ją z testem wyszukiwania dla każdej puli, a projekt staje się weryfikowalny, co jest różnicą między routingiem polityki, który przetrwa rok, a takim, którego wszyscy boją się dotknąć.