Dwa skoki VPN na jednym Pi: która trasa niesie którego partnera
Dwa adresy tunelu na jednym Pi nie są usterką. Każde miejsce docelowe potrzebuje własnego nośnika, własnego dowodu i ogłoszonego planu awaryjnego, gdy zewnętrzny skok umiera.
Dwa adresy tunelu na jednej małej płytce wyglądają jak błąd, a odruchem jest usunięcie jednego. Ten odruch psuje to, co miał uporządkować. Host niosący dwa skoki trzyma jeden adres na każde przyłączenie, a każdy adres wybiera inna trasa. Pytanie, które warto zadać, brzmi: która trasa wybiera który nośnik dla którego miejsca docelowego, a nie ile adresów istnieje.
Trzy miejsca docelowe wymagające różnych nośników
Łańcuch dwóch skoków to trzy klasy miejsc docelowych ułożone jedna na drugiej, a każdą niesie inne przyłączenie. Zewnętrzny partner musi być osiągnięty przez łącze fizyczne. Wewnętrzny partner musi być osiągnięty przez tunel zewnętrzny. Miejsce docelowe objętej aplikacji musi być osiągnięte przez tunel wewnętrzny, którego własny transport niesie ten zewnętrzny.
| Destination class | View that names the carrier | Command that proves it | Symptom when the wrong carrier wins |
|---|---|---|---|
| Outer peer, 198.51.100.10 | the main table, by destination | ip route get 198.51.100.10 | the outer handshake never completes |
| Inner peer, 203.0.113.7 | the main table once the outer tunnel is up | ip route get 203.0.113.7 | the inner handshake leaves over the physical link |
| Application destination, 172.30.9.1 | the table the inner client's traffic is selected into | ip route get 172.30.9.1 from 10.8.0.2 | the exit address looks right and the traffic never crossed the outer hop |
| Parallel tunnels, one per source group | one policy per group, not the main table | ip rule show beside a marked test connection | both tunnels are up and one steals the other's traffic |
Wypełnij wiersze rzeczywistymi adresami czytelnika, zanim dotkniesz trasy, bo tabela jest użyteczna tylko wtedy, gdy jest konkretna. Działający łańcuch spełnia wszystkie cztery wiersze jednocześnie, a na wpół działający zwykle spełnia jeden z nich z niewłaściwym nośnikiem. To właśnie czytanie niewłaściwego wiersza jako awarii zamienia problem routingu w całe popołudnie poprawek.
Adresy mają role, nie liczbę
Linux pozwala na kilka adresów na jednym interfejsie i kilka tuneli na jednym hoście, więc liczba nic nie mówi o poprawności. Liczy się to, który adres należy do którego przyłączenia, i czy trasa dla danego partnera wybiera przyłączenie, które miałeś na myśli. Trzy widoki odpowiadają na to z trzech kierunków, i warto je czytać za każdym razem w tej samej kolejności.
Inwentarz adresów pokazuje, co istnieje i które przyłączenie to posiada. Tabela tras odpowiada na pytanie o nośnik dla zwykłego ruchu docelowego. Widok polityk odpowiada na nie ponownie dla ruchu wybieranego według źródła lub znacznika, co jest normalnym układem, gdy dwóch klientów dzieli jednego hosta.
ip -4 addr show
ip -4 route show table all
ip rule show
Usunięcie adresu, bo lista wygląda długo, może usunąć część ścieżki, a usunięcie trasy, bo wygląda zbędnie, robi to samo ciszej. Żadne z nich nie daje błędu; partner po prostu przestaje odpowiadać na ścieżce, którą miałeś na myśli, pozostając osiągalnym inną. Aplikacja, która zgłasza adres wyjścia wewnętrznego partnera, nie dowodzi, że ruch przeszedł przez tunel zewnętrzny, ponieważ bezpośredni dostęp daje tę samą obserwację. Właśnie ta luka między obserwacją a dowodem jest powodem sprawdzania nośnika na warstwie routingu.
Kolejność aktywacji bije stałe oczekiwanie
Jeśli wewnętrzny klient zależy od adresu lub trasy dostarczanej przez klienta zewnętrznego, aktywacja musi czekać na ten zasób, a nie na opóźnienie. Oczekiwanie działa do dnia, w którym tunel zewnętrzny jest wolny, a wtedy zawodzi okresowo w sposób, którego nikt nie potrafi odtworzyć. Kolejność oparta na zależnościach usuwa zgadywanie i nie kosztuje nic poza jednorazowym opisem zależności. Nazwy interfejsów też nie są mechanizmem kolejności.
Jądro przydziela nazwy takie jak tun0 i tun1 w kolejności tworzenia, a ta kolejność może się zmieniać między restartami lub ponownymi połączeniami. Powiąż konfigurację z tożsamością dostarczaną przez narzędzie albo z nazwą, którą świadomie nadajesz. Nazwa, którą wybierasz, jest umową; nazwa, którą wybiera jądro, jest przypadkiem.
Trzymaj transport każdego klienta poza trasą aplikacji drugiego i bądź precyzyjny co do tego, czego opcje routingu OpenVPN 2.6 naprawdę obiecują. Udokumentowany mechanizm domyślnego przekierowania utrzymuje klienta w stanie osiągnąć własnego zdalnego partnera przez bramę, która już istniała, co przecina jedną konkretną pętlę rekurencji. Nie czyni jednego klienta nośnikiem drugiego, więc reszta łańcucha pozostaje twoim projektem. Tam, gdzie łańcuch potrzebuje polityki zamiast trasy, napisz jawną regułę źródła lub znacznika i przetestuj ją z ruchem, z którym ma się zgadzać.
Co się dzieje, gdy zewnętrzny skok umiera
Zanim łańcuch będzie uznany za kompletny, zdecyduj, co się dzieje, gdy zewnętrzny skok znika. Transport wewnętrznego klienta umiera razem z nim, a następny krok jest kwestią polityki, nie techniki: zawieść, spróbować ponownie albo połączyć się bezpośrednio przez łącze fizyczne. Właśnie trzeci wynik jest tym, o którym warto pomyśleć. Po cichu zamienia projekt dwóch skoków w projekt jednego skoku w chwili, gdy użytkownik wierzy, że zasięg jest jeszcze nietknięty.
Jeśli dwa skoki są obowiązkowe, wewnętrzny klient nie może móc ustanowić bezpośredniej ścieżki, gdy zewnętrznego nie ma, a sposobem, by to sprawdzić, jest zerwanie zewnętrznego skoku i obserwacja, co robi wewnętrzny. Zatwierdzony plan awaryjny jest legalną odpowiedzią, ale musi być zapisany, przetestowany i zakomunikowany. Plan awaryjny, którego nikt nie udokumentował, jest nieodróżnialny od wycieku podczas przeglądu incydentu.
DNS i druga rodzina adresów należą do tej samej decyzji. Lokalnie generowane zapytanie podlega polityce samego hosta, a nie przekazanego klienta, więc resolver działający dla przekazanego ruchu może nie być tym, którego używa sam host.
Zaakceptuj każdą warstwę w kolejności, w jakiej ją zbudowałeś
Testuj w kolejności, w której zbudowano łańcuch: najpierw sam tunel zewnętrzny, potem transport wewnętrznego klienta przez tunel zewnętrzny, potem aplikację przez tunel wewnętrzny. Każda akceptacja musi być nowym połączeniem, a nie stroną, która już była otwarta. Następnie zerwij i odtwórz każdą warstwę osobno i obserwuj, co robi następna.
Wynik planu awaryjnego jest tu najcenniejszą obserwacją, i tą, której strona z publicznym IP nigdy nie pokazuje. Zapisz ścieżki partnerów, adresy, których używają, i ten wynik obok konfiguracji, bo szczęśliwa ścieżka nie jest częścią, o którą pyta się później.