Участились случаи подмены нешифрованных udp:53 запросов. При этом tcp:53 обычно не трогается. Claude написал udp:53>tcp:53 локальный конвертер на Go для линукса. Предлагаю потестить.
dnsproxy.go (5,9 КБ)
dns-tcp-proxy: слушает DNS-запросы по UDP на локальном порту и
пересылает их upstream-серверу по TCP (DNS-over-TCP, RFC 7766).
Зачем: некоторые провайдеры подменяют/блокируют обычный
нешифрованный UDP:53, но не трогают TCP:53. glibc-резолвер сам
никогда не переключится на TCP, кроме случая truncated-ответа,
поэтому нужен локальный “переводчик” протокола.
Использование:
go build -o dns-tcp-proxy dnsproxy.go
sudo setcap 'cap_net_bind_service=+ep' ./dns-tcp-proxy
./dns-tcp-proxy -listen 127.0.0.1:53 -upstream 1.1.1.1:53
Затем указать 127.0.0.1 как DNS-сервер системы, например в /etc/resolv.conf.
Ещё пояснение от Claude:
Написал такой прокси на Go — с пулингом TCP-соединения и pipelining (не по одному хендшейку на запрос, а один живой TCP-коннекшен с ремаппингом ID для параллельных запросов):
Что внутри и почему так:
Как работает — прямое проксирование, без флага TC. Один живой TCP-коннекшен к upstream переиспользуется для всех запросов (pipelining, RFC 7766), с ремаппингом DNS ID, чтобы правильно раздать ответы обратно нужным UDP-клиентам. При обрыве TCP-соединения — автопереподключение. Всё это протестировал прямо здесь: 5 параллельных запросов с разными ID корректно размэтчились, а реконнект после убитого upstream-сервера тоже отработал сам.
Почему это лучше идеи с TC-флагом: не нужен лишний UDP-раунд-трип перед TCP, не зависит от того, правильно ли конкретное приложение обрабатывает truncation, и ответ может быть любого размера (loopback UDP не фрагментируется, в отличие от реального сетевого пути).
Из подводных камней — на большинстве дистрибутивов порт 127.0.0.53:53 уже занят systemd-resolved, так что в README расписал оба варианта: полностью его отключить, либо оставить и перенаправить его же upstream на прокси через resolved.conf.
И да, честно предупреждал в начале: если DPI провайдера начнёт мешать и голому TCP:53 (это сложнее, чем блайндовый UDP-спуфинг, но не невозможно) — этот инструмент не спасёт, там уже нужен DoT с TLS.
И если кто хочет systemd службу:
dns-tcp-proxy.service (474 байта)
Вроде, должно работать на винде. Там ничего unix специфичного. Могу собрать для win7.