Pull to refresh

Comments 21

Осталось добавить кэширование DNS записей.

Чтобы вычитать из пакета TTL записи надо будет разбирать пакеты а это уже не так просто. А топорный кэш который будет хранить все записи определённое время добавить легко. Я просто отрезал от запроса и ответа ID и помещал в кэш. И если приходил идентичный запрос я возвращал ответ из кэша.


Это основа а дальше с ней можно играться. Можно фильтры например сделать. Или к двум DNS слать запросы.

А вот это — не надо. С кэшированием это уже был бы недо-DNS сервер.
Кэшированием DNS записей занимается OS
Теперь наши DNS запросы под зашитой TLS.
Нет, не под защитой. В предложенном конфиге stunnel нет проверки сертификата.

По коду — ну такое. Нужно запускать два демона. Почему бы не обойтись тогда просто одним, который сам TLS-коннект в апстрим-резолвер открывает? Как оно будет работать в случаях, когда DNS-ответ не умещается в одну UDP-датаграмму?

И для чего тратить на это время на эту крайне спорную реализацию, если есть unbound и knot, которые поддерживают DoT нативно?

Помимо этого, есть куча готовых стабов для DoH/DoT:
(DoH) doh-proxy от Facebook
(DoT) stubby от GetDNS
(DoH) cloudflared от Cloudflare
Нет, не под защитой. В предложенном конфиге stunnel нет проверки сертификата.

Поправил. Теперь проверяет сертификат.


Почему бы не обойтись тогда просто одним, который сам TLS-коннект в апстрим-резолвер открывает?

TLS на Lua я не умею делать. А stunnel полагаю DNS не знает. Мне было интересно решить задачу тем что есть.


Как оно будет работать в случаях, когда DNS-ответ не умещается в одну UDP-датаграмму?

Полагаю её просто отбросит. Надо тестировать. Но там не большая разница между максимальным размером TCP DNS пакета (65535 байт) и максимальной UDP-датаграммой (65507 байт). Программа также может обратится и по TCP каналу напрямую в туннель если рассчитывает получить большой ответ.


И для чего тратить на это время на эту крайне спорную реализацию, если есть unbound и knot, которые поддерживают DoT нативно?

Не знаю. Каждый сам решит для себя.

Но там не большая разница между максимальным размером TCP DNS пакета (65535 байт) и максимальной UDP-датаграммой (65507 байт).

Есть лимит 512 байт на размер DNS-ответа. Обсуждение на SO о причинах.

Там промежуточный серт получается по сути захардкожен — это не круто и он протухнет через 3 года. Лучше использовать системный набор сертификатов.
[dns]
client = yes
accept = 127.0.0.1:53
connect = 8.8.8.8:853
CApath = /usr/lib/ssl/certs
verifyChain = yes
checkIP = 8.8.8.8


verify — устаревшая опция, ей лучше не пользоваться.

Далее, как я вижу, для маршрутизации ответов используется только ID запроса, который каждый клиент выбирает случайно. Нормальные резолверы так не делают, так как велика вероятность коллизии. Они ещё помнят с какого адреса-порта что запрашивалось, а ID ответа в основном проверяют для защиты от DNS-отравлений. По моим подсчётам по формуле для парадокса дней рождения, вероятность совпадения ID хотя бы у двух запросов в группе из 100 запросов составляет 7,3%. Довольно скверно, согласитесь.

Не знаю. Каждый сам решит для себя.

Ну, пока не выглядит даже как добрый совет.
Есть лимит 512 байт на размер DNS-ответа.

У меня UDP пакеты не уходят дальше локальной машины. Проверил лимиты. Нормально уходят и приходят пакеты до 8192 байт. Дальше только отправка работает а на приёме ошибка что слишком большой пакет.


Предлагаете ограничить?


Потом если предполагается большой ответ обычно используется TCP а он также доступен напрямую через Stunnel.


Лучше использовать системный набор сертификатов.

Только вот они похоже реестре лежат на Windows.


Далее, как я вижу, для маршрутизации ответов используется только ID запроса

Да. Я не придумал как не разбирая пакета без сложностей использовать больше иформации. Можно конечно попробовать написать лёгкую фунцию парсинга запросов.


Но опять же мы на локальной машине. Запросов от неё не так много.

Предлагаете ограничить?

Протокол DNS предусматривает передачу длинных ответов через TCP, вероятнее всего нужно ещё реализовать TCP-слушатель для них.
Да. Я не придумал как не разбирая пакета без сложностей использовать больше иформации. Можно конечно попробовать написать лёгкую фунцию парсинга запросов.
Качественная реализация какого-либо DNS-сервера требует много работы, которая уже была сделана.

Я скриптом как раз решал проблему того что Stunnel UDP не понимает. А в начале статьи я как раз отправляю тестовый TCP запрос через Stunnel напрямую.


nslookup -vc ya.ru 127.0.0.1


Опция vc заставляет nslookup использовать TCP соединение к DNS серверу вместо UDP.
для маршрутизации ответов используется только ID запроса

Поправил. Теперь не только ID сравниваются но и query часть.

Есть лимит 512 байт на размер DNS-ответа.

Почитайте на досуге про EDNS0. И это всего лишь лимит для UDP…
Можно для чайников — тех кто с трудом отличает Domain Name System от Direct Numerical Simulation — что это дает обычным людям?
Хотя бы в виде абзаца-абстракта. А то уж очень специфично/терминологично.
DNS (англ. Domain Name System — система доменных имён) — компьютерная распределённая система для получения информации о доменах. Чаще всего используется для получения IP-адреса по имени хоста (компьютера или устройства)

Сейчас все DNS запросы идут открытым текстом и провайдеры могут их читать и подменять в целях блокирования доступа или рекламы.


Скрипт в сочетании со Stunnel отправляет все приходящие на него DNS запросы через шифрованный канал напрямую к Google DNS. Тем самым провайдер не может прочитать или подменить ответы DNS сервера.


При сочетании DNS over TLS с Encrypted SNI провайдер перестанет понимать на какие сайты ходит пользователь. Всё что ему будет видно это только IP адреса на которые обращается пользователь.

Спасибо! Ага, т.е. вообще такое надо ставить — а то вдруг мало ли что… Зайду куда-нибудь, где ругают не того кого можно и станет одним хабраюзером меньше.
Пару дней назад Mozilla объявила о поддержке Encrypted SNI. blog.mozilla.org/security/2018/10/18/encrypted-sni-comes-to-firefox-nightly

По их заявлению включение этой опции одновременно с DNS over HTTPS приведет к большей анонимности
провайдер перестанет понимать на какие сайты ходит пользователь
. Кто-то сразу заявил, что вот оно средство против блокировок. Но у моего провайдера так и не заработало. Выяснилось, что Encrypted SNI он понимает как отсутствие SNI и режет такие пакеты. Вот обсуждение: github.com/ValdikSS/GoodbyeDPI/issues/71

Не знаю как насчет DNS over TLS в сочетании с Encrypted SNI
DNS отвечает, например, за доступность веб-контента по URL. (Не)добросовестные провайдеры выполняют требования, например, РКН, и что-то блокируют. Для того, чтобы к этому заблокированному получить доступ, можно поднять, например, VPN. Но если VPN реализован туннелированием через абстракционно не низший чем DNS протокол, то DNS автоматически под туннелем не ходит (инкапсуляция почти как из ООП, возможно, с этим Вы больше знакомы, пример подменяемого DNS — VPN через SSH), и получается, что трафик хоть и идёт через другую точку света, но трансляции из доменного имени в IP всё равно от провайдера (тут есть пример, но в реальности подмена DNS — не самое зло, подробности тут, хотя и с большим злом можно справиться). А (не)добросовестные клиенты не желают, чтобы требования РКН выполнялись. Кто тут добросовестнее — выбирать Вам.
С точки зрения изучения интересно. Но если нужно ехать, а не шашечки, то просто ставим Unbound и радуемся =)
UFO just landed and posted this here

Недавно решил попробовать DOH и ESNI в Firefox 65. (Уже и в 65.0.1 попробовал)


network.security.esni.enabled = true
network.trr.mode = 3

Сделал запрос на cloudflare.com который использует TLS 1.3. И ничего не изменилось. DNS запросы попрежнему идут на дефолтный DNS сервер без шифрования. А WireShark показывает не шифрованный SNI.

Sign up to leave a comment.

Articles

Change theme settings