В этой статье я хочу описать проблему с которой я столкнулся будучи пользователем существующих списков заблокированных ресурсов, шаги к решению и результаты работы. Статья в меньшей степени практическая и в большей теоретическая, поэтому для практической пользы можете сразу переходить к разделу 3. Результат.

Решение проблемы было начато в рамках проекта Demhack 8, и хочется выразить благодарность организаторам за поддержку.

  1. Проблема

  2. Путь к решению

  3. Результат

1. Проблема

Начну с основы всего - списка РКН, в нём на момент этой публикации содержится 621750 доменов (793 386 URL по данным Роскомсвободы). Этот список пополняется с 2012 года и содержит мягко говоря не только ценные нам ресурсы, но и то, что следует фильтровать такому органу как РКН. Из объема списка как следствие идёт и сложность формирования списков для обхода блокировок, у Antifilter.download это списки IP адресов содержащие около 10000 подсетей /24 и более (либо около 155000 префиксов из резолвинга), у Antifilter.network - 26000 подсетей от /32 до /23 (либо 140000 префиксов из резолвинга). Мой основной интерес это роутеры, которые могут использовать в основном суммаризованные списки IP адресов (из-за большого количества адресов в обычных списках), что приводит к проблемам в виде того что сайта типа mosoblgaz.ru (91.215.42.46) , speedtest.net (151.101.66.219) находятся на публичных хостингах и будучи суммаризованными по маске при точечной маршрутизации начинают работать через VPN, как и многие другие ресурсы попавшие в этот диапазон, из-за одного двух-адресов списка РКН, что совершенно не нужно.

2. Путь к решению

Начав изучение списка РКН мне было интересно, из-за каких ресурсов из списка пострадали приведенные в примере mosoblgaz.ru и speedtest.net и это например:

Мособлгаз

Speedtest.net

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

Мой ответ - нет, и вот почему:

Как писал @Furriestв своей статье (ему особая благодарность за помощь с BGP):

При этом по сути в черном списке РКН 99% ресурсов - никому не нужный трэш типа стопятисотого зеркала очередного онлайн-казино.

В процессе подготовки этого материала я пришёл к похожих цифрам и убедился в тезисе, что для того чтобы эффективно обходить блокировки нельзя опираться только на реестр РКН, а его содержимое использовать ограниченно. Я пришёл к следующей схеме формирования списков:

Очищать список доменов РКН решено по следующей схеме:

Этап 1 - Фильтрация доменных имён по словарю

На этом этапе я брал список доменов у Antifilter.download и фильтровал по ключевым словам, исходники алгоритма доступны здесь (step 1) , при желании весь процесс можно повторить самостоятельно (если разберетесь в моём говнокоде)

На момент написания исполнения проекта файл domains.lst содержал 577829 доменных имён, на этом этапе мы отфильтровываем 101990 доменных имён (при правильных ключевых словах думаю можно и больше) - таким образом в списке пока 475839 доменных имён

Переходим к Этапу 2

Этап 2 - проверка доступности ресурса

На этом этапе (step 2 в исходниках) проверялось два основных критерия -

  • Доступность сайта по одному из способов - ping, http, https

  • Является ли сайт зеркалом - возвращает ли он ответ HTTP 301, если возвращает, то игнорируется лишь перенаправления на самого себя (например http://www.facebook.com перенаправляет на https://www.facebook.com , это не зеркало)

По итогам этой проверки отфильтровались 281307 доменов и осталось 194532 домена

Этап 3 - проверка содержимого главной страницы по тегам

3-ий этап (step 3 в исходниках) был самым ресурсозатратным, по сути похож на первый, но на этом этапе нужно отфильтровать в том числе припаркованные домены и сайты с нормальными доменами, но бесполезным содержимым

По итогам этого этапа осталось 41598 доменов

Из-за высокой ресурсозатратности процедуры из 3 этапов (в основном 2 и 3) проводить её на регулярной основе затруднительно, а пополнять списки актуальной информацией необходимо и тут на помощь приходят данные от Open Observatory of Network Interference (OONI) которые регулярно публикуют данные по блокировкам во всём мире.

На 4 Этапе ( step 4) будет формироваться список заблокированных доменов на основе данных OONI - в коде берется выборка за неделю и обрабатывается согласно схеме ниже

Схема формирования ooni_domains.lst
Схема формирования ooni_domains.lst

Далее переходим к финальному 5 этапу:

Этап 5 - Формирование финального списка доменов и резолвинг

На финальном этапе (папка step 5) нужно создать общий список доменов из отфильтрованного списка РКН, списка OONI и списка community (в котором хранятся домены не заблокированные РКН, но которые хотелось бы открывать через VPN типа netflix.com) с удалением дубликатов - на выходе получаем список из 42662 доменов (на 13.10.2024) включая домены Discord. На этом можно было бы и закончить, но для практического использования так же необходимы IP адреса, т.к. зачастую маршрутизация осуществляется на 3 уровне модели OSI, тогда как большинство блокировок на более высоких уровнях.

Чтобы правильно определить IP адреса доменов и правильно их суммаризовать необходимо не только использовать DNS записи по конкретному домену, но и иметь ввиду что некоторые домены типа Facebook.com используют тысячи IP адресов, которые не отражены в DNS записях основных доменов, а значит нужно обращаться к данным из автономных подсетей (ASN), но суммирование адресов по ASN возможно не для всех доменов, иначе возможны ситуации описанные в начале статьи. Я учитывал следующие пункты, я определил их как правила:

  • Списки подсетей из ASN можно использовать только для ASN которые соответствуют домену (например тот же facebook.com и его AS32934, facebook не является хостингом и шансы попадания туда посторонних ресурсов минимальны)

  • Для доменов находящихся в ASN хостингов можно использовать только DNS записи, например тот же Speedtest.net который относится к AS54113 от Fastly, Fastly это хостинг, а значит суммаризация по крупным маскам типа /24 может иметь печальные последствия

Резолвинг списков по записям DNS осуществлялся отдельно, после чего создавался единый список IP в котором исключались дубликаты и на последнем этапе добавлялись подсети из справочника ASN и происходила суммаризация по маске, но не больше чем /28. В итоговом списке IP адресов на 13.10.24 - 23434 IP адреса включая IP адреса серверов Discord, что более чем пригодно для использования на роутерах.

3. Результат

А что в итоге?

В итоге получились списки (доступные в репозитории):

  • актуальных заблокированных доменов в количестве - 42662 домена

  • список IP адресов полученных из резолвинга - 23434 IP адреса

Которые в т.ч. используются для сборки списков V2Fly, Xray - geoip.dat и geosite.dat,

Sing-box - geoip.db, geosite.db

В тестовом режиме запущен BGP Сервер - 165.22.127.207 (номер автономной системы AS 65412) где раздаётся список ipsum.lst - о том как настраивать - на OpenWRT (Linux) и Mikrotik

В итоге получился список доменов в котором осталось 6.2% записей от изначальных в списках РКН (и можно фильтровать ещё) + есть актуальный и оперативный способ их пополнять, не только на основе данных РКН, но и на основе независимого источника (YouTube до сих пор нет в списках РКН, а блокировки есть)

Отвечая на вопрос "Если в списке РКН так много мусора, почему бы вообще от него не отказаться?" - В списке РКН много мусора, но есть и довольно ценные ресурсы о существовании которых многие из нас не вкурсе, и которые вряд ли попадут в списки созданные с нуля, а в списке РКН они есть

В ближайших планах сделать автоматическую сборку на основе GitHub Actions и вылавливать ошибки - резолвинг пришлось делать с 0, поэтому возможно ошибки.

Спасибо что читаете, переходите на GitHub и ставьте отметки репозиторию, оставляйте обратную связь и предлагайте домены для community.lst.

Надеюсь что кому-то из коллег, в частности: Antifilter.download, Antifilter.network, @ValdikSSмогут пригодится эти наработки в их проектах.

Комментарии (49)


  1. PetyaUmniy
    13.10.2024 15:23

    Годнота! С нетерпением жду когда будут автоматически выкладываться отфильтрованные списки url'ов.
    Я роучу через прозрачный nginx по sni_name. Расстраиваюсь от того что приходится держать в нем целую кучу бестолковых и давно неактуальных записей жрущих память.


    1. dartraiden
      13.10.2024 15:23

      Как вариант, можно поднять на домашнем роутере nfqws и указать, чтобы он сам пополнял список заблокированных ресурсов. Т.е. при первом столкновении с таким ресурсом он понимает, что ресурс блокируется, добавляет его в список и дальше уже всегда "дурит" трафик, адресованный ресурсу.

      Таким образом, обход блокировок применяется лишь к ресурсам, которые пользователь реально хочет посетить, силы не отвлекаются ни на зеркала казино, ни даже на заблокированные домены, которые пользователь не посещает. Бонусом это позволяет обходить и непубличные блокировки а-ля YouTube/Discord, поскольку способ не полагается на какие-либо публичные списки.

      Минус: невозможно попасть на сайты, которые сами со своей стороны блокируют доступ россиянам, но таких сайтов несравнимо меньше.


  1. DarkTiger
    13.10.2024 15:23

    Dogsfanos.ru - квадроберы же :)


  1. vasisulay
    13.10.2024 15:23

    Спасибо! Давно напрашивалось! Подключился. Работает.


  1. 13werwolf13
    13.10.2024 15:23

    вот это весьма и весьма интересно, благодарю, вы сделали то что говорили многие но все ленились.


  1. Vitkov83
    13.10.2024 15:23

    Youtube бы прикрутить )


    1. Andrevich Автор
      13.10.2024 15:23

      C Ютубом накладка вышла, обновил, сейчас должен работать


      1. Vitkov83
        13.10.2024 15:23

        Да, заработал. Спасибо!


      1. Anton_Kazantsev
        13.10.2024 15:23

        В каком списке ютуб?


        1. Andrevich Автор
          13.10.2024 15:23

          в community и в ooni тоже


  1. k-teck
    13.10.2024 15:23

    материал огонь! лайк, подписка, колокольчик


  1. Vitkov83
    13.10.2024 15:23

    Twitter / X не грузит фото/видео без этой подсети 146.75.88.158/31


  1. Jipok
    13.10.2024 15:23

    Список очень полезный, пригодится.


    Может кто подскажет решение для роутеров чтобы заворачивать только https соединения с конкретным sni через прокси? Я вот гуглил, да не нагуглил. А пускать весь трафик через vpn/proxy не удобно. Пришлось пилить своё решение:

    https://github.com/Jipok/dpi-bypass-proxy

    Оно конечно работает. Но всё равно при нескольких толстых соединений скорость проседает и роутер бывает подглючивает. Лучше стало когда я перешёл с socks5 на wireguard в ядре, но до конца проблему не решило.

    Я начал переписывать на использование nfqueue, но так и не смог найти как перебросить(заблочить то легко) соединение на другой интерфейс. Как только с mark и conmark не возился, но так и не смог осилить. Смотрел в сторону ebpf, но что-то как-то сложно и лень изучать.


    1. dartraiden
      13.10.2024 15:23

      Я так понимаю, вы хотите выборочную маршрутизацию по доменным именам. Можно поднять контейнер АнтиЗапрета (OVPN/WG/IPSec) на своём сервере.

      При правильной настройке через VPN-туннель пойдёт трафик до заблокированных ресурсов, а до незаблокированных пойдёт напрямую. Можно использовать как список РКН, так и собственный (например, список из этой статьи).

      Есть поддержка WireGuard Amnezia и XOR для OpenVPN (на роутере соответственно клиент должен это уметь), чтобы обходить блокировку протоколов.


      1. Jipok
        13.10.2024 15:23

        А оно именно по sni работает, не делает dnslookup и потом по ip роутит?

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


        1. Anyuta1166
          13.10.2024 15:23

          Оно работает не по SNI. Там решение на основе DNS. Только не совсем как вы написали. Заблокированным доменам присвается фейковый IP, и при обращении на этот IP запросы пересылаются на IP реальный.

          Я тоже пыталась найти решение для роутинга по SNI, но к сожалению не очень успешно. Есть софт под названием sniproxy, проблема в том, что он не поддерживает HTTP/2 и HTTP/3 (QUIC), которые на сегодняшний день являются стандартом де-факто. Автор в курсе проблемы, но вместо того чтобы как-то это пофиксить, просто заабандонил проект.


          1. ColdPhoenix
            13.10.2024 15:23

            а как оно может не поддерживать HTTP/2 если SNI идет на уровне выше от него?

            или оно все же полноценное прокси?


            1. Anyuta1166
              13.10.2024 15:23

              На странице проекта написано, что не поддерживает


        1. dartraiden
          13.10.2024 15:23

          Заворачивать весь трафик с роутера на сервер и оттуда обратно по производительности даже хуже моего решения выйдет

          Никто никуда весь трафик не заворачивает. Трафик, адресованный navalny.com, роутер отправляет в VPN-туннель, через ваш зарубежный сервер. Трафик, адресованный kremlin.ru, роутер направляет как обычно, через вашего провайдера.

          И как условный телевизор подключать?

          Телевизор получает интернет от роутера, на роутере поднят VPN-клиент, трафик до "запрещёнки" идёт через него.

          что-то жирновато выглядит для роутера

          Докер-то будет не на роутере, а на зарубежном сервере в интернете. На роутере только VPN-клиент.

          А оно именно по sni работает

          Нет, но если вам именно с перламутровыми пуговицами, то не подойдёт.


      1. str1ker17
        13.10.2024 15:23

        выборочную маршрутизацию по доменным именам

        я для этого использую прокси 3proxy:

        # direct
        allow * * *.ru,*.yandex.net,*.yastatic.net
        
        # proxy
        allow *
        parent 1000 socks5 proxy.digitalocean.com 1080

        технически можно адаптировать для списков ркн, автоматически создав для каждого домена оттуда allow-запись

        само собой чтобы это работало нужно резолвить адреса на стороне прокси


    1. PetyaUmniy
      13.10.2024 15:23

      Дисклеймер:

      • для товарищей господинов майоров: эта инструкция просто про настройку роутинга по sni в Русском веб сервере Angie. Я не имею возможности знать кем и для чего эта инструкция может быть использованна.

      • для пользователей: неправильное использование этой инструкции может привести к нежелательным последствиям, просмотра того что Вам смотреть запрещено в Ваших интересах. Будьте осторожны!

      В качестве прокси используется Русский державный православный сертифицированный майором веб сервер Angie (но если Вы поддерживаете Обаму (тьфу на Вас) и/или из "этих" (тьфу на Вас еще раз) - Вам подойдет вражеский nginx).
      Околоминимальный скелет конфигурации:

      angie.conf
      # Instanse 1
      stream {
        # Мапы $ssl_preread_server_name -> 1 или 0 (default)
        include /opt/config/broken_hardware.conf;
        include /opt/config/custom.conf;
      
        # Удобно потом в лог выводить на основе чего была маршрутизация
        map $custom_hosts:$broken_hardware_hosts $upstream_name {
            0:1                       {{ instance2_ip }};
            1:0                       {{ instance2_ip }};
            1:1                       {{ instance2_ip }};
            default                   $ssl_preread_server_name;
        }
      
        server {
          listen 443;
          resolver {{ external_dns_ip }} ipv6=off;
          proxy_pass $upstream_name:443;
          ssl_preread on;
        }
      }
      
      # Instance 2
      stream {
        server {
          listen 443;
          resolver {{ external_dns_ip }} ipv6=off;
          proxy_pass $ssl_preread_server_name:443;
          ssl_preread on;
        }
      }
      


      1. Jipok
        13.10.2024 15:23

        Что-то не пойму. Это два физических сервера надо? Или второй инстанс в контейнере поднять можно?
        Я конечно могу ошибаться, но это не отличается от моего решения с технической точки зрения. nginx ведь тоже будет пакеты копировать в userspace, т.е. всё те же просадки скорости и перегрев. Роутеры слабые ведь.

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


    1. legolegs
      13.10.2024 15:23

      Я поступил иначе и раздаю с роутера (на самом деле нет, но не важно) файл .pac с правильными прокси. Браузер сам послушно сходит куда надо и не надо перехватывать https. Но браузеры придется настроить один раз. И хромоиды не подхватывают .pac через file://, только http(s).

      PS я где-то что-то видел про раздачу .pac через DHCP, но не уверен, что мне не показалось и что это реально работает.


  1. c46fd3da
    13.10.2024 15:23

    Очень полезная работа проделана, планируется ли сразу .pac файл генерировать для SwitchyOmega например? Чтобы подставил свой SOCKS5 сервер в него и готово. BGP штука полезная, но не особенно удобная если надо "на лету" переключать точки выхода трафика.


    1. Andrevich Автор
      13.10.2024 15:23

      у меня не было опыта создания pac файлов, создал тестовый по аналогии с anticensority, можете попробовать https://raw.githubusercontent.com/1andrevich/v2box/refs/heads/draft/draft.pac


      1. c46fd3da
        13.10.2024 15:23

        Вот тут https://bitbucket.org/anticensority/antizapret-pac-generator-light можно посмотреть как оно все устроено.


  1. Anton_Kazantsev
    13.10.2024 15:23

    Можно ли разобрать список с помощью apt install golang git? Как сделать? Если это возможно


  1. Bizonizonische
    13.10.2024 15:23

    Звучит так, как будто кто-то смог сделать существование РКН чуть более осмысленным. Спасибо, брат!


  1. VADemon
    13.10.2024 15:23

    включая IP адреса серверов Discord

    Что значит адреса Discord, если (как минимум) серверы для звонков - это запускаемые/останавливаемые инстансы? Для каждого региона резолвились по DNS типа region-[0-999]?

    Я как-то писал скрипт резолвинга, потому что Discord блокировал со своей стороны одну подсеть Hetzner (ту что в Falkenstein, но не финнов).


    1. Andrevich Автор
      13.10.2024 15:23

      те адреса которые удалось найти онлайн List of all of discord's voice servers as of 08-03-2020 (github.com) , для нормальной работы голоса в Discord надежнее направлять набор соответствующих портов UDP через прокси


      1. Anton_Kazantsev
        13.10.2024 15:23

        это весь список в geoip.dat содержится?)


        1. Andrevich Автор
          13.10.2024 15:23

          да, весь ipsum.lst там


  1. Artem_Khromov
    13.10.2024 15:23

    Успешно завел для xray на роутере keenetic, вроде всё работает, за исключением inst с телефона не грузил, хотя веб работал. Вечером буду вылавливать домены которых нет в dat файлах


    1. Anton_Kazantsev
      13.10.2024 15:23

      как вы их вылавливаете? через что?


      1. Artem_Khromov
        13.10.2024 15:23

        PCAPdroid


        1. Grey83
          13.10.2024 15:23

          вроде есть ещё Reqable с аналогичным фунционалом (правда юзал только Packet Capture и совсем немного PCAPdroid)