Zwykła ochrona przed pętlą to trasa hosta: wyślij ruch do publicznego adresu serwera VPN przez łącze nadrzędne, aby zaszyfrowana sesja nigdy nie weszła do własnego tunelu. To działa dokładnie do momentu, gdy chcesz też dotrzeć do usługi internetowej na tym samym serwerze przez tunel, bo wyjątek jest oparty na celu, a cel jest identyczny. Wyjściem jest zaprzestanie klasyfikowania po celu i rozpoczęcie klasyfikowania według tego, które gniazdo wysłało pakiet.

Zacznij od dwóch strumieni, które chcesz rozdzielić

Jednym strumieniem jest sam zaszyfrowany transport OpenVPN, który musi wychodzić przez łącze nadrzędne, inaczej tunel niósłby własne połączenie zewnętrzne. Drugi to zwykłe żądanie HTTPS do tego samego publicznego adresu, które chcesz mieć wewnątrz tunelu, aby dotarło do usługi ze źródła tunelu. Ten sam cel, w wielu przypadkach ten sam numer portu, inna wymagana ścieżka.

W tym omówieniu załóż klienta na 10.90.0.10 przez tun1, publiczny adres serwera 198.51.100.25 i nietkniętą tabelę główną, której domyślna trasa wskazuje zwykłe łącze nadrzędne. Strona serwera musi też akceptować usługę internetową na ścieżce wewnętrznej i odsyłać ruch do źródła tunelu; wysłanie pakietu na publiczny adres nie omija nasłuchu ani polityki zapory serwera.

Zanim cokolwiek zmienisz, zapisz bieżące reguły hosta i wybierz wartości, których nikt inny nie używa: znacznik, numer tabeli i trzy priorytety reguł. Zadbaj o drogę powrotną do maszyny, która nie przechodzi przez to połączenie, bo błąd tutaj odbiera własny zdalny dostęp, a nie tylko psuje kartę przeglądarki.

Oznacz gniazdo, które przenosi kopertę

Konfiguracja klienta zyskuje znacznik dla swoich zaszyfrowanych pakietów wychodzących i przestaje sama instalować trasy, aby polityka zastępcza była jedyną rzeczą decydującą o ścieżkach:

mark 42
route-noexec
disable-dco

Dziesiętne 42 to szesnastkowe 0x2a, a forma szesnastkowa jest tym, do czego dopasują się reguły routingu. Dokumentacja link-options opisuje mark jako coś, co dotyczy zaszyfrowanych pakietów wychodzących w Linuksie, czyli dokładnie tego gniazda, którego ścieżką musisz sterować. Wyłączenie odciążenia kanału danych utrzymuje ten przykład na ścieżce przestrzeni użytkownika, gdzie zachowanie znacznika jest tym opisanym.

route-noexec tłumi automatyczne dodawanie i usuwanie tras przez OpenVPN. Nie instaluje niczego w ich miejsce, więc od tej chwili właściciel tras musi utrzymywać każdą trasę, której potrzebuje tunel. Jeśli prywatny cel zniknie po zmianie, to brakująca polityka zastępcza, a nie błąd znacznika.

Nie utrzymuj trasy hosta w tabeli głównej dla 198.51.100.25 podczas tej operacji. Taka trasa ponownie wprowadza dokładnie ten wyjątek, który projekt próbuje zawęzić, i wygra dla strumienia HTTPS, zanim zostanie sprawdzona którakolwiek z poniższych polityk.

Wyślij wszystko inne do tabeli tunelu

Gdy interfejs tunelu istnieje i ma swój adres, polityka wygląda tak:

ip -4 route add default dev tun1 src 10.90.0.10 table 47100
ip -4 rule add priority 20000 lookup main suppress_prefixlength 0
ip -4 rule add priority 20001 not fwmark 0x2a lookup 47100
ip -4 rule add priority 20002 not fwmark 0x2a unreachable

Pierwsza reguła utrzymuje widoczność tras specyficznych hosta, w tym każdej zatwierdzonej sieci lokalnej, jednocześnie czyniąc trasę domyślną tabeli głównej niewidoczną dla tego wyszukiwania. To rozróżnienie ma znaczenie: tłumienie trasy domyślnej nie jest tym samym co ignorowanie tabeli, a lokalne wyjątki, których nadal potrzebujesz, przetrwają właśnie dzięki temu. Czytaj te wyjątki jeden po drugim, zamiast zakładać, że wynik jest uniwersalnym wyłącznikiem awaryjnym.

Ruch nieoznaczony trafia wtedy do tabeli tunelu, przejmuje źródło tunelu i wychodzi przez VPN. Ruch oznaczony zawodzi w teście fwmark na dwóch kolejnych regułach i przechodzi do zwykłego wyszukiwania głównego niżej na liście, gdzie wciąż jest domyślna trasa łącza nadrzędnego. Końcowa reguła unreachable jest tym, co powstrzymuje nieoznaczony strumień przed cichym powrotem do łącza nadrzędnego, gdy brakuje trasy tunelu. Selektor to znacznik od początku do końca, a adres celu nigdy nie wchodzi do decyzji.

Utrzymuj tę blokadę między rozłączeniami i instaluj ją razem z resztą polityki, a nie ręcznie. Reguła, która znika wraz z interfejsem, nie jest polityką, lecz przypadkiem. Usunięcie polityki, gdy tunel pada, zmienia tryb awarii z „zablokowany” na „wyciekł”, a nieaktualna trasa tunelu, która później wygasa, jest znacznie łatwiejszym do wyjaśnienia problemem niż ruch, który wyszedł przez niewłaściwy interfejs.

Spraw, by ścieżka powrotna widziała ten sam znacznik

Znaczniki wychodzące to tylko połowa mechanizmu, i to jest część, którą pomija większość reprodukcji. Odpowiedzi do zaszyfrowanej sesji przychodzą przez łącze nadrzędne i podlegają walidacji ścieżki powrotnej, która pyta, czy źródło byłoby routowane z powrotem tą samą drogą. Bez pomocy to wyszukiwanie stosuje twoją nieoznaczoną politykę tunelu i dochodzi do wniosku, że pakiet jest na niewłaściwym interfejsie.

Poprawka należy do właściciela zapory: zapisz znacznik na połączeniu wychodzącym, odtwórz go na pasujących pakietach przychodzących i włącz obsługę znaczników walidowanych przez źródło dla odpowiedniej ścieżki. Ustawienie znacznika gniazda przez OpenVPN nie robi żadnej z tych trzech rzeczy, a przepis, który wymienia tylko opcje klienta, jest niekompletny. Poproś o tę integrację na piśmie, bo jest to najmniej widoczna część projektu i najłatwiejsza do zgubienia przy odbudowie.

Luźna weryfikacja ścieżki powrotnej też nie jest zamiennikiem. Tryb luźny nadal wymaga, by istniała jakaś trasa do źródła, a dodana przez ciebie blokada unreachable celowo usuwa jedną dla nieoznaczonych wyszukiwań. Dokończ i przejrzyj integrację znacznika połączenia, zanim oprzesz się na tym projekcie, a filtry hosta traktuj jako osobną kwestię: znacznik to sygnał routingu, nie pozwolenie. Jeśli integracji brakuje, objawem jest sesja, która się nawiązuje, a potem cichnie, gdy tylko zaczynają przychodzić odpowiedzi.

Udowodnij to dwoma wyszukiwaniami trasy

Porównaj, co jądro decyduje dla obu kontekstów, i czytaj pola dev i src, a nie kod wyjścia:

ip -4 route get 198.51.100.25
ip -4 route get 198.51.100.25 mark 0x2a

Pierwsze wyszukiwanie powinno rozwiązać się do tun1 ze źródłem tunelu, a drugie do łącza nadrzędnego. To wyszukiwania syntetyczne, więc dowodzą polityki, a nie działającego procesu: potwierdź osobno rzeczywistą ścieżkę transportu działającego klienta, a potem wykonaj prawdziwe żądanie HTTPS z włączoną weryfikacją certyfikatu.

Zapisz, czego projekt nie obejmuje, zanim uznasz go za gotowy. DNS, IPv6 i cykl życia reguł wymagają każdy własnej decyzji, a to jest przykład routingu IPv4, a nie kompletna konfiguracja prywatności. Jego wartość to selektor: koperta otrzymuje wyjątek łącza nadrzędnego, a zwykła usługa pod tym samym adresem nie musi go dziedziczyć.

Powiązane artykuły