Edytowanie resolv.conf nie naprawia DNS po rozłączeniu VPN
Martwy resolver tunelu na górze listy kosztuje jeden limit czasu na każde zapytanie. Sprawdź, kto jest właścicielem pliku, zresetuj stan łącza i przestań edytować wygenerowane dane wyjściowe.
Rozłączasz VPN, ping 1.1.1.1 nadal odpowiada, a każde zapytanie o nazwę wisi, zanim strona w końcu się podda. Wtedy cat /etc/resolv.conf pokazuje serwer nazw, który kiedykolwiek istniał tylko wewnątrz tunelu, zwykle pierwszy na liście. Usunięcie tej linii wygląda na naprawę na około dziesięć minut, dopóki uśpienie, roaming Wi-Fi albo restart nie przywrócą jej z powrotem. Edytowany plik nie jest ustawieniem; to odwzorowanie stanu łącza, którego właścicielem jest inny komponent.
Dlaczego jeden nieaktualny wpis kosztuje sekundy na każde zapytanie
Resolver glibc przechodzi listę serwerów nazw po kolei i odczekuje limit czasu, zanim spróbuje następnego, a resolv.conf(5) ogranicza tę listę do trzech wpisów. Umieść resolver po stronie tunelu, na przykład 10.8.0.1, na górze po zniknięciu tunelu, a każde zapytanie zapłaci limitem czasu, zanim przejdzie do serwera, który odpowiada. Dlatego objaw wygląda jak martwe połączenie, a nie błąd DNS: przeglądarki blokują, kończy się czas i czasami podają adres z pamięci podręcznej, który później staje się nieaktualny.
To wyjaśnia też, dlaczego skarga przychodzi jako „internet jest zepsuty”. Ping do adresu IP dowodzi, że łącze jest w porządku, co sprawia, że usterka wygląda na winę aplikacji. Lista resolverów to pierwsza rzecz do przeczytania i ostatnia do edytowania.
Mit: resolv.conf to plik ustawień
Zapytaj, czym ta ścieżka naprawdę jest, zanim ją zmienisz:
ls -l /etc/resolv.conf
readlink -f /etc/resolv.conf
Na hoście z systemd-resolved to dowiązanie symboliczne do pliku stub wskazującego na 127.0.0.53, a prawdziwe serwery żyją w stanie dla każdego łącza, który wypisuje resolvectl. Na hoście z NetworkManager to może być plik, który NetworkManager zapisuje z aktywnego połączenia. U niektórych klientów dostawców to zwykły plik przepisywany na miejscu przy połączeniu i, jeśli nie masz szczęścia, nigdy nieprzywracany przy rozłączeniu. To trzej różni właściciele, a ręczna edycja pierwszych dwóch albo nic nie daje, albo utrzymuje się do następnego zdarzenia sieciowego.
resolvectl status to widok, który mówi prawdę: serwery DNS dla każdego łącza, domeny routingu i to, czy łącze tunelu nadal istnieje. resolvectl query example.com idzie dalej i pokazuje, który interfejs odpowiedział. Użyj obu, zanim dotkniesz pliku, i pamiętaj, że przeglądarka z własnym bezpiecznym DNS ignoruje to wszystko.
Znajdź właściciela, zanim cokolwiek edytujesz
Zwykle trzy komponenty rywalizują o to samo ustawienie: systemd-resolved, NetworkManager i to, co zainstalował klient VPN. Najpierw zidentyfikuj żywy:
systemctl is-active systemd-resolved
nmcli connection show --active
ps aux | grep -E "openvpn|wg-quick|vpn"
Jeśli resolved jest aktywny, a dowiązanie symboliczne wskazuje jego stub, plik globalny jest wygenerowanym wyjściem, a twoja edycja jest kosmetyczna. Jeśli połączenie należy do NetworkManager, serwery należą do profilu połączenia, więc naprawą jest zmiana właściwości przez nmcli, a nie edycja pliku. Jeśli działa demon dostawcy, tylko jego własna ścieżka przywracania przetrwa następne połączenie.
Posprzątaj stan łącza pozostawiony przez klienta
Zabity klient nie może uruchomić swojego haka czyszczącego. SIGKILL nie da się przechwycić w ogóle, a SIGINT i SIGTERM można, więc tunel, który „po prostu się zatrzymał” po wymuszonym zabiciu, często zostawia na miejscu zarówno rejestrację interfejsu, jak i wpis resolvera. Znajdź konkretny PID i wyślij sygnał tylko do niego:
ps aux | grep -E "openvpn|wg-quick"
sudo kill <pid>
resolvectl revert tun0
Nie sięgaj po pkill -f vpn ani killall vpn, zanim nie przeczytasz całej listy dopasowań. -f dopasowuje cały wiersz poleceń, więc może zakończyć skrypt opakowujący, sesję edytora albo niezwiązany proces, którego ścieżka zawiera ten ciąg. Zakończenie niewłaściwego procesu w środku pracy to sposób, w jaki problem resolvera staje się utraconym plikiem.
resolvectl revert resetuje konfigurację DNS w czasie działania tego łącza, co jest węższe niż restart resolvera i znacznie węższe niż edycja pliku globalnego. Jeśli łącze tunelu zniknęło całkowicie, systemctl restart NetworkManager odbudowuje stan połączenia i to jest krok, do którego wątki źródłowe ciągle wracają. Uważaj na menedżera usług z Restart=always, bo potrafi przywrócić zabitego klienta i jego ustawienia DNS od razu z powrotem.
Drugi kierunek: wypchnięty DNS, który nigdy nie dotarł
Lustrzanym odbiciem nieaktualnego wpisu jest tunel bez żadnego użytecznego resolvera. Opcja DNS w profilu to prośba; komponent zarządzający połączeniem musi przekazać ją resolverowi. Jeśli log pokazuje, że serwer został odebrany, ale łącze tunelu nie niesie żadnych ustawień DNS, brakuje integracji, a nie serwera.
Przetestuj przekazanie, wykonując je ręcznie, co oddziela „serwer jest zły” od „nikt tego nie zastosował”:
resolvectl dns tun0 10.10.10.10
resolvectl domain tun0 ~.
Domena routingu przechwytująca wszystko wysyła każdą nazwę na to łącze, czego chce klient pełnego tunelu i czego podzielony DNS nie może używać. Te ustawienia znikają przy następnym połączeniu. Aby były trwałe w NetworkManager, wyłącz automatyczny DNS, ustaw serwer na połączeniu i dodaj domenę:
nmcli connection modify office ipv4.ignore-auto-dns yes
nmcli connection modify office ipv4.dns 10.10.10.10
nmcli connection modify office ipv4.dns-search "~."
Dla tunelu firmowego, który powinien odpowiadać tylko na nazwy wewnętrzne, wymień te strefy z wiodącą tyldą zamiast przechwytywania wszystkiego, aby nazwy publiczne nadal korzystały z lokalnego resolvera.
Obejścia, które stają się następną awarią
Kopiowanie resolv.conf przed połączeniem i przywracanie go potem to uzasadniona linia w runbooku, i to obejście, a nie naprawa. Zawodzi dokładnie wtedy, gdy ma znaczenie, bo awaria albo wymuszony restart pomijają przywrócenie. Zapisz to jako obejście, żeby następna osoba na nim nie budowała.
Wyłączenie systemd-resolved i twarde wpisanie publicznych serwerów to drugi popularny ruch. Czyni połączenie i rozłączenie przewidywalnymi i usuwa DNS dla każdego łącza w każdym innym sieci, co psuje podzielony DNS dla nazw wewnętrznych i niweczy cel tunelu, który ma trzymać zapytania wewnątrz. Instalacja resolvconf i przypięcie publicznych serwerów kosztuje tyle samo z dodatkową warstwą. Traktuj każde z nich jako diagnostykę: jeśli przywraca przeglądanie, dowiedziałeś się, że winna jest integracja resolvera, a nie że publiczne serwery są poprawne.
Trwała naprawa to jeden właściciel na warstwę: zdecyduj, który komponent odpowiada za DNS łącza tunelu, a który za globalne ustawienie domyślne, zapisz to i usuń pozostałe ze ścieżki. Potem sprawdź po rozłączeniu nazwą, którą rozwiązuje tylko VPN. Jeśli prywatna nazwa nadal odpowiada, rejestracja nie została usunięta; jeśli nic się nie rozwiązuje, plik wskazuje serwer, który już nie istnieje. Oba są widoczne w resolvectl, zanim otworzysz przeglądarkę.