Pi jako klient VPN: jeden menedżer czy własny skrypt?
Porównaj profil NetworkManagera z ręcznie napisanym skryptem klienta na Raspberry Pi, w tym pełny tunel, DNS, IPv6 i zachowanie po zerwaniu tunelu.
Raspberry Pi, który ma chronić tylko własny ruch wychodzący, ma dwa realistyczne projekty: pozwolić menedżerowi sieci posiadać tunel albo trzymać skrypt, który go posiada. Oba mogą przenosić ruch. Zawodzą w różnych miejscach, a awaria, którą można zdiagnozować zdalnie o drugiej w nocy, jest tą, którą warto wybrać. Porównaj je pod względem własności, tego, co oznacza pełny tunel, gdy w grę wchodzą IPv6 i DNS, oraz tego, co dzieje się w chwili, gdy tunel padnie.
Dwóch właścicieli jednego tunelu
Projekt A to profil wewnątrz menedżera sieci systemu: zaimportowany profil OpenVPN lub natywne połączenie WireGuard, aktywowane przy starcie przez tę samą usługę, która podnosi Ethernet i Wi-Fi. Projekt B to twoja własna jednostka, która uruchamia klienta bezpośrednio, edytuje konfigurację resolvera i instaluje własne trasy oraz reguły zapory. Oba są uzasadnione; różnią się tym, komu wolno zmieniać tablicę routingu.
Awarie różnią się, bo właściciele się różnią. Przy A profil, który się nie aktywuje, zostawia interfejs podniesiony, a tunel opuszczony, a logi menedżera mówią dlaczego. Przy B skrypt, który uda się połowicznie, zostawia trasy, które przeżywają proces, który je stworzył. Uruchamianie obu to najgorszy wynik: dwa procesy piszą trasę domyślną, dwie edycje resolvera ścigają się przy starcie, a dwa zestawy sekretów trzeba rotować.
Wybierz jednego właściciela na tunel i wyłącz drugiego, zanim cokolwiek przetestujesz. Dwóch właścicieli oznacza też dwa miejsca do sprawdzenia, gdy tunel jest podniesiony, a nic się nie rozwiązuje. Ta jedna reguła zapobiega większości mylących stanów opisanych w wątkach o Pi VPN.
Co tworzy import, a czego nie
W Raspberry Pi OS Bookworm i nowszych domyślnym narzędziem konfiguracji sieci jest NetworkManager, więc profil jest naturalnym domem tunelu klienta. Import wymaga zainstalowanej odpowiedniej wtyczki; bez niej kończy się komunikatem o nieobsługiwanym typie połączenia, co jest uczciwym sygnałem, by się zatrzymać i zainstalować wtyczkę.
nmcli connection import type openvpn file ./provider.ovpn
nmcli connection show
nmcli --ask connection up id provider-name
Import zapisuje profil. Nie dowodzi, że druga strona jest osiągalna, i nie gwarantuje, że każda dyrektywa w pliku przetrwała konwersję. Odczytaj wynikowe połączenie i sprawdź części niosące tożsamość i zaufanie: certyfikat, zdalny host i port oraz to, czy hasło jest pytane, czy zapisywane.
Aktywacja z --ask trzyma frazę hasła poza historią powłoki na współdzielonej maszynie. Dla Pi bez nadzoru w końcu zechcesz, aby profil podnosił się przy starcie, co jest osobną decyzją od jednorazowego podniesienia ręcznie.
Pełny tunel w porównaniu obu projektów
Pełny tunel to twierdzenie o trasach, nie o intencji, i oba projekty wyrażają je różnie. Podejście z profilem prosi menedżera o zainstalowanie trasy domyślnej i swoich ustawień resolvera; podejście ze skryptem robi to, co mówi skrypt, łącznie z niczym. Żaden projekt nie obejmuje IPv6, jeśli się tego nie powie, a nietknięta trasa domyślna IPv6 chętnie poniesie ruch poza tunelem, podczas gdy IPv4 wygląda bezbłędnie.
ip -4 route get 198.51.100.23
ip -6 route show default
resolvectl query example.org
Do sprawdzenia trasy użyj adresu dokumentacyjnego i zastąp go hostem, który wolno ci sondować. Pierwsze polecenie pokazuje, którego interfejsu Pi użyłby dla zwykłego celu; drugie pokazuje, czy istnieje jeszcze trasa domyślna IPv6; trzecie dowodzi, który resolver odpowiedział. Przeczytaj wszystkie trzy, zanim uwierzysz w jakiekolwiek twierdzenie o pełnym tunelu.
Jeśli instrukcje dostawcy obiecują pełny tunel, ale trasa domyślna IPv6 przetrwa, Pi przecieka. Wyłącz IPv6 na łączu wyjściowym albo poproś profil, by jej zażądał, i zdecyduj świadomie, zamiast odkrywać to później.
Błąd otwarty kontra zamknięty
Gdy tunel padnie, tablica routingu, która traci trasę domyślną, po prostu wraca do fizycznego łącza wyjściowego, a ruch idzie jawnie. To błąd otwarty i jest to domyślne zachowanie obu projektów, o ile coś temu nie zapobiega. Większość ludzi odkrywa to tygodnie później, czytając log zapory.
Błąd zamknięty kosztuje cię dostęp zdalny, gdy tunel jest wyłączony, więc wymaga świadomego wyjątku dla ścieżki zarządzania. Jednym ze sposobów jest reguła, która poza tunelem pozwala tylko na adres peera VPN:
sudo nft add table inet vpnkill
sudo nft 'add chain inet vpnkill out { type filter hook output priority 0; policy accept; }'
sudo nft add rule inet vpnkill out oifname != "tun0" ip daddr != 203.0.113.24 reject
Porównaj koszt operacyjny uczciwie. Profil zwykle nie potrafi wyrazić tej reguły, więc błąd zamknięty pcha cię ku projektowi ze skryptem lub ku małej jednostce, która instaluje regułę niezależnie od tunelu. W każdym razie przez tydzień loguj odrzucenia: ciche odrzucenie wygląda identycznie jak zepsuta usługa, i będziesz chciał licznika, gdy użytkownik zgłosi, że jedna witryna przestała się ładować.
Wybór dla Pi bez ekranu
Jeśli obraz już uruchamia NetworkManagera, tunel nie wymaga niczego egzotycznego, a chcesz, by sam podążał za łączem wyjściowym, weź profil. Jeśli potrzebujesz routingu polityk, kilku tuneli wybieranych według celu albo reguły błędu zamkniętego, która musi istnieć, zanim tunel się podniesie, weź skrypt i posiadaj każdą jego część, łącznie z kolejnością startu i sprzątaniem. Mieszanie obu projektów kosztuje więcej niż każdy z osobna.
Migracja między nimi to głównie kwestia kolejności: wyłącz starego właściciela, potwierdź, że nie przetrwała żadna nieaktualna trasa ani wpis resolvera, potem włącz nowego i uruchom ponownie dwa razy. Jeden restart może ukryć wyścig, który ujawni drugi. Zakończ testowaniem Pi, a nie tunelu: rozwiąż nazwę, pobierz coś przez IPv4, pobierz przez IPv6, jeśli je zachowałeś, potem zrzuć tunel i potwierdź, że wybrane zachowanie naprawdę występuje. Interfejs w ip link to początek testu, nie koniec.