IP klienta VPN w Kubernetes: zachować czy zrobić SNAT?
Wybierz między zachowaniem rzeczywistego adresu klienta VPN a NAT źródłowym w Kubernetes na podstawie trzech warunków, a następnie zweryfikuj ścieżkę powrotną i wymianę podów.
Gdzieś między tunelem a backendem adres klienta albo przetrwa, albo zostanie zastąpiony, i oba wyniki są do obrony. Wybór należy do właściciela usługi odbierającej, a nie do tego, kto zainstalował CNI. Gdy liczą się autoryzacja na klienta, limity lub zapisy audytowe, adres musi przetrwać każdy skok. Gdy wspólne przypisanie jest akceptowalne, NAT źródłowy usuwa problem routingu, który w przeciwnym razie utrzymywałbyś na zawsze.
Gdzie adres klienta naprawdę znika
Pakiet zdalnego klienta dociera do poda VPN z wewnętrznym źródłem w zakresie tunelu, powiedzmy 10.90.0.42. Gdy pod przekazuje ten pakiet w stronę ClusterIP lub IP poda, trzy różne mechanizmy mogą przepisać źródło. Reguła masquerade w CNI węzła obejmuje ruch, który pod wysyła poza CIDR klastra. Wpis conntrack kube-proxy w węźle docelowym obejmuje sam skok do Service. Proxy, które kończy połączenie, w ogóle nie przekazuje pakietu, więc źródło, które w końcu widzisz, należy do proxy.
Każdy żyje w innej warstwie, dlatego jedno pole Service prawie nigdy nie naprawia całej ścieżki.
externalTrafficPolicy w publicznym Service VPN decyduje tylko o tym, co dzieje się z połączeniem zewnętrznym: Local zachowuje zdalny adres w węźle, który go odebrał, natomiast Cluster pozwala kube-proxy przekazać pakiet innemu węzłowi i zamaskować go tam. To ustawienie rządzi listenerem, z którym łączą się twoi klienci. Nie mówi nic o odszyfrowanym pakiecie, który twój proces VPN kieruje potem do klastra.
Trzy warunki, które rozstrzygają spór
Zadaję te same trzy pytania w tej samej kolejności za każdym razem, gdy temat się pojawia, bo pierwsze zwykle kończy dyskusję. Odpowiedz na nie dla konkretnego obciążenia, a nie dla całego klastra. Dwa klastry w jednej firmie mogą dojść do różnych odpowiedzi i obie mogą być poprawne.
| Question | Preserve | SNAT |
|---|---|---|
| Does the backend enforce policy per client? | Yes, the address is the identity | Only if a trusted proxy supplies identity |
| Can the cluster route 10.90.0.0/24 back to a stable gateway? | Required | Not needed |
| Is the workload a forwarder or a proxy? | Forwarder | Proxy is fine |
Jeśli backend odpowiada tak na pierwsze pytanie i nie na drugie, masz pracę sieciową do wykonania, a nie manifest do edycji. Jeśli trzeci wiersz mówi proxy, adres nigdy nie miał przetrwać, a udawanie inaczej kosztuje tydzień przechwytywania pakietów.
Czego tryb preserve wymaga od sieci
Zachowanie źródła oznacza, że węzeł docelowy musi zwracać ruch do 10.90.0.42 przez aktywną bramę VPN. Pula VPN nie jest CIDR klastra, więc żadne CNI nie routuje jej za ciebie domyślnie. Dodajesz trasę samodzielnie, a potem pilnujesz, by punkt końcowy bramy, na który wskazuje, przetrwał przeplanowanie.
ip route add 10.90.0.0/24 via 10.244.3.17 dev eth0
sysctl -w net.ipv4.conf.eth0.rp_filter=2
Następny skok to adres poda, a adresy podów się przemieszczają. Skieruj trasę na VIP Service albo adres węzła, który zostaje na miejscu, albo zaakceptuj, że po każdym wyrugowaniu będziesz gonić bramę. Filtrowanie odwrotnej ścieżki to druga pułapka: tryb ścisły odrzuca pakiety, których ścieżka powrotna nie odpowiada interfejsowi, na którym dotarły, a to dokładnie kształt zachowanego przepływu VPN.
Luźna walidacja często bywa różnicą między działającą ścieżką powrotną a odpowiedziami, które znikają po opuszczeniu backendu. Reguły masquerade w węźle VPN też muszą wykluczać zakres tunelu, inaczej przekazany pakiet wychodzi z adresem poda, niezależnie od zbudowanej trasy. Lepiej wyrazić to wykluczenie w konfiguracji samego CNI niż ręcznie edytować iptables, bo agent przy restarcie przepisuje swoje łańcuchy, a twoja ręcznie napisana reguła przetrwa dokładnie do następnej aktualizacji.
NetworkPolicy to kontrola dostępu, nie routing. Zaostrzenie polityki nigdy nie przywróci adresu, który masquerade już zastąpił.
Ile kosztuje SNAT i jak to zapisać
NAT źródłowy w stronę klastra to tańszy projekt i nie jest błędem. Backend widzi adres poda lub węzła VPN, logi się zgadzają i żadna trasa powrotna nie musi istnieć. Tracisz możliwość odróżnienia dwóch klientów na warstwie sieci, więc limity, bany i ślady audytowe muszą pochodzić skądinąd.
Zwykle tym skądinąd jest aplikacja: token sesji, podpisany nagłówek albo wiersz protokołu PROXY zapisany przez proxy, które kontrolujesz. Dają one odbiorcy tożsamość, której może zaufać tylko wtedy, gdy proxy stoi na ścieżce, a nagłówka nie da się ustawić po stronie klienta. W runbooku wyraźnie wskaż, która obowiązuje, bo następny inżynier założy, że adres w logu to klient. Nie jest, a jeden incydent wystarczy, by to założenie stało się kosztowne.
Wymiana pozostaje uczciwa, dopóki jest zapisana.
Kontrole, które oddzielają działającą ścieżkę od szczęśliwej
Testuj na świeżym połączeniu, a nie na zbuforowanym, i testuj w obu kierunkach. Kilka awarii wygląda na przerywane tylko dlatego, że nowe przepływy idą przepisaną ścieżką.
Przechwyć tuple w trzech punktach podczas jednego autoryzowanego żądania: zaraz po dekapsulacji, na interfejsie wyjściowym poda VPN i na backendzie. Jeśli źródło zmienia się między drugim a trzecim przechwyceniem, przyczyna leży poniżej poda. Jeśli zmienia się przed drugim, sam pod tłumaczy.
Następnie usuń pod VPN i powtórz test, gdy jest przeplanowywany. Zachowana ścieżka, która psuje się przy wyrugowaniu, jest niedokończona, podobnie jak reguła NAT przypięta do adresu, który już nie istnieje. Na koniec wyślij jedno żądanie ze źródła, które spodziewasz się odrzucić, i potwierdź, że odmowa pochodzi z polityki, a nie z brakującej trasy.