Кабысдох – DoH-припарка от русского firewall

    # wtf cf-hls-media.sndcdn.com
    cf-hls-media.sndcdn.com is an alias for d1ws1c3tu8ejje.cloudfront.net.
    d1ws1c3tu8ejje.cloudfront.net has address 13.33.240.123
    ❌ 13.33.240.123 заблокирован

    С в очередной раз замолчавшего радио и начался тот день, когда я допилил DNS-over-HTTPS сервер для облегчения фантомных болей от творчества Роскомнадзора.

    Боли эти хорошо описаны @ValdikSS в статье «В России сохраняются проблемы с доступностью сайтов, но никто их не замечает».

    Думать особо не приходится, суть проблем проста и решение тоже не очень сложно: достаточно выкидывать из DNS ответов заблокированные IP адреса а, если адресов не осталось, заменять их на подходящие адреса с того же CDN. Такое издевательство над DNS позволяют как минимум Cloudflare и Amazon Cloudfront.

    Например, если в условном DNS-ответе от AKAMAI пришли адреса 23.1.14.0 и 23.1.20.2, а первый из них заблокирован РКН, то в таком случае DNS-сервер может отдать клиенту только один адрес из двух, и браузер не будет «тупить» в попытке установить соединение с заблокированным IP. Это не обход блокировок, скорее наоборот. Но оно измеримо уменьшает боль. Я был бы рад такую конструкцию увидеть у Яндекс.DNS в «Безопасном» режиме, но всё же не думаю, что Яндекс готов реализовать такую в меру «серую» фичу.

    Валить в панике из страны? Заворачивать весь трафик в VPN? Зачем! Интернет в России ещё не настолько поломан, чтоб добавлять 50-100ms ко всем своим Zoom-созвонам во времена повсеместной самоизоляции. Можно ещё попытаться что-то починить, да посмеяться над тем, что осталось.

    Но хочу предупредить, модель такого DNS-сервера по имени kabysdoh.gulag.link запущена на виртуалке в Санкт-Петербурге, поэтому её использование из других регионов России может добавить существенную задержку к вашим DNS-запросам. При наличии архива XML-выгрузок Роскомнадзора, можно взять исходный код с GitHub и запустить Unbound в подходящей локации. Поддержку Knot Resolver я с @ValdikSS допилю в каком-нибудь обозримом будущем.

    Мобильные устройства на Android поддерживают DNS-over-TLS, который доступен по адресу kabysdoh.gulag.link (но, кажется, мы нашли баг в Unbound и с DNS-over-TLS наблюдаются проблемы), а Mozilla Firefox поддерживает DNS-over-HTTPS по адресу https://kabysdoh.gulag.link/dns-query. Скриншоты примерной конфигурации можно увидеть ниже (про все возможные опции DoH в Firefox можно прочитать на wiki):

    У меня на сегодня всё! Надеюсь, кому-то данная конструкция будет полезна. И помните, once you step into the waters of modifying in-flight DNS messages it seems like crocodiles all the way down.

    Комментарии 31

      +7

      NS необычный — результат отличный!

        0

        Спасибо за отличную идею и реализацию!

          +2
          Заворачивать весь трафик в VPN? Зачем!

          Чтобы не утруждать себя поиском и реализацией иных путей, вроде игр с dns, которые всё равно не дают 100% результата. И чтобы получить белый ip заодно, некоторые провайдеры их больше не выдают, даже за деньги.
            –1
            Так я не понял, а в чем проблема использовать DoH от Cloudflare или Google? Разве это не то же самое?
              +1

              Нет, это существенно другая конструкция. Примерно вся разница описана в этом параграфе:


              выкидывать из DNS ответов заблокированные IP адреса а, если адресов не осталось, заменять их на подходящие адреса с того же CDN

              Это нарушение стандартов работы DNS и выкатывать такое "по-умолчанию" большой сервис позволить не может.


              Собственно, пару недель тому назад на https://cloudflare.com нельзя было зайти — оба IP адреса из ответа были заблокированы по предварительному обеспечению по "пиратке".

              +1
              Я был бы рад такую конструкцию увидеть у Яндекс.DNS в «Безопасном» режиме, но всё же не думаю, что Яндекс готов реализовать такую в меру «серую» фичу.

              Есть эти ребята которые держат публичный сервер, ответы фильтруются.
              Для заблокированных доменов отдают Non-existent, а для остальных удаляют из выдачи заблокированные ip
              Эти ребята
                0

                Отличные ребята! Спасибо! Я посмотрю немного подробнее, что именно они делают. Жаль, исходников конфигурации не выкладывают.

                  0

                  Я глубоко не уверен, что это даже близко похоже. По описанию, это скорее для блокировки

                  0

                  А что это за утилита wtf в начале поста?

                    +1

                    Да так, мелкий самодельный утиль.


                    В публичном виде это выглядит как @u2ckbot от schors.

                    +1

                    В настройках андроида вбил ровно как на скриншоте — пишет «Ошибка подключения». К dns.google.com, вбитому в это же поле, подключается без проблем.

                      0

                      Кажется, мы нашли какой-то баг в Unbound или его конфигурации. С DNS-over-TLS у меня сейчас тоже наблюдаются проблемы, а DNS-over-HTTPS работает нормально. При том диагностики примерно нуль: сервер просто ИНОГДА не отвечает на Client Hello, а в мониторинге всё хорошо (отсох почему-то только IPv4, а мониторинг предпочитает IPv6 при dual-stack).


                      Буду разбираться. На smoke-тесте всё работало.

                        0

                        Попробуй временно поставить чуть не nginx перед

                          0

                          Попробую, конечно, хотя именно этого я хотел бы избежать. Я допускаю, что это моя лютая питонячка по памяти проехалась на автобусе. Там запуск подзапроса сделан весьма странно.


                          Но в целом там accept() завис, даже соединения из очереди не забираются:


                          State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process 
                          LISTEN  157     256           0.0.0.0:853        0.0.0.0:*     users:(("unbound",pid=4167,fd=8)) 
                          LISTEN  197     256           0.0.0.0:443        0.0.0.0:*     users:(("unbound",pid=4167,fd=4)) 
                          LISTEN  0       256              [::]:853           [::]:*     users:(("unbound",pid=4167,fd=10)) 
                          LISTEN  0       256              [::]:443           [::]:*     users:(("unbound",pid=4167,fd=6)) 
                          0
                          Лучше перед ним поставить AdGuard Home.
                            0

                            У меня пара частных Unbound в режиме DoT и с Андроидов 9+ работают вроде бы без проблем у родственников. Версия последняя? OpenSSL? Ну и вообще TLS стек должен быть стабилен как танк, там дальше уже возможны вопросы...

                              0

                              Версия из debian:testing с пересобранным пакетом, т.к. DoH по-умолчанию не собирается. Там не в TLS дело, там в какой-то момент на серверном сокете происходит "нечто", после чего он перестаёт accept()-ить новые соединения, это отлично видно в strace. Я пока уверен, что это баг в Unbound и я попробую с ним разобраться.

                            0

                            Сейчас должно работать. Но когда оно опять сломается — я предсказать не берусь пока, но по крайней мере своевременно теперь узнаю. Будем разбираться и починять. Собственно, в том числе для теста технологии я эту конструкцию и собрал :-)

                            +1
                            Как вариант — использовать Pi-hole (https://pi-hole.net) или AdGuard Home (https://adguard.com/ru/blog/in-depth-review-adguard-home.html, github.com/AdguardTeam/AdguardHome#comparison-pi-hole).
                            Оба умеют dot, doh, dnssec + резалка рекламы. Оба можно развернуть у себя.

                            Зы. AdGuard Home можно развернуть прямо на pfsense (у кого он есть).
                              0

                              Pi-Hole использую, но у него атакой фичи нет.
                              Идея, кстати, очень хорошая и надо предложить авторам её добавить (возможность lookup запроса к внешнему приложению для валидации/корректировки ответа).


                              Можно вообще совместить и сделать интересный хак — если нет ни одного разрешённого IP, то сервису выделяется приватный IP, отдаётся короткое время жизни DNS записи, по этому IP делается NAT в реальный IP с обходом блокировок.


                              Тогда и таблицы роутинга пухнуть на роутерах не будут (если пускать в обход блокировок все заблокированные адреса) и работать всё будет прозрачно.

                              +6
                              Автор предлагает побыть объектом атаки DNS spoofing c последующей MITM? :)
                                0
                                У меня последний FireFox просто не открывает через указанный автором DNS ни один https сайт, с сообщением — Издатель не может быть проверен.
                                То, есть блок сразу за MitM.
                                  0

                                  Для меня это звучит неожиданно. Если вам интересна причина такого поведения вашей сети — давайте вместе в ней попробуем разобраться.

                                    –1
                                    Да нет особого смысла в этом. Завернуть запросы на ВПН, или на crypt днс, все-таки надежнее.
                                  0

                                  С технической точки зрения — в точности так!

                                  0
                                  Ростов-на-Дону, Ростелеком.
                                  Коннекты на публичные DoH частенько отбивает по TCP RST по нескольку недель. Зависимости не выявил.

                                  Нужно больше приватных серверов!
                                    0

                                    Ну, например, mozilla.cloudflare-dns.com has address 104.16.248.249, а 104.16.248.249 заблокирован со ссылкой на Октябрьский районный суд г. Ставрополя 2-946/13 2013-06-10.


                                    У 8.8.8.8 и 1.1.1.1 (не путать с dns.google и one.one.one.one) причина тоже понятна — в запросах к ним нет SNI и такое некоторые DPI не любят.

                                    +1
                                    Заворачивать весь трафик в VPN? Зачем! Интернет в России ещё не настолько поломан, чтоб добавлять 50-100ms ко всем своим Zoom-созвонам во времена повсеместной самоизоляции.

                                    В Новосибирске — да, 50-100 мс добавится. В Москве при выходе VPN в Финляндии или Швеции — 10-15 мс — уже не так страшно. В Питере вообще пренебречь можно. У меня для некоторых ресурсов на роутере трафик пущен не через VPN (домены яндекса в основном для mirrors.yandex.ru, всякие mos.ru, домены и IP работодателя и еще штук 5). Остальное — через VPN, и, конечно, никаких DNS провайдера.
                                    После того, как перешёл на VPN, забыл напрочь весь геморрой с "национальными особенностями", поэтому считаю, что оно стоит того.

                                      0
                                      Cloudflare WARP сейчас работает реально шустро, практически не заметно задержек. И это несмотря на его бесплатность.
                                      0
                                      Блин, эт круто все! Но открывая думал в статье увидеть технопорно про препарирование Unbound, пенетрацию XML-выгрузок Роскомнадзора и вспомогательных скриптов, быть может хитрые трюки какие-нить…

                                      Может бы донастроил BGP для залоченных адресов у себя…
                                        0

                                        Ну это скорее в исходниках. Там не сложно, но ничего особо интересного :-)

                                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                      Самое читаемое