DNS през VPN работи, но имената .local все още се провалят: кой ги разрешава?
Име .local може напълно да заобиколи DNS резолвера на вашия VPN. Сравнете трите пътя на резолвера и след това обявете домейна, вместо да пренареждате nsswitch.
Две машини в един и същ VPN, едно и също име на хост и само една от тях го разрешава: разликата обикновено не е в тунела, а в това кой резолвер е отговорил. На Linux десктоп това име може да мине през превключвателя на услугите за имена, през stub-а на systemd-resolved или през резолвер, който приложението е донесло със себе си, и всеки от тях прилага собствено правило към един и същ суфикс. Именно при суфикса правилата се разминават, защото .local не е неутрален етикет. Разберете кой път всъщност поема програмата, която се проваля, преди да промените реда, в който нещо се изпълнява.
Два резолвера, два различни отговора
Традиционното търсене през glibc минава по реда hosts: в nsswitch.conf и пита всеки модул на свой ред, докато някой отговори. Клиент, който говори със systemd-resolved през stub слушателя, вместо това пита един процес, а този процес прилага политика за всяка връзка плюс собствени специални случаи. Приложение, което носи собствен резолвер или свързва библиотека, която го прави, може да заобиколи и двете. Така едно име на хост може да има трима собственици на една машина и само един от тях знае какво е имал предвид VPN.
Определете собственика, преди да промените нещо, защото поправката е различна за всеки от трите. Браузър и инструмент за команден ред на един и същ десктоп могат законно да не са съгласни и това несъгласие е уликата, а не грешката. Ако браузърът разрешава името, а инструментът не, отстранявате проблем в пътя на резолвера, а не във VPN маршрута. Проверете маршрута отделно, за да не се сбърка повреда в маршрутизацията с повреда в услугата за имена. Когато и двамата са съгласни, повредата е над хоста и конфигурацията на резолвера тук не заслужава още една редакция.
Коя команда всъщност попита вашия резолвер
Две команди само за четене отговарят на свързани въпроси и сравняването им локализира проблема по-бързо от четенето на конфигурация. Използвайте истинско вътрешно име и пазете изхода поверителен, защото вътрешните записи си остават вътрешни. Изпълнете и двете в същата сесия, в която работи програмата, която се проваля:
getent ahosts files.corp.local
resolvectl query files.corp.local
resolvectl statusПървата пита през конфигурираните модули, което е това, което изпитва типичната програма. Втората пита systemd-resolved директно и съобщава връзката, протокола и сървъра, който е отговорил. Запитването на корпоративния сървър по адрес доказва само, че сървърът пази записа, защото не казва нищо за това дали приложението изобщо го е питало. Прочетете връзката, която носи VPN, и домейните, които тя заявява, след което сравнете този списък със суфикса в името, което се проваля.
Защо .local заобикаля вашата unicast зона
справката на systemd-resolved казва, че имената с няколко етикета, завършващи на .local, обикновено отиват към multicast DNS, когато mDNS е включен, а не към обикновения unicast DNS. RFC 6762 отделя това пространство от имена за link-local multicast, така че корпоративна зона може да пази правилен запис, който никога не се пита за този суфикс. Тунелът може да маршрутизира резолвера безупречно и пак да загуби състезанието. Успешен ping от кеш не казва нищо за търсенето, което току-що е станало.
Има документирано изключение и то решава повечето от тези случаи: когато връзка обяви този суфикс като домейн за търсене или домейн за маршрутизация, демонът го задържа на unicast пътя и пропуска специалния случай на multicast. Това е политика за всяка връзка, а не глобална предпочитаност. Две машини с един и същ VPN сървър могат да се държат различно, когато единият мрежов профил обявява домейна, а другият не, затова четете активния профил, а не този, който си спомняте, че сте редактирали.
Тясното изключение бие глобалното пренареждане
За съществуваща зона, която не можете да преименувате, накарайте собствениците на резолвера и на VPN да обявят домейна на връзката, която го носи. Запис за домейн на маршрутизация за този един суфикс плюс предвидения адрес на сървъра е малка промяна с посочен собственик и живее с връзката, а не във файл, редактиран на ръка.
Той оцелява и при прекъсване, защото политиката на връзката се прилага отново, когато връзката се върне. Редактирането на споделения nsswitch.conf е изкушаващата и по-скъпа алтернатива, защото променя поведението при търсене за всяко име на машината, включително локалното откриване. Изключването на multicast демона също не е равностойно: то премахва локалното поведение, без да научи който и да е резолвер за корпоративната зона. Ако услугата е нова, а не наследена, поставете я в поддомейн, който организацията ви контролира, и пропуснете състезанието напълно. Изберете тясното изключение, когато името е фиксирано във фърмуера или отпечатано на етикет, и изберете нов поддомейн, когато все още контролирате клиента.
Какво да докажете след промяната
Докажете поправката със собственото търсене на приложението, а не с инструмент, който сте инсталирали за тестване, и изчистете всеки кеш, който би могъл да отговори вместо него. След това потвърдете пътя на резолвера и връзката, която е дала отговора. Накрая проверете, че локалното откриване се държи както преди промяната, защото принтерът, който спира да се появява, е частта, която хората забелязват последна. Тези три команди проверяват името, пътя и самоличността по TLS в този ред:
getent ahosts files.corp.local
resolvectl query files.corp.local
curl -sv --max-time 5 https://files.corp.local/ 2>&1 | head -n 20Правилен адрес с грешен сертификат все още се проваля при строг клиент, затова проверете името, което приложението очаква, след като разрешаването проработи. Потвърдете, че услугата приема връзки от VPN адреса, а не само от офис диапазона. Запишете обхвата на домейна, сървъра и собственика в документацията на връзката. Иначе следващият човек, който срещне този проблем, посяга към същата глобална редакция, която току-що избегнахте.