Dziennik pokazuje opcję wypchniętą przez serwer, tunel działa, a nazwy wewnętrzne nadal zawieszają się. Bezpośrednie zapytanie do resolvera odpowiada, więc serwer jest w porządku, ale każda aplikacja nadal pyta lokalny router. To, co dotarło do klienta, jest propozycją, nie zmianą w resolverze, a komponent odpowiedzialny za rozwiązywanie nazw różni się w Linux, Windows i macOS. Gdy oddzielisz opcję od jej właściciela, cztery usterki pokrywają niemal każde zgłoszenie: brak hooka, dwa konkurujące hooki, podzielony DNS działający zgodnie z projektem albo krótka nazwa, która potrzebuje sufiksu, a nie serwera.

Wypychana opcja to propozycja, nie instalacja

Na serwerze dwie dyrektywy opisują zamiar, a nie efekt:

push "dhcp-option DNS 10.8.0.1"
push "dhcp-option DOMAIN corp.example"

Klient nie otrzymuje skonfigurowanego resolvera. Otrzymuje zmienne środowiskowe, foreign_option_1 i kolejne, po jednej na każdą wypchniętą linię, a coś lokalnego musi je odczytać i przepisać stan resolvera systemu operacyjnego. W Linux nic tego domyślnie nie robi, dlatego poprawny serwer i połączony klient nadal mogą rozwiązywać nazwy przez LAN.

Między dwoma końcami są trzy etapy: wypchnięcie musi dotrzeć, klient musi je ujawnić, a hook musi je zastosować. Czytaj środkowy etap w dzienniku klienta, a ostatni w stanie resolvera, nigdy odwrotnie, bo jedna linia dziennika dowodzi tylko pierwszych dwóch.

Potwierdź, że wypchnięcie dotarło, i znajdź właściciela

Zacznij od nazwania startera: gołe openvpn polecenie, instancja systemd, NetworkManager albo klient dostawcy. To decyduje, gdzie może żyć hook. Na hoście z systemd-resolved, resolvectl status wylicza każde łącze z serwerami DNS i domenami wyszukiwania, których naprawdę używa, a łącze tunelu nie zawsze nazywa się tun0.

Jeśli wypchnięty adres jest w dzienniku, ale nie na żadnym łączu, brakuje integracji. Jeśli jest na łączu, a zapytania nadal wychodzą gdzie indziej, problemem jest które zapytania wybierają to łącze. NetworkManager dns=dnsmasq w pliku /etc/NetworkManager/NetworkManager.conf uruchamia lokalny przekazujący, który celowo stosuje podzielony DNS: nazwy w domenie VPN idą do resolvera VPN, reszta zachowuje poprzednią ścieżkę. Takie zachowanie wygląda jak usterka, gdy oczekiwałeś przeniesienia całego ruchu; sprawdź ustawienia dla połączenia przez nmcli connection show "My VPN", gdzie ipv4.dns i ipv4.dns-search przechowują wartości stojące za tym, co raportuje urządzenie, zanim nazwiesz to zepsutym. Jeśli każde zapytanie naprawdę ma docierać do resolvera VPN, usuń dns=dnsmasq z NetworkManager.conf i uruchom ponownie NetworkManager, co zwraca rozwiązywanie nazw ustawieniom połączenia; w przeciwnym razie zachowaj podzielony DNS i popraw wypchaną listę domen.

Linux: przekaż opcje resolverowi

Pakiety dystrybucji dostarczają do tego hook, a klientowi trzeba pozwolić go uruchomić. Typowy układ na hoście bez systemd-resolved:

script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

Z systemd-resolved starszy skrypt resolv.conf może nic istotnego nie zmienić, bo resolver stub trzyma stan dla każdego łącza. update-systemd-resolved pomocnik dokumentuje formę hooka, która używa up-restart i down-pre, co ma znaczenie, gdy interfejs przeżywa jedną próbę połączenia. Cokolwiek wybierzesz, stan musi posiadać jeden komponent. Dodanie niepowiązanego hooka obok NetworkManagera daje dwóch pisarzy do tego samego łącza, a wynik zależy wtedy od kolejności, a nie od twojej konfiguracji.

Jest też przypadek, w którym NetworkManager całkowicie ignorował wypchniętą opcję, dopóki adres serwera nie został wpisany w ustawieniach IPv4 połączenia, a potem stan resolvera pokazał, że jest używana. Warto spróbować przed przepisywaniem skryptów, bo przenosi to problem z hooka powłoki do profilu połączenia, który już niesie tunel.

Windows i macOS stosują różne części

Klient Windows rzeczywiście ustawia serwery DNS adaptera VPN, ale Windows nadal wybiera interfejs według metryki i nadal potrzebuje sufiksu, by rozwinąć krótką nazwę. Potwierdź stan adaptera, a nie profilu:

Get-DnsClientServerAddress -InterfaceAlias "My VPN"
Get-DnsClientNrptPolicy

Jeśli adresu brakuje, ustaw go przez Set-DnsClientServerAddress -InterfaceAlias "My VPN" -ServerAddresses 10.8.0.1, następnie dodaj sufiks do właściwości IPv4 adaptera, aby fileserver stał się fileserver.corp.example. Wartość SearchList dla całej maszyny pod Tcpip\Parameters robi to samo. Tam gdzie długa nazwa się rozwiązuje, a goła nie, resolver jest już poprawny i winna jest lista wyszukiwania. Poprawki po kolei: wypchnij DOMAIN aby klient poznał sufiks, dodaj ten sufiks do listy wyszukiwania adaptera lub połączenia, a jako środek tymczasowy przypnij nazwę w hosts, albo LMHOSTS w Windows; przeglądanie NetBIOS nie przechodzi przez router, więc rozgłoszenie, które znajduje krótką nazwę w biurowej LAN, nigdy nie dociera do klienta tunelu.

block-outside-dns block-outside-dns to zachowanie klienta Windows, a nie przenośna linia profilu, i skopiowanie jej do profilu Linux lub macOS nie odtworzy jej tam. Jeśli nazwy publiczne działają, a wewnętrzne zawodzą w Windows, porównaj kolejność adapterów w Ustawieniach zaawansowanych z ipconfig /all. W macOS kolejność resolverów dla usługi należy do systemu, więc użyj scutil --dns aby zobaczyć, który resolver jest pytany dla której domeny, i traktuj każdą pojedynczą zgłoszoną poprawkę profilu jako zależną od klienta, a nie ogólną.

Maszyna wirtualna na tym samym laptopie niczego z tego nie dziedziczy. Daj gościowi własny wpis resolvera dla domeny wewnętrznej albo pozwól NAT-owi hiperwizora przekazywać jego zapytania przez hosta, co jest poprawne tylko dopóki tunel hosta działa.

Historia jest trzecią przyczyną. Serwery DNS lub ustawienia sufiksu z wcześniejszego profilu mogą przetrwać ponowne połączenia, więc gdy adapter wygląda poprawnie, a wyszukiwania nadal zawodzą, porównaj żywy adapter z Get-VpnConnection i usuń lub nadpisz nieaktualny wpis, zanim dotkniesz serwera.

Udowodnij, gdzie poszło zapytanie

Przechwycenie podczas jednego wyszukiwania rozstrzyga spór: tcpdump -ni eth0 port 53 pokazuje zapytania na interfejsie fizycznym, co znaczy, że wychodzą poza tunel i resolver nigdy nie został przełączony. dig @10.8.0.1 name.corp.example potem rozdziela dwa pozostałe przypadki. Jeśli bezpośrednie zapytanie odpowiada, resolver działa i klient go nie używa; jeśli kończy się przekroczeniem czasu, resolver jest nieosiągalny przez tunel i żadna lokalna zmiana nie pomoże.

Jeśli używany resolver to ten rozdany przez dostawcę, tunel szyfruje ruch, ale nazwy pozostają widoczne dla tego dostawcy. To kwestia wycieku, a nie działania, i to samo przechwycenie na nią odpowiada: zapytanie na interfejsie fizycznym idzie do kogoś poza tunelem.

Osiągalność obejmuje zaporę na hoście VPN, która musi zezwalać na UDP i TCP 53 z puli. Zamknięty port wygląda dokładnie jak zepsute wypchnięcie, podobnie resolver, który odpowiada tylko od wewnątrz sieci tunelu. Powtórz przechwycenie po jednym rozłączeniu i ponownym połączeniu, bo ustawienia, które pojawiają się przy pierwszym połączeniu i znikają przy drugim, to usterka cyklu życia hooka, a nie brakująca opcja.

Utrzymaj jednego właściciela i weryfikuj po kolei

Skrypt, który przepisuje DNS adaptera na podstawie zgadywanego stanu tunelu, powiela konfigurację, którą profil już niesie, i zawodzi cicho, gdy założenie po raz pierwszy jest błędne. Preferuj własne ustawienia DNS połączenia albo jeden udokumentowany hook, i zapisz, który wybrałeś, żeby następna osoba nie dodała drugiego.

Zamknij pętlę czterema kontrolami: wypchnięty adres obecny na łączu tunelu, nazwa wewnętrzna rozwiązywana jako pełna nazwa kwalifikowana, ta sama nazwa rozwiązywana bez sufiksu, i oba nadal prawdziwe po jednym ponownym połączeniu. Jedno przechwycenie mówi, który z czterech zawiódł. Podręcznik OpenVPN 2.6 wymienia dhcp-option oraz dyrektywy skryptów wraz z ich uwagami o platformach.

Powiązane artykuły