Что происходит с DNS в России? Возможно, мы нашли признаки цензуры. Разбор #26

Нашли три аномалии, у всех разное поведение.
Что это за рубрика

В рубрике «Разбор Теплицы» мы в режиме реального времени разбираемся в определённой проблеме, новостях интернет-цензуры и рассказываем:

  • что происходит;
  • как это устроено;
  • как с этим можно бороться.

Что случилось?

В России что-то происходит с DNS (системой получения информации о доменах) — и происходит давно.

Например, 8 сентября 2021 года Роскомнадзор заблокировал у нескольких крупных операторов, с помощью ТСПУ (техсредства «противодействия угрозам»), на час с 21:00 до 22:00 публичные DNS 1.1.1.1 и 8.8.8.8, это задокументировали независимые специалисты. Через несколько дней «Ростелеком» разослал внутреннее предложение закрепить эту блокировку на постоянной основе. В октябре 2024 года Cloudflare включил по умолчанию расширение TLS ECH, скрывающее домен назначения (SNI) при установке соединения; с 5 ноября 2024 года зафиксирована блокировка TLS-сессий с этой сигнатурой не через TCP RST, а через тихий дроп пакета после ее обнаружения, что вынуждает браузер откатываться на обычное, открытое соединение.

Мы решили самостоятельно проверить, как работают разные DNS в России на разных ресурсах и какую роль в их ограничении играет ТСПУ.

Что мы решили измерить?

Узлы фильтрации

Для изоляции узлов фильтрации (ТСПУ) измерительная инфраструктура развернута на пяти независимых точках:

  • Эталонная нода (Испания, Residential ШПД).
  • Эталонная нода (Германия, магистральный уровень Tier-1).
  • Измерительные ноды внутри РФ (Москва и Санкт-Петербург, уровень дата-центров Tier-2/Tier-3).
  • Измерительная нода внутри РФ (Санкт-Петербург, уровень конечного ШПД-пользователя).

Домены

Сделали опрос резолверов по нескольким группам доменов.:

  1. Заблокированные мессенджеры: whatsapp.com, telegram.org, signal.org.
  2. Заблокированные СМИ: meduza.io, bbc.com, novayagazeta.eu.
  3. Технические ресурсы: protonvpn.com, te-st.org, github.com.
  4. Эталонные иностранные (не заблокированые): microsoft.com, nvidia.com.
  5. Деградирующие: youtube.com, apple.com.
  6. Локальные российские (работающие): ya.ru, vk.ru.
  7. Инфраструктура CDN: cdnjs.cloudflare.com (Cloudflare), fastly.net, ajax.googleapis.com (Google), cdn.jsdelivr.net . (Цель: выявление блокировок подсетей хостинг-провайдеров на уровнях L3/L4 в противовес точечной L7-фильтрации)

DNS-серверы (резолверы)

  • BigTech & Публичные резолверы: Cloudflare, Google, Quad9, Cisco Umbrella, OpenDNS.
  • Специализированные и приватные DoH/DoT: NextDNS, Control D, AdGuard DNS, Mullvad DNS, LibreDNS.
  • Российские: «Яндекс DNS», НСДИ (Национальная система доменных имен), не как тестируемые «внешние» DNS, а как ориентир, что отвечает DNS, заведомо работающий под российской юрисдикцией

Чем мы измеряли 

  • kdig — для запросов по обычному DNS, DoT, DoH и DoQ; ъ
  • dig — для ручного управления полем EDNS Client Subnet при проверке гипотезы про географическую маршрутизацию;
  • curl — чтобы проверить напрямую, что отдает конкретный IP-адрес по HTTPS с заданным SNI, независимо от резолвера и его ответа.

Что мы хотели найти

  • L3/L4: IP Blackholing подсетей известных резолверов, веерная блокировка порта 853, отправка поддельных пакетов TCP RST для сброса соединений на этапе установки сессии. (Порт 853 общий для DoT и DoQ, сравнение поведения этих двух протоколов на одном порту позволяет определить, режется ли порт целиком, либо фильтр различает конкретный протокол/сигнатуру внутри.)
  • Active Intercept: Подмена A/AAAA-ответов серверами ТСПУ (DNS Hijacking). Для верификации точки перехвата и доказательства подмены именно на ТСПУ применяется трассировка сетевых маршрутов. 

«Испорченный» DNS-ответ в этом исследовании может возникать по одной из двух разных причин, которые нельзя смешивать в одной таблице:

  1. In-path перехват (ТСПУ). Модификация/сброс трафика на маршруте между клиентом и резолвером. Наблюдается только если запрос физически проходит через сеть российского оператора. Признак: результат меняется в зависимости от точки наблюдения при одном и том же резолвере (РФ-нода видит подмену/сброс, зарубежная нода к тому же резолверу — честный ответ).
  2. Resolver-side compliance. Оператор резолвера сам встраивает blocklist в логику ответа на своих серверах. Признак: результат идентичен независимо от геолокации клиента, потому что фильтруется не маршрут, а сама точка ответа.

Различать два эти случая важно, так как для каждого нужны разные меры противодействия: VPN/обфускация трафика решает первое, но бессильна против второго — там нужна смена DNS.

Что мы нашли

Сразу скажем: классической блокировки, сброса соединений или недоступности целых подсетей, на наших тестовых узлах мы не нашли. Зато мы обнаружили необъясненную подмену DNS-ответа у части резолверов для части доменов. Мы делали разбор этих адресов.

Тогда мы назвали эти адреса «заглушками РКН». Но при более подробной проверке оказалось, что это не совсем точное описание. По этим адресам отдается настоящий, рабочий контент Cloudflare, а не пустой отбойник, мы проверили это напрямую curl’ом с явным SNI на signal.org через адрес 8.47.69.6, причём не только с VPS, но и через обычный домашний интернет в России. 

Как мы отличали «шум» от реальных аномалий

Первый проход по логам показал: для части доменов ответ на российском узле отличался от ответа на всех проверенных зарубежных узлах. Прежде чем что-либо интерпретировать, эту выборку нужно было очистить от шума, иначе метод «повтор IP там, где его не должно быть» дает ложные срабатывания на любом anycast/CDN-сервисе

Важное методологическое наблюдение: стабильность, высокая повторяемость, сама по себе еще не признак вмешательства. Например, whatsapp.com и youtube.com дают воспроизводимые, узло-зависимые ответы со 100%-й повторяемостью и это ровно то, что можно объяснить штатной географической балансировкой нагрузки у самих провайдеров, а не подменой. Отличать «аномалию» от «шума» позволяет только сопоставление с контрольной группой: если то же самое происходит и с nvidia.com/microsoft.com, которые пока не блокируют и не собираются блокировать, дело может быть не в цензуре. 

После вычитания «шума »в данных остается одно заметное семейство ответов: 8.47.69.N / 8.6.112.N, где N ∈ {0, 6, 8}. 8.6.112.0/24 по данным ARIN зарегистрирован за Cloudflare, Inc. (origin AS13335). При этом сеть не входит в публикуемый Cloudflare список IP Ranges, который предназначен для настройки allowlist на origin-серверах и не покрывает весь внутренний/продуктовый диапазон компании. Иными словами, обнаружение адреса вне публичного списка не означает, что адрес принадлежит кому-то другому.

Как мы нашли признаки подмены

Для автоматического выявления подмены использовался простой принцип: если один и тот же IP-ответ повторяется у нескольких доменов, которые физически не связаны общей инфраструктурой (например, signal.org — собственные сервера Signal, meduza.io — за Cloudflare, te-st.org — за Cloudflare), это статистически аномально и указывает на общий источник подмены, а не на совпадение.

Метод не использует внешние базы данных о владельцах IP и не делает предположений о «правильных» адресах заранее — он просто ищет повторы там, где их не должно быть, что позволяет находить аномалии без необходимости заранее знать, что именно искать. Легитимность или нелегитимность каждого найденного совпадения мы проверяли дополнительно вручную. Домены за одним CDN-провайдером могут законно делить общий IP, такие случаи мы засчитывали как совпадение, а не подмену. Отличить одно от другого помогло то, какие конкретно домены оказались в одной группе.

Как мы исключили MITM

Проверка TLS-сертификата показала, что соединение к 8.8.8.8/1.1.1.1 устанавливается с подлинной инфраструктурой Google/Cloudflare (сертификаты действительны, выпущены легитимными CA Google Trust Services и SSL.com соответственно), что исключает классический MITM-перехват с подменой сертификата на пути к самому резолверу. Трассировка подтверждает, что трафик из российских узлов действительно попадает в собственную сеть этих провайдеров (AS15169 для Google), а не перенаправляется на посторонний адрес. 

Отсюда следует вывод: аномальный ответ по адресам 8.47.69.x/8.6.112.x не является результатом перехвата трафика на маршруте между клиентом и DNS Google/Cloudflare, соединение до самого резолвера подлинное. Если подмена и происходит, то она встроена в логику ответа на стороне резолвера (см. классификацию 2.4), либо является легитимным поведением инфраструктуры, которое имитирует подмену внешне.

Почему ответ похож на настоящий Cloudflare 

Схема адресации Cloudflare для доменов под ее защитой, две A-записи в двух соседних /24 с одинаковым последним октетом:

signal.org            104.18.10.47 , 104.18.11.47   → октет 47
meduza.io             104.18.0.79  , 104.18.1.79    → октет 79
cdnjs.cloudflare.com  104.17.24.14 , 104.17.25.14   → октет 14
аномалия (класс B/C)  8.47.69.0    , 8.6.112.0      → октет 0
аномалия (класс A)    8.47.69.6    , 8.6.112.6      → октет 6
аномалия (AdGuard)    8.47.69.8    , 8.6.112.8      → октет 8

Аномальный ответ во всех трех вариантах воспроизводит внутреннее соглашение Cloudflare (парные /24 с общим последним октетом), а не выглядит как произвольная подстановка IP, типичная для инжектора на пути (ТСПУ в таких случаях обычно отдает один фиксированный IP-заглушку без такой структуры). Это аргумент в пользу происхождения ответа от инфраструктуры Cloudflare, а не от стороннего перехватчика, но это не окончательное доказательство.

Три разных сценария, которые мы нашли по состоянию на 7 августа

Класс A. Дифференциальный сигнал, только заблокированные домены, вне зависимости от протокола шифрования 

резолвер узлы протоколы ответ заблокированных контрольных задето
Google RU-msk, RU-spb, EU-vpn-SPB udp_53, dot_853, doh_443 8.47.69.6, 8.6.112.6 4 0
AdGuard RU-spb udp_53, dot_853, doq_853, doh_443 8.47.69.8, 8.6.112.8 4 0

Повторяемость внутри класса A от 53.3% до 100%, у Google на RU-spb/doh_443 — 100%. Ключевая деталь: у Google этот ответ появляется на RU-Msk, RU-SPb и EU-vpn-SPb (VPN-выход через домашний ШПД в Санкт-Петербурге) и не появляется ни на одном из узлов без РФ-маршрута, то есть эффект зависит именно от маршрута, а не от DNS как такового. При этом cdnjs.cloudflare.com, включенный в ту же матрицу тестирования, ответ не меняет, задет только заблокированный набор. Это единственный класс, где дифференциальный тест (реакция только на заблокированные домены, при чистом контроле) пройден полностью. 

Данные по DoT и DoH здесь важны отдельно: ответ 8.47.69.6 приходит и по каналам, где контент запроса зашифрован (DoT/DoH). Внутри TLS-сессии ТСПУ не может подменить DNS-ответ, не разрушив сессию (это привело бы к ошибке валидации на клиенте, а не к тихой подстановке IP), значит этот конкретный ответ сформирован на стороне, которая владеет приватным ключом сессии, то есть самим резолвером Google (или тем, кто отвечает ему как источник ответа для самого резолвера). Это сужает круг возможных причин появления аномалий класса A до действий Google/Cloudflare, реагирующей на маршрут запроса. Но зачем по такой логике исключать cdnjs.cloudflare.com — открытый вопрос. 

Класс B. Resolver-side, ответ не зависит от узла-наблюдателя, но задевает контроль

«Яндекс» и НСДИ отдают этот ответ  8.47.69.0, 8.6.112.0 со всех измерительных узлов. Затронуты 4 заблокированных домена и cdnjs.cloudflare.com, который не входит в блокировочные списки. Повторяемость от 53.3% до 100% (максимум у NSDI/FI-VPS — 100%).

Отсутствие зависимости от маршрута здесь ожидаемо и объяснимо инфраструктурно: «Яндекс» и НСДИ всегда обращаются к серверам из России, независимо от того, откуда вы сами их спрашиваете, поэтому «одинаковый ответ с любого узла» не отличает пока resolver-side цензуру от resolver-side не-цензурной особенности (например, ECS/anycast-роутинга самого вышестоящего сервера). Единственное, что не укладывается в нейтральную версию — участие cdnjs.cloudflare.com, домена, который не блокируется.

Гипотеза о «списке РКН» не подтверждается. Возможно, речь об инфраструктурной особенности ответа Cloudflare для upstream-запросов из РФ. Важное уточнение: мы пока не проверяли напрямую, ведет ли себя вышестоящий сервер «Яндекса»/НСДИ так же, как Cloudflare.

Класс C. РФ-специфично, зависимость от маршрута, но задевает тот же контроль

Cloudflare (RU-Msk, все протоколы включая DoH/DoT) и NextDNS (RU-Msk + RU-SPb, все 4 протокола) отдают тот же 8.47.69.0, 8.6.112.0 только с РФ-узлов, при этом cdnjs.cloudflare.com снова затронут. Повторяемость у Cloudflare/RU-Msk 100% по всем трем протоколам.

Формально класс C ближе к «признаку in-path перехвата» из методологии (результат меняется в зависимости от точки наблюдения), но структура ответа и участие DoH/DoT делают версию in-path-инжекции маловероятной по той же логике, что и в классе A. ТСПУ не может модифицировать шифрованный ответ незаметно для клиента. Более вероятное объяснение – то, что географическая маршрутизация запроса до вышестоящего сервера (edns-client-subnet или anycast-нода) приводит к тому же результату, что и у «Яндекса» и НСДИ, но проявляется только при РФ-адресе клиента, а не при РФ-адресе резолвера.

Что все это значит

  • Класс A (Google, AdGuard). Дифференциальный тест пройден полностью, зависимость от маршрута подтверждена, ответ приходит и по шифрованным транспортам. Наиболее вероятное объяснение — логика на стороне резолвера/источника ответа для самого резолвера, зависит от маршрута запроса, а не in-path инжекция.
  • Класс B (Яндекс, НСДИ). Воспроизводит структуру адресации Cloudflare, но затрагивает cdnjs.cloudflare.com, это противоречит версии со списком Роскомнадзора. Проверить, зависит ли ответ этих резолверов от поля ECS так же, как у Cloudflare, мы пока не успели.
  • Класс C (Cloudflare, NextDNS). Тот же ответ, но только с российских узлов, причем затрагивает и cdnjs.cloudflare.com. Прямая проверка показала: смена заявленной подсети (российская против немецкой) ответ не меняет, значит, дело не в содержимом ECS, а в конкретном сетевом пути от узла до Cloudflare. У Cloudflare аномалия проявляется только на московском узле. Это отличается от класса A, где аномалия одинаково цепляет оба российских узла, скорее всего, у Google и Cloudflare делают это по-разному, и одно с другим не связано. 

Что мы обнаружили к концу августа?

Коротко

  • 29 августа с нашей домашней точки в Петербурге запросы по открытому DNS к Google, Cloudflare и OpenDNS перестали доходить: их выбрасывают молча, без ответа и без ошибки, на выходе из сети оператора. До этого 3 августа с той же точки все три резолвера отвечали честно.
  • Сами резолверы работают. Google 8.8.8.8, Cloudflare 1.1.1.1 и OpenDNS 208.67.222.222 отвечают на пинг, а тот же запрос, отправленный на тот же порт 53 по TCP вместо UDP, возвращает настоящие адреса. Не проходит именно незашифрованный DNS-запрос по UDP.
  • На наших VPS в Москве и Петербурге 29 августа на наши запросы DNS-резолверы ответили так же, как 5 августа. Там пока не изменилось ничего.
  • Заворот запросов на резолвер НСДИ, о котором сообщило тех сообщество Zapret 2, мы на своих точках не обнаружили
  • НСДИ все так же отказывается выдавать адреса YouTube и WhatsApp, как отказывался 3 августа
  • Три аномалии, которые мы ранее описывали, повторяются в том же виде. «Википедия» с наших точек пока резолвится нормально.

А теперь подробнее.

26 августа: YouTube не открывается по причине «домена не существует»

Вечером 26 августа пользователи начали сообщать, что перестали открываться YouTube и другие заблокированные сайты, причем с ошибкой «домена не существует». На следующий день на «Хабре» вышел разбор с замерами, техническое сообщество собрало наблюдения пользователей из разных регионов в отдельную статью, обсуждение идет на ntc.party.

Что происходит?

  1. ТСПУ распознает DNS-запрос внутри UDP-пакета.
  2. ТСПУ переписывает в нем адрес получателя на государственный резолвер НСДИ (195.208.5.1).
  3. Отвечает уже НСДИ: заблокированным доменам — «домена не существует», остальным — настоящие адреса.
  4. Ответ приходит с адреса 8.8.8.8, поэтому со стороны выглядит как ответ Google.

Именно это мы искали 2–5 августа и не нашли ни на одной своей точке. Мы повторили замер 29 августа на трех точках внутри России: ВПС в Москве, ВПС в Петербурге и домашнее широкополосное подключение в Петербурге.

29 августа: на домашней точке открытый DNS к трем резолверам (Google, Cloudflare и OpenDNS) не работает

3 августа 2026 с домашнего подключения в Петербурге Google (8.8.8.8), Cloudflare (1.1.1.1) и OpenDNS (208.67.222.222) отвечали по открытому UDP порт 53 так же честно, как с зарубежных точек. 29 августа ни один из трех уже не ответил ни разу.

ТСППУ блокируют DNS не выборочно. Не приходят ответы ни про ya.ru, ни про nvidia.com и microsoft.com — домены, которые никто пока не блокирует и которые мы держим в списке на проверку как контрольную группу. Очевидно ТСПУ не разбирает, о чем спрашивают: он смотрит, куда идет пакет (UDP_53 to Google, Cloudflare, OpenDNS) и блокирует.

Тогда, 2–5 августа, мы описывали подмену в некоторых случаях: резолвер отвечал, но подставлял чужой адрес для конкретных доменов. 29 августа, добавилось другое: три резолвера не отвечают вообще ни на что.

Резолверы при этом живы, и это проверяется в три шага. Все три адреса отвечают на пинг. DoT и DoH к Google, Cloudflare и OpenDNS с этой же точки работают и отдают настоящие адреса. А тот же вопрос про ya.ru, заданный тем же трем DNS-серверам на тот же порт 53, но по TCP, возвращает настоящие адреса Яндекса от всех трех. Один адрес, один порт, один вопрос, разница только в транспорте.

Блокируется не резолвер, а узкая комбинация: адрес получателя из списка, протокол UDP, порт 53 и DNS-запрос внутри пакета. Убери любое одно условие — и пакет проходит.

Мы нашли, где пакет «застрял»

Трассировка настоящим DNS-запросом до 8.8.8.8 и 1.1.1.1 проходит пять хопов по сети оператора и обрывается сразу за последним из них: дальше не отвечает никто. Тот же запрос, адресованный «Яндексу», эту границу проходит и идет еще три хопа, до точки обмена трафиком. Обычная трассировка до 8.8.8.8, без DNS внутри, границу тоже проходит и доезжает до сети Google.

То есть маршрут рабочий, а незашифрованный DNS-запрос к нужному адресу через выход из сети оператора не пропускают. Само устройство замер не опознает: он показывает, где пакет исчезает, а что там стоит, ТСПУ, собственный фильтр оператора или фильтр транзитного провайдера выше, из него не следует.

На ТСПУ указывает то, что правило одинаково выбирает три самых известных публичных адреса и реагирует на содержимое пакета: так выглядит централизованно раскатанная настройка, а не самодеятельность одного провайдера. 

С этой же точки 29 августа прошли и запрос по TCP, и DoT, и DoH , их правило не тронуло. Рассчитывать на это как на надежную опору нельзя: расширить правило на другие транспорты ничто не мешает, а у абонентов других операторов в те же дни зафиксировали обрывы DoH по имени сервера. Наши прежние рекомендации от этого становятся не просто актуальными, а необходимыми.

Еще одна деталь. С той же домашней точки широкополосного интернета по открытому UDP нормально отвечают Quad9 (9.9.9.9 ), AdGuard (94.140.14.14 ), NextDNS (45.90.28.232 ), ControlD (76.76.2.0 ), Яндекс и сам НСДИ. Под удар попали три самых известных публичных DNS адреса, те, которые чаще всего прописывают вместо провайдерских.

Заворота на НСДИ на наших точках мы не обнаружили

На домашней точке это видно из одной пары запросов. НСДИ на ya.ru отвечает нормально: три настоящих адреса «Яндекса». Значит, если бы наш запрос про ya.ru к 8.8.8.8 заворачивали на НСДИ, мы бы получили эти адреса, заворот устроен так, что ответ приходит. Мы не получили ничего. Пакет не перенаправляют, а выбрасывают.

На ВПС открытый UDP работает, и там не сходятся сами ответы. Возьмём те пять доменов, на которых мы поймали подмену: signal.org, meduza.io, novayagazeta.eu, te-st.org и cdnjs.cloudflare.com. Google с ВПС по открытому UDP отдает на них 8.47.69.6, а НСДИ на те же пять доменов отдает 8.47.69.0. А youtube.com через Google по открытому UDP приходит с настоящими адресами Google, тогда как НСДИ на этот домен отвечает отказом. Заворот сделал бы оба ответа одинаковыми.

Оба признака выше построены на сравнении наших собственных ответов между собой, и у такого сравнения есть слабое место. При завороте обратный адрес переписывают назад: ответ приходит будто бы от 8.8.8.8, и по нему не понять, кто его составил. Нужен свидетель со стороны, тот, кто видел, кто именно к нему пришел за ответом. Такой свидетель существует, причём специально для отладки. У Akamai есть служебное имя whoami.akamai.net, устроенное наоборот по сравнению с обычным доменом: его сервер возвращает не адрес сайта, а адрес того, кто у него спросил. А спрашивает не ваш компьютер, а резолвер, если вы обращаетесь к 8.8.8.8, он идет за ответом дальше по цепочке и приходит к серверу Akamai уже от себя. Так и выясняется, чья сеть на самом деле обслужила запрос.

Спрашиваем это имя через 8.8.8.8 с домашней точки по TCP, то есть по тому единственному открытому транспорту, который к этому резолверу отсюда еще проходит, и получаем 172.253.83.211, адрес, принадлежащий Google. Запрос доезжает до Google, а не в чужую сеть. Если бы его завернули на НСДИ, вернулся бы адрес из сетей MSK-IX: именно так подмену и ловили пользователи ntc в обсуждении. Смотреть при этом надо не на то, совпал ли ответ с 8.8.8.8 , так как он и не должен совпадать, наружу к авторитативным серверам резолверы ходят с других адресов. Смотреть надо на владельца сети, через whois по полученному адресу, поля netname и org.

Это не опровергает сообщения пользователей правила раскатывают неравномерно, по операторам и регионам. Наши три точки просто показывают другие действия того же оборудования. Важная закономерность: на домашнем интернете ТСПУ фильтрует жестче, чем в дата-центрах.

НСДИ отказывает так же, как отказывал 3 августа

Мы спросили оба адреса НСДИ напрямую, 195.208.4.1 и 195.208.5.1. Оба на youtube.com и whatsapp.com отвечают NXDOMAIN «такого имени не существует» с флагом aa и с пустой секцией AUTHORITY. Флаг aa заявляет: «я владею этой зоной и говорю о ней как хозяин». Он стоит в обоих ответах, хотя зону youtube.com держит Google, а whatsapp.com — Meta, и к НСДИ они отношения не имеют. Пустая AUTHORITY означает, что сервер не приложил запись SOA. SOA — это служебная запись зоны, ее паспорт: какой сервер в зоне главный, кто администратор и на какой срок ответы про эту зону можно запоминать. Стандарт требует прикладывать SOA к отказу «такого имени не существует», чтобы клиент знал, кто именно сказал «нет» и как долго это помнить. Здесь под отказом не подписался никто. На ya.ru те же серверы отвечают тремя настоящими адресами и без флага aa. НСДИ фильтрует избирательно, и подпись у него ровно та, что описывали пользователи ntc.party на прошлой неделе: отказ NXDOMAIN, флаг aa, пустая AUTHORITY .

Но тот же отказ стоит и в нашем замере 2–5 августа, причем на всех семи точках, с которых мы тогда мерили: из Москвы, из Петербурга, из Испании, из Германии, из Финляндии.

Аномалии 3 августа также воспроизводятся к концу месяца

Пять доменов, signal.org, meduza.io, novayagazeta.eu, te-st.org и cdnjs.cloudflare.com, с российских точек резолвятся не в свои настоящие адреса, а в адреса из диапазонов 8.47.69.x и 8.6.112.x, которые этим сайтам не принадлежат. Третий октет зависит от того, какой резолвер спросили: у Google это .6, у AdGuard .8, у остальных .0. В разборе мы разделили это на три класса по тому, кто как отвечает и с каких точек. 

Все три аномалии воспроизвелись 29 августа в том же виде: тот же резолвер, та же точка, тот же адрес в ответе. Google отдает 8.47.69.6 со всех трех наших российских точек, Cloudflare 8.47.69.0 только из Москвы, AdGuard 8.47.69.8 только с петербургского ВПС. cdnjs.cloudflare.com, который никто не блокирует, по-прежнему цепляют одни резолверы и не цепляют другие. Отдельные ответы мигают между настоящим адресом и подмененным ровно те, у которых повторяемость и в начале августа была неполной, от 60% до 93%.

Ещё восемь доменов «Википедии» мы добавили в проверку после ночного сбоя 28 августа, который разбирали отдельно 28 августа. Но по ним мы пока не видим подмену

Что в итоге? Есть ли блокировка?

Возможно, да. При этом на данный момент официальных комментариев насчет проблем с DNS от российских властей не поступало.

Из 27 доменов в нашем списке (19 из прошлого исследования и 8 доменов «Википедии») НСДИ отказывает ровно по двум: youtube.com и whatsapp.com. Это мы подтверждаем, и так было уже 3 августа, за три недели до волны 26 августа. Остальные 25 доменов он резолвит, в том числе заблокированные в России: по пяти подставляет свой адрес из диапазона 8.47.69.x, по остальным отдаёт настоящие. 

А вот заворот запросов к чужим резолверам на НСДИ мы на своих точках не обнаружили. Получается, новое в последние дни августа не то, что НСДИ отказывает, а то, что к нему, по описаниям пользователей, начали направлять трафик тех, кто от провайдерского DNS ушел. 

Со стороны пользователя эти два случая не различить. И тот, чей провайдер честно пересылает запросы на НСДИ, и тот, чьи запросы к Google завернули по дороге, получают один и тот же отказ от одного и того же сервера.. Есть ли в этом признаки блокировки, мы не можем утверждать стопроцентно. Ранее мы уже писали о похожем поведении, блокировке уже настоящего адреса на уровне SNI (Разбор #20), увиденная нами аномалия подтверждает наш разбор.

За рамками этого исследования остались децентрализованные системы (OpenNIC, Namecoin, Emercoin, GNU Name System), альтернативные протоколы (DNSCrypt, ODoH) и малоизвестные региональные резолверы, они требуют другого инструментария и отдельной проверки.

Как проверить у себя?

Картина различается по операторам: на нашем домашнем подключении открытый DNS к трем резолверам (Google, Cloudflare и OpenDNS) не работает, а на двух ВПС в СПб и Мск работает все. Так что смотрите свою сеть.

  • Спросите у 8.8.8.8 адрес заблокированного сайта, например dig www.youtube.com @8.8.8.8 в Linux и macOS, nslookup youtube.com 8.8.8.8 в Windows. Ответ NXDOMAIN (в Windows это «Non-existent domain») означает подмену.
  • Полное отсутствие ответа означает, что открытый DNS к этому адресу у вас не проходит, тогда повторите запрос по TCP: dig +tcp www.youtube.com @8.8.8.8, в Windows nslookup -vc youtube.com 8.8.8.8.
  • Если по TCP ответ приходит, режут транспорт, а не резолвер. Это как один из способов проверки, а не обход: запрос по TCP такой же открытый и виден на маршруте целиком.

Что можно сделать с этими аномалиями? Технические рекомендации

Администраторам сайтов и разработчикам

  • Self-Hosted DoH через Reverse Proxy. Маршрутизация запросов через собственную VPS. Трафик проксируется через веб-сервер (Nginx или Caddy) на порту 443 с легитимным TLS-сертификатом к локально запущенному dnscrypt-proxy. Для сигнатурного анализа ТСПУ такое соединение неотличимо от обычного веб-серфинга.
  • Альтернативные протоколы (ODoH). Развертывание протокола Oblivious DoH. Эта технология использует промежуточный прокси-сервер, гарантируя криптографическое разделение: прокси знает IP-адрес клиента, но не видит сам DNS-запрос, а конечный резолвер видит запрос, но не знает IP-адрес клиента.
  • Инкапсуляция трафика (XTLS/Обфускация). Упаковка системных DNS-запросов (порт 53) в туннели с маскировкой под TLS 1.3 хэндшейк (протоколы VLESS+Reality). Это скрывает от DPI не только конечный домен, но и сам отпечаток (ALPN) протокола DNS, делая L7-фильтрацию невозможной.
  • Уберите зависимость от открытого DNS к внешним адресам. Если какой-либо сервис резолвит имена через 8.8.8.8 открытым DNS, он может замолчать без предупреждения, и найти причину будет тяжело. Слова «DNS» в логах не появится: приложение сообщит, что не смогло достучаться до платёжного шлюза, вебхука или внешнего API, потому что для него отказал именно удалённый хост, а не поиск его адреса. Первым симптомом к тому же будет не отказ, а замедление, так как системный резолвер несколько секунд ждёт таймаута на каждом запросе и только потом идет ко второму серверу из списка. Сейчас правило написано под UDP, но TCP такой же открытый и попасть под него может в любой момент.
  • После избавления от зависимости разверните собственный DoH через reverse proxy на 443-м порту: для сигнатурного анализа такое соединение не отличается от обычного веб-серфинга. Еще устойчивее упаковать DNS-запросы в туннель с маскировкой под TLS-рукопожатие, тогда фильтрация по адресу резолвера перестает что-либо значить.
  • Проверьте, как заданы резолверы в роутерах, клиентах и конфигах. Там, где резолвер прописан именем, соединение к нему рвут по SNI: сейчас уже фиксируют блокировки dns.google, cloudflare-dns.com, dns.adguard.com и dns.quad9.net, хотя на наших точках такого пока нет. Тот же резолвер, заданный адресом с портом, под такое правило не попадает.
  • Не ограничивайтесь самыми известными адресами DNS-резолверов. Под удар на нашей домашней точке попали три, Google, Cloudflare и OpenDNS, очевидно те, которые чаще всего прописывают вместо провайдерских. Держите в конфигурации резервные: Quad9, AdGuard, NextDNS и ControlD оттуда же 29 августа отвечали. Но «отвечали» не значит «отвечали честно»: часть из них подставляет свои адреса на тех пяти доменах, о которых мы писали. От молчания резервные адреса спасают, а от подмены нет. 

Разработчикам приложений

  • Не полагайтесь на системный резолвер: браузеры давно ходят через свой встроенный DoH, клиентские библиотеки есть под все основные языки, и со своим клиентом вы сможете держать несколько адресов и переключаться по таймауту, а не ждать системного.
  • Логируйте резолвинг отдельной строкой: пользователь пришлет вам «приложение не работает», и это единственный способ отличить блокировку DNS от падения вашего же бэкенда.
  • Проверьте, как ведет себя приложение, когда имя не резолвится вообще: оно должно показать внятную ошибку резолвинга, а не оставаться в состоянии загрузки до системного таймаута.

Пользователям

  • Локальные резолверы и раздельное туннелирование. Для обхода гео-блокировок российских ресурсов (банков, госуслуг) и одновременного обхода цензуры рекомендуется использование dnsmasq на домашних роутерах (OpenWrt, Keenetic). Запросы к зоне .ru принудительно направляются на DNS провайдера, а все остальные — в зашифрованный локальный туннель (DoH/DNSCrypt).
  • Отказ от открытого DNS. Базовые запросы через порт 53 перехватываются ТСПУ для подмены ответов (Слой 3). Настройка DoH (DNS over HTTPS) в современных браузерах или на уровне ОС — минимальный базовый шаг. Это не скрывает SNI, но исключает выдачу IP-заглушек.
  • Что надо сделать на своих устройствах: DoH в браузере, DoT в системе, на роутере и на телефоне. Незашифрованный DNS оборудование на маршруте видит целиком и может как подменить ответ, так и выбросить запрос, и это верно и для UDP, и для TCP. Правило, которое мы поймали, написано под UDP, но TCP защиты не даёт: он идёт таким же открытым текстом. Прячет содержимое только шифрование, а адрес резолвера только туннель.

Список источников и полезных материалов:

  1. RFC 9230 (Oblivious DNS over HTTPS): Технический стандарт IETF, описывающий архитектуру ODoH — datatracker.ietf.org/doc/rfc9230/
  2. DNSCrypt & dnscrypt-proxy: Официальный репозиторий проекта с инструкциями по развертыванию защищенного клиента и сервера — github.com/DNSCrypt/dnscrypt-proxy
  3. dnsmasq: Документация легковесного кэширующего DNS-сервера для настройки раздельного туннелирования на роутерах — thekelleys.org.uk/dnsmasq/doc.html
  4. Nginx Reverse Proxy: Официальная документация модуля ngx_http_proxy_module для проксирования DoH-трафика — nginx.org/en/docs/http/ngx_http_proxy_module.html