Tunel działa, zapora ogniowa zezwala na port 53, AdGuard Home jest uruchomiony, a nazwy wciąż nie są rozwiązywane dla klienta WireGuard. Zapytanie normalnie dociera, a odpowiedź normalnie wychodzi, więc liczniki pakietów na resolverze wyglądają zdrowo, a usługa wydaje się niewinna. Co idzie nie tak, to adres źródłowy tej odpowiedzi: wychodzi z lokalnego adresu, o który klient nigdy nie pytał, i niegościnny resolver stuba klienta ją odrzuca. Jedna lista w konfiguracji AdGuard Home decyduje o tym, a jej zwykłe ustawienie domyślne przekazuje decyzję jądru.

Zapytanie dociera, odpowiedź wychodzi skądś indziej

Klient skonfigurowany z 10.6.0.1 jako swoim serwerem rozwiązywania wysyła zapytanie UDP do 10.6.0.1 port 53. Ten pakiet przechodzi przez tunel i trafia na hosta, a AdGuard Home udziela odpowiedzi. Na sieci jednak odpowiedź jest nowym pakietem, którego adres źródłowy jest wybierany przez stos hosta, a nie zgodnie z oczekiwaniami klienta.

Gdy resolver klienta jest gniazdem połączonym, co jest używane przez systemd-resolved, dnsmasq i większość stub resolverów, akceptuje tylko odpowiedzi z dokładnie tego adresu, na który wysłał zapytanie. Odpowiedź pochodząca z 192.168.1.10 do zapytania wysłanego do 10.6.0.1 zostaje odrzucona zanim nastąpi jakiekolwiek parsowanie. Resolver loguje poprawną odpowiedź, klient loguje upłynięcie czasu oczekiwania, i obie informacje są prawdziwe.

Tak więc liczniki nie kłamią, a klient też nie. Dowody, których potrzebujesz, znajdują się w trzech miejscach, w tej kolejności: adres, do którego przywiązany jest odbiorca, trasa, którą jądro użyłoby do powrotu do klienta, oraz adres źródłowy w rzeczywistej pakiecie odpowiedzi.

Jak jądro wybiera źródło odpowiedzi

Gniazdo UDP przypisane do0.0.0.0nie ma własnego adresu źródłowego, więc każda wychodząca odpowiedź wywołuje wyszukiwanie trasy do celu. Następnie jądro pobiera źródło z tej trasy: adres przypisany przez trasę lub podstawowy adres wychodzącego interfejsu. Nic z adresu docelowego zapytania nie jest zapamiętywane.

Na hoście z jednym interfejsem jest to niewidoczne, ponieważ istnieje tylko jedna prawdopodobna odpowiedź. Na maszynie posiadającej adres LAN, adres WireGuard i adres zarządzania, kilka odpowiedzi jest prawdopodobnych, a zwycięzca zależy od tabeli routingu w danym momencie. Dodaj dodatkową trasę, drugi adres na tym samym interfejsie, przekierowanie NAT przed resolverem lub uruchom AdGuard w kontenerze z własną przestrzenią nazw, a wybrane źródło może się różnić od tego, które zapytuje klient.

ss -lunp | grep :53pokazuje, w jakiej grze jesteś. Słuchacz na0.0.0.0:53jest przypadkiem uniwersalnym; słuchacz na10.6.0.1:53już przypiął odpowiedź. Odczyt gniazda jest szybszy niż odczyt YAML i odzwierciedla to, co faktycznie działa, a nie to, co było ostatnio zapisane.

To, co rzeczywiście kontroluje bind_hosts

AdGuard Home.dns.bind_hoststo lista lokalnych adresów, których używa nasłuchujący DNS. Domyślnie jest ustawiony znak wieloznaczny, co oznacza akceptację na każdym lokalnym adresie i pozwolenie jądru na wybór źródła dla każdej odpowiedzi. Zastąpienie znaku wieloznacznego adresem, którego używają klienci, zmienia gniazdo i wraz z nim adres źródłowy w każdej odpowiedzi.

Lista może zawierać więcej niż jeden wpis, co ma znaczenie w przypadku resolvera obsługującego dwie sieci. Wpisanie10.6.0.1i192.168.1.10daje dwa związane gniazda, a zapytanie przychodzące na którekolwiek z nich jest odpowiadane z adresu, na który przyszło. To jest zachowanie, które większość osób zakłada, że znak wieloznaczny już zapewnia.

YAML jest prosty, a adres w nim jest tym, którego twoi klienci tunelu mieli używać, a nie głównym adresem hosta:

dns:
  bind_hosts:
    - 10.6.0.1
  port: 53

Dlaczego dwie instalacje jednego resolvera się nie zgadzają

W tym kontekście zarządzanie przez wtyczkę oznacza, że resolver został zainstalowany i jest nadzorowany przez inny pakiet: pakiet oprogramowania routera, pakiet NAS lub dodatek do automatyki domowej. Taki pakiet zwykle dostarcza własną kopię YAML AdGuard Home i ponownie uruchamia proces według własnego harmonogramu, podczas gdy samodzielna instancja to binarka lub kontener dostawcy, który konfigurujesz samodzielnie. W każdym przypadku mamy do czynienia z dwoma niezależnymi procesami z oddzielnymi plikami konfiguracyjnymi i oddzielnymi wyborami powiązań, nawet jeśli oba odczytują tę samą listę upstream i te same listy filtrów. Jeden może powiązać konkretny adres tunelu, podczas gdy drugi dziedziczy wildcard, a interfejs webowy wygląda identycznie po obu stronach.

Dlatego „ten sam resolver działał przed migracją” nic nie dowodzi na temat obecnego powiązania. Sprawdź gniazdo, a następnie sprawdź plik konfiguracyjny, który faktycznie załadował działający proces. Nieaktualna kopia w innym katalogu jest częstym powodem, dla którego edycja wydaje się nie mieć efektu.

Przypnij to, a następnie przetestuj od strony tunelu

Zmieńbind_hostsna adres tunelu, uruchom ponownie usługę i potwierdź, że gniazdo się przeniosło:ss -lunp | grep :53powinno teraz pokazać10.6.0.1:53i żadnego wpisu wieloznacznego. Jeśli nadal pokazuje0.0.0.0,działający proces nie czyta pliku, który edytowałeś.

Następnie przetestuj od strony klienta, ponieważ to jest jedyna strona, która ma znaczenie. Zapytanie zdig @10.6.0.1 example.comwykorzystuje ścieżkę, którą użytkownik wykorzystuje, a przechwycenie na hoście ztcpdump -ni wg0 udp port 53pokazuje adres źródłowy odpowiedzi w sieci. Porównaj go z adresem w ustawieniach resolvera klienta; gdy są równe, limit czasu przestaje być tajemnicą.

ip route get 10.6.0.2wyjaśnia wszelkie pozostałe dziwności, ponieważ drukuje interfejs i źródło, które host użyłby, aby wysłać odpowiedź do klienta. Jeśli w tym wyjściu pojawi się interfejs LAN, zmiana powiązania nie jest pełną naprawą, a tablica routingu jest kolejną rzeczą do sprawdzenia.

Czego ustawienie powiązania nie może naprawić

Przypięcie nasłuchiwacza nie naprawia listy dostępu, która pomija podsieć tunelu, reguły firewalla, która zezwala na zapytanie, ale nie na odpowiedź, ani brakującej trasy powrotnej do puli WireGuard. Te problemy pojawiają się wcześniej lub później niż adres źródłowy i każdy ma innego właściciela.

Nie zmienia takżedo którego nadrzędnego serwera resolver przekazuje zapytania, czy ochrona przed ponownym wiązaniem odrzuca prywatną odpowiedź dla prywatnej nazwy, lub jak klient stosuje własne domeny wyszukiwania. To są osobne mechanizmy kontrolne. Zmień adres bindowania, gdy źródło odpowiedzi jest błędne, i zmień coś innego, gdy nim nie jest.

Powiązane artykuły