Jedna aplikacja przez WireGuard: wiązanie to nie routing
Powiązanie aplikacji z wg0 ustawia tylko jej adres źródłowy. Jądro nadal potrzebuje tabeli z trasami tunelu i reguły, która wysyła ten adres źródłowy właśnie tam.
Ustawienie wygląda jak przełącznik dla pojedynczej aplikacji, więc ludzie wiążą klienta z interfejsem WireGuard i oczekują, że tylko ten klient będzie używał tunelu. Wiązanie w rzeczywistości wybiera adres źródłowy. Potem jądro szuka trasy do celu, znajduje zwykłą trasę domyślną i wysyła pakiet przez łącze fizyczne z dołączonym adresem tunelu. Tylko trasa wybrana dla tego adresu źródłowego realizuje zamierzenie.
Mechanizm ma dwie połowy: tabelę routingu, której powinien używać tylko ruch tunelu, oraz regułę, która wysyła tam pasujące źródło.
Wiązanie ustawia adres źródłowy i nic więcej
Linux wybiera interfejs wyjściowy, szukając celu w tabeli routingu, po tym jak reguły polityki miały szansę przekierować to wyszukiwanie. Reguły mogą wybierać po adresie źródłowym, znaczniku firewalla, interfejsie wejściowym, UID, a nawet porcie; każda z nich to inny sposób powiedzenia ten ruch, a nie cały. Konfiguracja klienta VPN wybiera tabelę, która zawiera trasy tunelu; reguła wybiera, który ruch może ją konsultować. Samo wiązanie nie daje ani jednego, ani drugiego.
Dlatego ta awaria wygląda tak dziwnie. Aplikacja z pewnością używa adresu tunelu, tunel z pewnością działa, a ruch z pewnością wychodzi przez niewłaściwy interfejs. Każde zdanie jest prawdziwe, a razem opisują system, w którym nic nie połączyło adresu z trasą.
Daj tunelowi własną tabelę
wg-quick instaluje trasy tam, gdzie każe profil. Dodanie Table = 40 pod [Interface] przenosi je do tabeli 40 zamiast do tabeli głównej. Podnieś interfejs i potwierdź, że dotarły: ip -4 route ls table 40 powinno pokazać trasy tunelu, a ip -4 route get 10.66.127.142 pokazuje, jak jądro obecnie rozwiązuje jedną z nich. Gdy trasy są we własnej tabeli, tabela główna nadal działa dla wszystkiego innego.
Zrób to samo dla IPv6, zamiast dopasowywać szeroki prefiks. ip -6 rule add from fd00::2/128 lookup 40 przypina jeden adres; fc00::/8 może kolidować z innymi interfejsami na hoście i utworzyć regułę pasującą do więcej, niż zamierzano.
Dodaj regułę źródła i patrz na liczniki
Następnie połącz obie połowy: ip -4 rule add from 10.66.127.142/32 lookup 40, z tym samym adresem przypiętym do interfejsu WireGuard. Umieść obie reguły w PostUp, aby ponowne połączenie je odtworzyło. Sprawdź prawdziwym żądaniem, a nie ustawieniem: ip route get 1.1.1.1 from 10.66.127.142 powinno wskazać urządzenie tunelu, a curl --interface wg0 ifconfig.me powinno zgłosić adres tunelu, a nie domowy.
Gdy nadal nie działa, przeczytaj ip -s rule. Reguła, która istnieje, ale nigdy nie została dopasowana, pokazuje zerowe liczniki, i to odróżnia błędną regułę od braku reguły. To jedno polecenie oszczędza wiele domysłów, czy aplikacja zignorowała swoje ustawienie interfejsu.
Odwrotny przypadek: trzymaj SSH poza tunelem
Przeciwny problem jest równie częsty: wg-quick posiada trasę domyślną i sesja SSH do serwera ginie w połowie sesji. Jego reguły mają niski numer priorytetu, więc wyjątek musi być oceniony wcześniej niż one. ip rule add dport 22 ipproto tcp table main priority 123 robi to na nowszym iproute2; tam, gdzie selektor nie jest dostępny, oznacz przepływ w nftables i dopasuj znacznik.
Sprawdź także ścieżkę odpowiedzi. Sesja SSH, która się nawiązuje, a potem milknie, zwykle ma routing asymetryczny: jeden kierunek wychodzi przez tunel, drugi przez interfejs fizyczny. ip route get dla adresu serwera powie ci, w którą stronę poszłaby odpowiedź.
Zapisz numer tabeli, regułę źródła i wyjątek w samym profilu. Wszystkie trzy należą do jednego projektu i będą edytowane razem.