Чаму resolv.conf паказвае DNS вашага VPN, а запыты яго ігнаруюць
На хосте з resolved файл — гэта прадстаўленне, а не сам стан. Прасачыце за stub, серверамі кожнага злучэння і радком nsswitch, каб убачыць, што менавіта выкарыстоўвае запыт.
У журналах нічога не выглядае няправільным: інтэрфейс узняты, рэзалвер паведамляе DNS-сервер VPN, і файл на дыску змяшчае яго. Тым не менш унутранае імя хоста ўсё яшчэ вырашаецца праз лакальны маршрутызатар. Гэтыя тры сцверджанні не супярэчаць адно аднаму, бо файл, стан кожнага злучэння і шлях запыту — розныя аб'екты, якія проста маюць адно імя. Далей апісаны шлях, які запыт фактычна праходзіць на хосте з systemd-resolved.
Тры аб'екты з назвай resolv.conf
На хосте з resolved /etc/resolv.conf звычайна з'яўляецца сімвалічнай спасылкай на /run/systemd/resolve/stub-resolv.conf. Гэтая мэта ўтрымлівае адрас лакальнага stub-слухача, 127.0.0.53, а таксама дамены пошуку, разлічаныя resolved. Гэта прадстаўленне стану, а не сам стан.
Стан жыве ў канфігурацыі resolved для кожнага злучэння, і таму resolvectl status можа разыходзіцца з файлам і пры гэтым быць правільным. Кожнае злучэнне нясе свае серверы і свае дамены маршрутызацыі, а stub звяртаецца да гэтых даных, калі прыходзіць запыт. Даведнік па systemd-resolved апісвае згенераваныя файлы і мадэль кожнага злучэння; падзел паміж прадстаўленнем і станам — гэта тое, што варта запомніць. Змяненне мэты сімвалічнай спасылкі змяняе тое, што чытаюць традыцыйныя кліенты, а не тое, што ведае рэзалвер.
Трэці аб'ект, /run/systemd/resolve/resolv.conf, згортвае кожнае злучэнне ў адзін спіс сервераў. Праграма, накіраваная на гэты файл, адпраўляе запыты проста на пералічаныя серверы і абыходзіць stub, таму палітыка кожнага злучэння на яе ўжо не дзейнічае. Такім чынам, дзве праграмы на адной машыне могуць адказваць на адно імя па-рознаму, і ні адна з іх не зламаная.
Прасочыце адзін запыт праз NSS
glibc чытае /etc/nsswitch.conf, каб вырашыць, хто адказвае на імя. Радок hosts, які змяшчае resolve, накіроўвае пытанне ў nss-resolve, які запытвае resolved праз D-Bus і атрымлівае адказ для кожнага злучэння. Радок толькі з files dns адпраўляе запыт на той адрас, які ўтрымлівае /etc/resolv.conf.
Гэты адзін радок тлумачыць большасць разыходжанняў паміж браўзерам і dig. dig чытае resolv.conf напрамую і ніколі не звяртаецца да NSS, таму правярае stub ці вышэйстаячы сервер, а не шлях, які выкарыстоўвае праграма. getent hosts internal.example ідзе праз NSS, і параўнанне яго адказу з адказам dig — першае карыснае вымярэнне.
Праграмы, якія ўбудоўваюць уласны рэзалвер або гавораць DNS праз HTTPS з фіксаванай канчатковай кропкай, абыходзяць абодва шляхі. Нішто ў resolv.conf або ў стане resolved іх не абмяжоўвае.
Праверце, хто валодае файлам і куды ён паказвае
Прачытайце ланцуг спасылак, перш чым нешта змяняць, бо менавіта ўладальнік вызначае, які файл галоўны. Кожная каманда ніжэй толькі чытае стан.
stat -c '%N' /etc/resolv.conf
resolvectl status --no-pager
grep '^hosts' /etc/nsswitch.conf
ls -l /run/systemd/resolve/
Першы радок друкуе спасылку і яе мэту разам, а звычайны файл, якім валодае VPN-скрыпт, азначае, што рэзалвер ніколі не лічыць гэты запіс уваходам. Вывад стану пералічвае серверы кожнага злучэння плюс дамены маршрутызацыі, якія вызначаюць, куды ідзе кожны запыт. Радок nsswitch кажа, ці звяртаюцца да stub наогул, таму адрас stub у файле без resolve азначае, што запыты дасягаюць лакальнага слухача, пакуль нішто не кіруе падзелам. Апошні спіс таксама важны, бо хост без stub-resolv.conf не запускае апісаную тут схему.
Калі ланцуг сканчаецца файлам, якім кіруе іншы пакет, VPN-кліент і гэты пакет — два ўладальнікі, якіх трэба ўзгадніць. Замена спасылкі адкідае працу аднаго ўладальніка і пакідае працу другога на месцы.
Рамонт ва ўладальніка спасылкі
VPN-злучэнне павінна рэгістраваць свае серверы і свае дамены на сваім злучэнні, а затым здымаць іх пры адключэнні. Інтэграцыя resolved у NetworkManager і ўласны памочнік кліента працуюць менавіта так; скрыпт, які толькі перапісвае resolv.conf, — не.
На ўжо існым злучэнні механізм паказваюць налады часу выканання. resolvectl dns tun0 10.40.0.53 далучае сервер, а resolvectl domain tun0 '~corp.example' далучае дамен маршрутызацыі. Тыльда — гэта нясучая літара: яна абмяжоўвае запыты для гэтага суфікса гэтым злучэннем і пакідае ўсё астатняе ў спакоі, а тое ж значэнне без яе становіцца даменам пошуку, і падзел знікае. Гэтыя адрасы — лабараторныя прыклады, а не пастаянная канфігурацыя. Пацвердзіце з resolvectl query host.corp.example і прачытайце, якое злучэнне адказала.
Зарэгістраваны сервер усё яшчэ патрабуе маршруту. Калі запыт дасягае патрэбнага злучэння і сканчаецца тайм-аўтам, праблема ў дасягальнасці праз тунэль, а не ва ўладанні рэзалверам.
Як выглядае працоўны стан
Здаровы вынік узгоднены ва ўсіх трох прадстаўленнях: серверы кожнага злучэння супадаюць з тым, што выдаў VPN, дамены маршрутызацыі ахопліваюць толькі ўнутраныя суфіксы, а важная праграма вырашае ўнутранае імя, тады як публічнае імя па-ранейшаму ідзе лакальным шляхам. Адзін паспяховы запыт даказвае менш, чым гэтая ўзгодненасць.
Затым адключыцеся і паўтарыце абодва запыты. Кліент, які пакідае свае дамены зарэгістраванымі пасля разрыву, стварае машыну, якая праз гадзіны не можа вырашыць унутраныя імёны, без адкрытага тунэлю і без відавочнай прычыны.