Проследите запрос DNS шаг за шагом, чтобы найти настоящий источник
Навязанный адрес резолвера не определяет, какой источник увидит резолвер. Проследите клиента, форвардер и принимающий сервер, а затем запишите путь.
Если выдать клиенту адрес резолвера, это определяет, куда уходят запросы, а не какой источник увидит резолвер. Маршрутизация, пересылка и трансляция получают свой черёд между двумя концами. Методичка по вопросам источника сопровождает запрос шаг за шагом и фиксирует, что на самом деле видел каждый наблюдатель. Порядок важен, потому что утверждение, сделанное до наблюдения, — лишь догадка в лучшем оформлении.
Запишите схему до того, как собирать доказательства
Четыре места могут сообщить что-то об источнике DNS, и не все говорят одно и то же. Ядро клиента знает, какой источник оно использовало бы, форвардер знает, что отправил вверх, транслирующее устройство знает, что переписало, а принимающий резолвер знает, что пришло. Запишите, до каких из них вы действительно можете добраться, прежде чем что-либо собирать.
| Observation point | What it can prove | What it cannot prove | How to read it |
|---|---|---|---|
| client kernel | which source address it would use for that resolver | anything a device in between rewrote | ip route get against the resolver address |
| forwarder | that it sent an upstream query, and from which source | what the client originally asked for | its own log and its cache state |
| translating device | that a source was rewritten, and to what | whether the query was legitimate | NAT policy and its counters |
| receiving resolver | the address that actually arrived | which client behind that address asked | a scoped capture on port 53 |
Запишите и своё ожидание, включая резолвер, который, по вашему мнению, используется. Раздельный маршрут может отправить запрос совсем в другое место, а кэш может ответить вообще без обмена вверх, поэтому предположение, хранимое только в памяти, не переживёт первого сюрприза. Держите заявленную схему и наблюдаемый путь в отдельных столбцах одной и той же заметки; когда они расходятся, вы нашли вопрос, за которым стоит проследить.
Проверьте, какой процесс на самом деле отправил запрос
Начните с клиента: запишите адрес резолвера, имя запроса и время, затем подтвердите, какой процесс его отправил. Первая строка ниже называет процесс, держащий сокет UDP, и это та проверка, которую обещает заголовок. Если этот процесс — помощник браузера или среда выполнения контейнера, а не системный резолвер, остаток трассы описывает путь, о котором никто не просил.
ss -tunp 'dport = :53'
dig @10.20.30.53 host.corp.example +noall +answer
ip route get 10.20.30.53
На хосте с несколькими интерфейсами сначала выясните, какой адрес источника ядро выберет для этого назначения, прежде чем смотреть куда-либо ещё. Это последняя точка, где путь полностью под вашим контролем, и это значение, которое вы сравните с тем, что сообщает резолвер. Расхождение — сигнал, что что-то между ними переписало пакет или что были отправлены два разных запроса.
Держите тестовые имена внутренними, потому что внутреннее имя, отправленное публичному резолверу, ничего не доказывает о внутреннем пути и публикует имя, которое вам не нужно было публиковать. Браузер с включённым защищённым DNS вообще не появится в этом списке сокетов, и само это отсутствие и есть ответ.
Форвардер делает второй, отдельный запрос
Форвардер превращает один обмен в два. Запрос снизу приходит, и затем форвардер отправляет свой собственный запрос вверх с выбранного им адреса. Его конфигурация, а не клиент, определяет, что видит верхний резолвер.
Руководство dnsmasq стоит прочитать именно поэтому: в нём описано, как форвардер выбирает серверы вверх и привязывает свою сторону прослушивания, и ничто в этой схеме не передаёт источник клиента вверх. Поэтому журнал резолвера с адресом шлюза — это норма, а не доказательство сбоя. Отсутствие так же легко прочитать неправильно, потому что попадание в кэш не создаёт никакого запроса вверх и выглядит точно так же, как запрос, который так и не пришёл. Прочитайте конфигурацию форвардера и состояние его кэша, прежде чем делать любой из двух выводов. Два вопроса, два места, куда смотреть.
Прочитайте источник на принимающем резолвере
Единственное наблюдение, которое это решает, делается на стороне сервера. Всё, что выведено из списка интерфейсов клиента, остаётся гипотезой, пока резолвер не сообщит, что действительно пришло.
tcpdump -ni any port 53 and host 10.20.30.53
Снимайте на хосте резолвера, держите захват коротким и ограниченным и храните его там, где позволяет политика. Если наблюдаемый источник — транслированный адрес, следующий вопрос: какое устройство выполнило трансляцию и является ли его политика той самой. Захват отвечает, что пришло; он не объясняет, почему политика это разрешила. Назовите наблюдателя и шаг в заметке, потому что утверждение о приватности в отношении шлюза относится к этому шагу, а не ко всему пути.
Запишите находку как путь, а не как адрес
Запишите клиента, резолвер, любой форвардер, наблюдаемый источник на каждом шаге и политику, которая им управляет. Такая запись отвечает на большинство будущих вопросов без нового захвата. Нарисуйте её как цепочку, потому что список адресов скрывает, какой шаг дал какой.
Приложите к схеме дату, версию клиента и ревизию конфигурации, чтобы поздний читатель мог сказать, действует ли она ещё. Отделите транспортный источник от всего остального, что обрабатывает служба, потому что вид адреса шлюза ничего не говорит о том, что ещё хранится. Местоположение резолвера тоже ничего не говорит о том, какой клиент спрашивал. Именно разделение этих утверждений делает вывод защитимым на проверке.