Openwrt dns over https настройка

Обновлено: 25.09.2022

OpenWrt ставится на очень много моделей soho роутеров, конфигурируется и расширяется как душа пожелает. Сейчас многие прошивки роутеров — это надстройки над OpenWrt.

Wireguard используется из-за его быстрой и простой настройки, а так же из-за высокой скорости передачи через туннель.

Автоматически развертываем с помощью Ansible

Playbook и темплейты лежат на github. Используется модуль, в нём не нужен python на роутере и есть поддержка uci. Я постарался сделать так, что бы ваша конфигурация OpenWrt осталась не тронутой, но всё равно будьте бдительны.

Устанавливаем модуль gekmihesg/ansible-openwrt:

Копируем плейбук и темлпейты:

Добавляйте ваш роутер в hosts:

Подставляете свои переменные в hirkn.yml:

Обязательно нужно задать:

wg_server_address — ip/url wireguard сервера
wg_private_key, wg_public_key — приватный ключ клиента и публичный сервера
Остальное можно не менять или менять, в зависимости от того как настроен WireGuard сервер

После выполнения плейбука, роутер сразу начнёт выполнять обход блокировок через ваш wireguard сервер.

Блокировки

Грубо говоря, существует два типа блокировок:

Нам нужно победить оба. Разберёмся с каждым из них по порядку.

1. Устанавливаем и настраиваем Pi-Hole

Pi-Hole — это известная домашняя платформа, предназначенная прежде всего для борьбы с рекламой через блокирование запросов к доменам из централизованно обновляемого списка. Не то чтобы это был необходимый компонент решения, но если начал собирать домашний DNS, становится трудно остановиться. А если серьезно — Pi-Hole, возможно, и не идеален, но снимает большой объем головной боли с человека, которому надо "чтобы работало".

Чтобы установить Pi-Hole на уже имеющийся у нас запущенный Linux-сервер, нам достаточно выполнить одну команду:

И далее запущенный скрипт проведет вас по шагам установки.

В момент, когда он спросит вас про выбор Upstream DNS Provider, вы можете выбрать любой, поскольку на следующем шаге мы всё равно будем его менять. Все остальные параметры можно смело оставлять по умолчанию.

В конце инсталляции скрипт покажет вам сгенерированный случайным образом пароль от веб-интерфейса, который вам было бы полезно записать.

Если что-то при установке пошло не так — можно использовать альтернативные способы, описанные тут.

Шаг 3. Скрипт для сбора списков заблокированных адресов

Это возможно благодаря крутейшему сервису antifilter.download, который обрабатывает выгрузки Роскомнадзора и отдает их в виде списков IP-адресов в машиночитаемых форматах. Мы настроим периодическую выгрузку списков заблокированных адресов с antifilter.download, чтобы всегда иметь актуальную информацию о блокировках. По моему опыту обновлять этот список раз в сутки (например, ночью) вполне достаточно.

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

Начнём со скрипта, который реализует эту логику по обновлению списков заблокированных адресов.

Создадим файл /etc/init.d/hirkn со скриптом следующего содержания:

Этот скрипт скачивает два списка заблокированных адресов — один в виде сетей (иногда РКН блокирует адреса целыми подсетями), другой — обобщенный список отдельных заблокированных адресов. За счёт обобщения в небольшие подсети он содержит не миллионы строк, а всего лишь что-то около 15 тысяч. Нам нужны оба списка, они не пересекаются между собой. Файлы сохраняются в каталог /tmp , который в OpenWRT хранится в оперативной памяти — это должно работать быстро. В конце скрипт перезапускает файлволл. Настройка файлволла будет происходит позже.

Добавим этому скрипту права на выполнение:

Добавим скрипт в "автозапуск", чтобы он выполнялся при включении роутера после всех остальных скриптов:

Через cron запланируем выполнение этого скрипта раз в сутки:

В открывшемся редакторе нужно добавить на новой строке:

На crontab.guru можно посмотреть объяснение этой строчки.

Включим cron , потому что по умолчанию в OpenWRT он выключен:

Убедимся, что скрипт работает.

Если файлы со списками заблокированных адресов появились, то всё ок:

Настройка WireGuard на сервере

Я проделываю всё на Ubuntu 18.04, но в официальной документации есть инструкции по установке для всех известных и не очень ОС.

3. Настраиваем ваш домашний роутер

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

1) У роутера можно задать кастомный DNS-сервер в настройках WAN-интерфейса, даже если IP-адрес получается от провайдера динамически

2) Роутер выдает внутренним клиентам свой адрес в качестве DNS и переправляет их запросы на тот сервер, который указан в настройках WAN

Соответственно, в этом случае нам необходимо и достаточно прописать адрес нашего Pi-Hole в качестве DNS-сервера в настройках WAN-интерфейса домашнего роутера. Важно, чтобы он был единственным DNS-сервером в настройках, если будет указан какой-то еще — роутер будет балансировать запросы между ними по только ему известному принципу и такая ситуация крайне неудобна для отладки проблем в сети.

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

Если у вас роутер более умный и, например, имеет возможность указать в DHCP, какой адрес раздавать клиентам в качестве DNS-сервера, можете пойти по альтернативному пути и настроить раздачу адреса Pi-Hole клиентам напрямую. Это немного разгрузит роутер, но зато усложнит вышеописанный откат с использования сервиса.

В случае, если что-то не будет получаться — спрашивайте в комментариях, найдем решение.

Default Settings

Default configuration has the service disabled (use Web UI to enable/start service or run uci set simple-adblock.config.enabled=1; uci commit simple-adblock; ) and selected ad/malware lists suitable for routers with 64Mb RAM.

If your router has less then 64Mb RAM, edit the configuration file, located at /etc/config/simple-adblock . The configuration file has lists in ascending order starting with smallest ones and each list has a preceding comment indicating its size, comment out or delete the lists you don’t want or your router can’t handle.

Features

If you want a more robust AdBlocking, supporting free memory detection and complex block-lists, supporting IDN, check out net/adblock on GitHub/jsDelivr.

Requirements

Starting with OpenWrt 19.07 and up the required packages should be automatically installed when you install simple-adblock .

4. Решаем проблемы

В целом после выполнения вышеописанных пунктов у вас уже всё должно быть хорошо, но бывают нюансы, с которыми я и мои клиенты иногда сталкивались.

Обнаружить такую проблему достаточно просто — если вы пытаетесь зайти на заблокированный сервер, ваш браузер показывает вам ошибку ERR_NAME_NOT_RESOLVED или подобную, а проверка в командной строке через nslookup в ответ выдает 0.0.0.0.

Также регулярно бывает, что Pi-Hole инсталлируют на сервер, на котором уже работает какой-то веб-сервис. В этом случае вы не получите доступа к веб-интерфейсу управления. Как разруливать такой конфликт — зависит от конкретной ситуации, но основные пути решения — это:

Documentation / Discussion

Please head to OpenWrt Forum for discussion of this package.

How To Use

Once the service is enabled in the config file, run /etc/init.d/simple-adblock start to start the service. Either /etc/init.d/simple-adblock restart or /etc/init.d/simple-adblock reload will only restart the service and/or re-download the lists if there were relevant changes in the config file since the last successful start. Had the previous start resulted in any error, either /etc/init.d/simple-adblock start , /etc/init.d/simple-adblock restart or /etc/init.d/simple-adblock reload will attempt to re-download the lists.

If you want to force simple-adblock to re-download the lists, run /etc/init.d/simple-adblock dl .

How To Customize

You can use Web UI (found in Services/Simple AdBlock) to add/remove/edit links to:

    (127.0.0.1 or 0.0.0.0 followed by space and domain name per line) to be blocked.
  • domains lists (one domain name per line) to be blocked.
  • domains lists (one domain name per line) to be allowed. It is useful if you want to run simple-adblock on multiple routers and maintain one centralized allow-list which you can publish on a web-server.

You can also use Web UI to add individual domains to be blocked or allowed.

If you want to use CLI to customize simple-adblock config, refer to the Customization Settings section.

Установка пакетов

Насчет занимаемого места на флеше, на всё понадобится примерно 0.9МБ. Если у вас совсем плохо с местом, замените curl wget'ом и можете не ставить dnscrypt-proxy.

Ставим пакеты. В OpenWrt это просто сделать через менеджер пакетов opkg:

How It Does Not Work

For most of the DNS Resolution Options to work, your local LAN clients need to be set to use your router’s DNS (by default 192.168.1.1 ). The dnsmasq.addnhosts is the only option which can help you block ads if your local LAN clients are NOT using your router’s DNS. There are multiple ways your local LAN clients can be set to NOT use your router’s DNS:

If you are running a wireguard “server” on your router and remote clients connect to it, the AdBlocking may not work properly for your remote clients until you add the following to /etc/network (credit to dibdot):

Настройка роутера

Я использую OpenWrt версии 18.06.1 на Xiaomi mi 3G и Asus RT-N16.

Немного о WireGuard

В нашем случае сервер — это VPS вне РКН, клиент — OpenWrt роутер дома. Когда вы захотите зайти на pornolab telegram, ваш роутер направит трафик через сервер с WireGuard.
WireGuard поднимает site-to-site соединение, т.е. и у сервера и у клиента имеется серверная и клиентская часть конфигурации. Если не понятно — станет понятно когда увидите конфигурацию.

У сервера и у клиента есть свои собственные приватный и публичный ключи.

Логика работы роутера

Загружаем списки, помещаем их в iptables, все адреса из этих списков iptables помечает маркером 0x1. Далее все пакеты помеченные 0x1 идут в отдельную таблицу маршрутизации, все пакеты попавшие в эту таблицу маршрутизации идут через wg интерфейс.

DNS Resolution Option

Thanks

I’d like to thank everyone who helped create, test and troubleshoot this service. Special thanks to @hnyman for general package/luci guidance, @dibdot for general guidance and block-list optimization code, @ckuethe for the curl support, non-ASCII filtering and compressed cache code, @EricLuehrsen for the Unbound support information, @vgaetera for firewall-related advice, @mushoz for performance testing and @phasecat for submitting various bugs and testing.

Конфигурация таблицы маршрутизации

Создаем таблицу маршрутизации для трафика через туннель, просто добавив строку:

в файл /etc/iproute2/rt_tables.

Создать дефолтный маршрут для таблицы "vpn" через wg интерфейс можно командой:

Но при рестарте сети маршрут пропадёт, поэтому создаём файл 30-rknroute в директории /etc/hotplug.d/iface/ с простым содержимым:

Это означает, что при включении\выключении интерфейсов будет добавляться наш маршрут. И соответственно, этот маршрут будет всегда прописан.

Unmet Dependencies

If you are running a development (snapshot) build of OpenWrt on your router and your build is outdated (meaning that packages of the same revision/commit hash are no longer available and when you try to satisfy the requirements you get errors), please flash either current OpenWrt release image or current development/snapshot image.

Configuration Settings

In the Web UI the simple-adblock settings are split into basic and advanced settings. The full list of configuration parameters of simple-adblock.config section is:

Конфигурация

Конфиг хранится в /etc/wireguard/wg0.conf. Серверная часть выглядит так:

Address — адрес для интерфейса wg (адрес внутри туннеля)
PrivateKey — Приватный ключ (privatekey-server)
ListenPort — Порт на котором служба ожидает подключения

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

PublicKey — публичный ключ нашего роутера (publickey-client)
AllowedIPs — подсети, которые будут доступны через этот туннель. Серверу требуется доступ только до адреса клиента.

Обе части хранятся в одном конфиге.

Включаем автозапуск при перезагрузке:

Делаем сервер маршрутизатором:

Настроим фаервол. Предположим, что у нас на сервере только WireGuard и ssh:

Сохраним конфигурацию iptables:

Поднимаем wg интерфейс первый раз вручную:


WireGuard сервер готов.

UPD 27.06.19 Если ваш провайдер до сих пор использует PPoE, то нужно добавить правило. Спасибо denix123

Screenshots (luci-app-simple-adblock)

Configuration - Basic Configuration

Configuration - Advanced Configuration

Allowed and Blocked Lists Management

screenshot

Disclaimer

Поскольку публиковать способы обхода блокировок доступа к информации, запрещенной на территории Российской Федерации, не очень законно, целью этой статьи будет рассказать о методе, позволяющем автоматизировать получение доступа к ресурсам, разрешенным на территории Российской Федерации, но из-за чьих-то действий недоступным напрямую через вашего провайдера. А доступ к другим ресурсам, получаемый в результате действий из статьи, является досадным побочным эффектом и целью статьи ни в коем случае не является.

Разворачиваем собственный DNS-сервер на базе Pi-Hole, использующий Cloudflare DoH для запросов в мир. Цель — зашифровать все DNS-запросы и обойти таким образом операторскую фильтрацию через перехват DNS. Полезный бонус — фильтрация рекламы.

Никаких волшебных know-how не открывается, простая пошаговая инструкция для тех, кому не хочется разбираться во всех хитросплетениях самому.

2. Устанавливаем и настраиваем cloudflared

Тут для установки нам потребуется приложить немного больше усилий, но тоже ничего особо сложного.

Выбираем и загружаем инсталлятор для нашей платформы.

После выполнения последней команды мы должны получить вывод, подобный следующему:

Если он у вас такой (естественно, номер версии и билда может отличаться) — то поздравляю, установка прошла успешно. Теперь дело за настройкой.

Создаем пользователя для работы сервиса:

Создаем файл конфигурации сервиса /etc/default/cloudflared:

И даем на него и на исполняемый файл права свежесозданному пользователю:

Далее создаем файл /lib/systemd/system/cloudflared.service, который даст нам возможность интеграции сервиса в systemd:

Активируем сервис и запускаем его:

Если всё получилось — вы увидите, что сервис в состоянии active (running).

Вы можете проверить работу сервиса, например командой dig:

Осталось только подключить сервис к Pi-Hole. Для этого вы заходите в веб-интерфейс Pi-Hole (тут вам пригодится записанный в первом этапе пароль), идете в пункт меню Settings — DNS и делаете его выглядящим приблизительно вот так:

Screenshot of Pi-hole configuration

Если вы забыли записать пароль — ничего страшного, заходите на сервер через ssh и исполняете команду pihole -a -p, она позволит задать новый пароль. Ну и в целом посмотрите ключи команды pihole, там много интересного. Например, обновление системы делается одной командой pihole -up.

Requirements for DNS Resolver

In order to actually block the ads, this service requires one of the following DNS resolvers to be installed on your router: dnsmasq or dnsmasq-full or unbound . The dnsmasq package is usually included in the default OpenWrt installation.

If you want to use the dnsmasq.ipset option you need to install ipset and dnsmasq-full instead of the dnsmasq . To do that, connect to your router via ssh and run the following command:

Роутер и прошивка

OpenWRT — это опенсорсный проект, который разрабатывает прошивки для роутеров на основе Linux. В той или иной мере, пожалуй, поддерживаются все существующие девайсы. Внутри есть даже свой собственный пакетный менеджер. Так как роутер с OpenWRT — это почти настоящая линукс-машина, то открывается огромное поле для различных извращений — файловые шары, торрент-клиенты, блокировка рекламы на уровне роутера, VPN — да что угодно.

Мой нынешний роутер — это Xiaomi Mi WiFi Router 3G. Выбрал его, потому что в нём достаточно мощи, чтобы на нём хорошо работала OpenWRT. Да и вообще, Mir3G — это, похоже, один из самых популярных девайсов в тусовке людей, которые занимаются дрессировкой роутеров, так что в сети по нему уже есть много мануалов и обсуждений на форумах. Если захотите купить такой же, то будьте аккуратны с конкретной моделью — их две под одним названием, а хорошая только та, у которой есть порт USB3. Такой роутер должно быть несложно купить на Авито или других досках объявлений.

У меня на данный момент установлена почти последняя версия прошивки:

Прошивка OpenWRT и базовая настройка роутера выходит за рамки этой статьи. Поищите мануалы для вашего роутера. Далее предполагается, что у вас уже есть роутер с OpenWRT, подключенный к интернету, и к нему настроен доступ по SSH.

Что вам для этого потребуется

  1. Доверять Cloudflare. На самом деле это очень важный пункт, поскольку в описываемой реализации все ваши DNS-запросы обрабатываются сервисом Cloudflare. Если вы ему не доверяете — вам придется внедрить другое решение (и это немногим сложнее, чем описанное, но целью этой статьи не является).
  2. Иметь возможность поддерживать в домашней сети постоянно работающий сервер с Linux, который будет обслуживать DNS-запросы ваших устройств. Требование Pi-Hole — от 512M оперативной памяти (впрочем, работу с меньшим объемом сам не проверял). Если ваш роутер или NAS умеют виртуальные машины — это прекрасный вариант, если на полке где-то завалялась Raspberry Pi или другой микрокомпьютер на ARM — не менее хорошо, если на антресолях в коридоре жужжит виртуальная ферма на ESXi — то что я вам рассказываю, вы и сами всё знаете. Если у вас ничего из этого нет — самые младшие решения, типа Orange Pi Zero, на вторичном рынке можно найти за единицы сотен рублей либо привезти из Али за плюс-минус те же деньги. Но выбор платформы сильно выходит за рамки этой статьи, поэтому считаем, что у вас что-то есть. Впрочем, вопросы на этот счет можно задавать в комментариях.
  3. Вы должны иметь представление о использовании Linux и сетевых технологиях. Или хотя бы хотеть получить такое представление. Поскольку объять необъятное в этот раз я не готов, некоторые непонятные для вас моменты вам придется изучить самостоятельно. Впрочем, на конкретные вопросы, конечно же, отвечу в комментариях и вряд ли окажусь единственным отвечающим, так что не стесняйтесь спрашивать.

Шаг 5. Отключаем IPv6

Этот шаг мой самый нелюбимый, потому что я за всё новое и против всего старого. По моему глубокому убеждению IPv4 уже давно должен умереть и быть вытеснен шестой версией протокола. К сожалению, дела у IPv6 пока идут не так гладко, как хотелось бы (сейчас он занимает всего около 30% процентов трафика).

Проблема в том, что antifilter.download выдаёт только заблокированные IPv4 адреса. Это значит, что наш обход блокировок не будет работать по IPv6. Если разрешить вашему роутеру работать по IPv6, то многие ваши устройства предпочтут открывать сайты по IPv6 либо напарываясь на страницы с блокировками от провайдеров, либо просто получая ошибки подключения по таймауту.

Отключаем IPv6 (команды взяты отсюда):

После этого может потребоваться ещё одна перезагрузка роутера, чтобы он перестал раздавать вновь подключенным устройствам IPv6-адреса.

Вот как-то так можно при помощи несложных (ладно, сложных) манипуляций настроить свой роутер на точечный обход блокировок. Все незаблокированные сайты работают как обычно, а заблокированные — через VPN. С такой конфигурацией можно полностью забыть про мелкие пакости от Роскомнадзора и начать, наконец, жить :)

image

После сравнительно недавнего анонса компанией Mozilla запуска поддержки DNS-over-HTTPS (DoH) в продакшн в сети не утихают споры, зло это или благо. По моим ощущениям, позиция "зло" базируется в основном на том, что при этом манипуляция вашими DNS-запросами даже в полезных для вас целях будет затруднена, поэтому я пока что остаюсь на позиции "благо".

В Российской Федерации операторы связи, поставленные в очень жесткие условия нашим законодательством, вынуждены строить изощренные многоуровневые системы блокировок доступа к запрещенному Роскомнадзором на территории РФ контенту, на одном из уровней которых более-менее успешно работает перехват DNS-запросов. Использование DoH позволит обойти этот уровень, что в совокупности с использованием VPN может несколько облегчить вам жизнь. Обратите внимание, само по себе решение не может избавить вас от блокировок, потому что вряд ли в России есть провайдер, полагающийся только на фильтрацию через DNS. Вам нужен еще какой-то вариант обойти блокировки, например VPN, один из описанных в моих предыдущих статьях.

Парадоксально, но в текущем паноптикуме оператору связи ничем не грозит ваш обход его блокировок (с использованием специальных средств для этого), поэтому если вы опасаетесь навредить ему таким образом — эти опасения напрасны.

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

How Does It Work

This service downloads (and processes in the background, removing comments and other useless data) lists of hosts and domains to be blocked, combines those lists into one big block-list, removes duplicates and sorts it and then removes your allowed domains from the block-list before converting to to DNSMASQ/Unbound-compatible file and restarting DNSMASQ/Unbound if needed. The result of the process is that DNSMASQ/Unbound return NXDOMAIN or 127.0.0.1 (depending on settings) for the blocked domains.

In general, whatever domain is specified to be allowed; it, along with with its subdomains will be allowed, but not any fake domains containing it.

Requirements for IPv6 Support

For IPv6 support additionally install ip6tables-mod-nat and kmod-ipt-nat6 packages from Web UI or run the following in the command line:

Шаг 1. Шифрованный DNS

DNS (Domain Name System) — это распределенная система (нет, это не сеть магазинов), состоящая из множества серверов по всему миру, которая позволяет вашему компьютеру преобразовать человекочитаемое имя сайта в машиночитаемый IP-адрес, например, из github.com получить 140.82.121.3 . Этот процесс называется "разрешением" или "резолвингом" доменного имени.

Блокировка по доменным именам зачастую реализуется провайдером следующим образом: ваш роутер по умолчанию использует DNS-сервер, который контролируется провайдером и для заблокированных доменных имён возвращает специальный адрес сайта-заглушки. Именно это происходит, когда вы видите в браузере "доступ к ресурсу ограничен в соответствии со 149-ФЗ".

Доступ ограничен

Кажется, что решение очевидно — просто не пользоваться DNS-сервером провайдера, а использовать, например, Google DNS, IP-адреса которого уже стоит знать наизусть как считалку — 8.8.8.8, 8.8.4.4 . Раньше это действительно работало, но сегодня провайдеры уже не дадут вам так просто себя обмануть.

Поскольку DNS — это очень старый протокол, в котором никак не было предусмотрено шифрование от слова "вообще", у провайдеров есть возможность перехватывать ваши запросы и подменять ответы, вставляя свой сайт-заглушку, даже если запрос шёл, например, к Google DNS. Именно этим они и занимаются. По сути, провайдер проводит против вас атаку DNS hijacking.

Вот как это работает, если всё хорошо. В таком сценарии можно даже не заметить этого "человека посередине" в лице вашего провайдера:

DNS-запрос к незаблокированному домену

А вот так это работает, когда всё плохо. Провайдер наверняка даже не отправляет запрос к DNS-серверу, которому он предназначался, а просто сразу же возвращает ответ, подставляя адрес своей заглушки:

DNS-запрос к заблокированному домену

Но по-настоящему эффективное решение есть. Если провайдер не сможет увидеть, к какому домену происходит обращение, то не сможет и подменить ответ. А ещё лучше, если он вообще не будет знать, что происходит резолвинг имени. Этого можно достичь шифрованием.

Обновим список пакетов. Эту команду нужно выполнять после каждой перезагрузки роутера перед установкой пакетов:

Чтобы плагин для LuCI заработал, нужно сделать выполнить вот такую команду:

Готово! Теперь на компьютере, подключенном к роутеру, можно проверить как это работает:

Обратите внимание, что адреса возвращаются разные: до настройки DoH — неправильный, это результат подмены адресов провайдером, а после — правильный. Можно считать это маленькой победой!

OpenWRT LuCI DoH settings

Сам по себе обход блокировок по DNS вряд ли даст ожидаемый эффект, потому что, как правило, в довесок к доменному имени, ресурс блокируется еще и по IP-адресам — видимо, для надежности. Это следующий тип блокировок, которые нужно победить.

Стоит упомянуть про побочные эффекты от такой настройки — могут стать недоступными различные внутренние ресурсы провайдера. Например, когда у меня кончается интернет и я забываю его оплатить, провайдер просто не может меня переадресовать на страницу, куда он обычно направляет своих забывчивых абонентов. Для меня выглядит это всё так, будто интернет просто пропал, без каких-либо объяснений. Я даже первый раз из-за этого чуть не поругался с поддержкой, а оказалось, что это я сам дурак. Что ж, просто приходится платить заранее.

Если нравится статья, то подпишитесь на уведомления о новых постах в блоге, чтобы ничего не пропустить! А ещё читайте другие мои посты!

Requirements for Faster Block-list Processing

The gawk , grep , sed and coreutils-sort are the optional, but recommended packages as they speed up processing dramatically. You can install these recommended packages by running the following command:

Загрузка списков

Всё, что можно сделать через стандартные возможности OpenWrt, сделано через них. Всё остальное (кроме hotplug) я поместил в небольшой скрипт:

Списки запрещенных подсетей и адресов получаем файлами. Для них создаём директорию в /tmp. В /tmp — потому что это RAM, такая особенность OpenWrt, довольно удобная. На ROM роутера что-то писать лишний раз не стоит.

Выкачиваем списки с antifilter.download curl'ом, флаг z означает, что curl будет скачивать файл, только если удаленный файл отличается от локального или если его нет, как например в случае при загрузке роутера.

subnet.lst — список заблокированных подсетей, изменяется не часто.
ipsum.lst — список заблокированных адресов, который суммаризирован по маске. Вместо 150 тысяч записей получаем 15 тысяч — удобно.

После того как файлы у нас — рестартуем firewall, это нужно для того что бы ipset отработал и добавил списки в iptables, ipset у нас будет сконфигурен в /etc/config/firewall.

Скрипт этот мы добавляем в /etc/init.d/ назовём hirkn. Сделаем его исполняемым

Теперь у нас не просто скрипт, а целая служба. Для того, что бы он запускался при загрузке, делаем симлинк в /etc/rc.d. Нам нужно, что бы он запускался после всех остальных служб, поэтому делаем приставку S99

Списки нужно обновлять время от времени, добавляем запись в cron:

Мне кажется вполне достаточным обновлять их раз в сутки. Имейте в виду, что при добавлении списков в ipset, отваливается сеть, в моём случае это 2 секунды.
UPD: Если не хотите разрывов, то sigo73 и Grayver подсказали в комментариях как это осуществить.

Так же включите крон, по дефолту он отключен:

Шаг 2. Настройка VPN WireGuard

Для того, чтобы обходить блокировки по IP-адресам, придётся настроить VPN — другого способа нет. VPN "спрячёт" от провайдера ваши IP-пакеты так, что он не будет знать куда именно они направляются и что в себе содержат. В качестве протокола предлагаю использовать WireGuard — легковесный VPN-протокол, который к тому же довольно легко настраивать.

Всё описанное дальше вдохновлено и по сути является пересказом вот этой замечательной статьи на Хабре с некоторыми (минимальными) дополнениями от меня.

VPN — это клиент-серверный протокол. Наш роутер будет клиентом, но также нам обязательно нужен сервер. Можно либо поднять свой VPN-сервер самостоятельно (смотрите инструкцию в статье по ссылке выше, это не сложно), либо оформить подписку на какой-нибудь готовый VPN-сервис. Я пробовал оба варианта, но поддерживать свой VPN-сервер оказалось достаточно трудозатратно, и это тоже, как ни странно, стоит денег. Сложнее всего найти хостинг для своего VPN с незаруиненной репутацией. Проблема, с которой я столкнулся, заключалась в том, что все дешевые хостинги уже имеют плохую репутацию (спасибо вам, господа спамеры), и некоторые ресурсы, типа Пикабу (который тоже, как выяснилось, немножко заблокирован), сразу же заранее отвечают ошибкой 403. Намного проще купить готовый VPN, и пусть лучше кто-то другой за меня беспокоится о том, чтобы мне были доступны все нужные мне сайты.

В последнее время появляется очень много VPN-сервисов, которые работают по протоколу WireGuard — это нынче горячая тема. Недавно поддержка WireGuard была добавлена в основной состав ядра Linux. Погуглите, выбор сервисов действительно есть. Сейчас я пользуюсь RedShieldVPN, и меня пока что всё устраивает.

Бонус для читателей: при регистрации по этой ссылке вам подарят месяц бесплатного VPN.

Дальше буду описывать процесс для RedShieldVPN, но, думаю, для других подобных сервисов процесс должен быть похожим.

Переходим в раздел WireGuard, авторизуемся, выбираем страну и скачиваем конфиг. Я обычно выбираю какую-нибудь европейскую страну, чтобы пинг был приемлемым. В этот раз возьму Финляндию.

Вот примерно такой файл конфигурации скачался (ключи я заменил):

Переключимся на роутер и установим там нужную зависимость:

Дальше нужно настроить сеть. Это происходит в файле /etc/config/network . Открываем его при помощи vi (если не умеете пользоваться этим редактором, то лучше предварительно почитайте что-нибудь для подготовки психики) и дописываем в конец две секции вот такого содержания:

Приватный и публичный ключи замените соответствующими значениями из конфига. Поле list addresses заполняется IPv4-адресом из строчки Address в конфиге, а IPv6 адрес мы просто игнорируем — позже станет понятно почему. Поле Endpoint из конфига WireGuard распадается, соответственно, в поля endpoint_host и endpoint_port в конфиге OpenWRT. Остальные поля статичные.

Перезапустим сеть на роутере:

Если команда wg show выводит что-то подобное, то всё идёт хорошо.

Конфигурация сети

Нам необходимо сконфигурировать WireGuard и правило для пакетов с меткой 0x1.

Конфигурация WireGuard располагается в /etc/config/network

private_key — это privatekey-client, который мы генерировали при настройке сервера
list addresses — адрес wg интерфейса
listen_port — порт на котором WireGuard принимает соединения. Но соединение будет происходить через порт на сервере, поэтому здесь мы не будем открывать для него порт на firewall
proto — указываем протокол, что бы openwrt понимало что это конфигурация WireGuard

public_key — ключ publickey-server
allowed_ips — подсети, в которые может ходить трафик через тунель, в нашем случае никаких ограничей не требуется, поэтому 0.0.0.0/0
route_allowed_ips — флаг, который делает роут через wg интерфейс для перечисленных сетей из параметра allowed_ips. В нашем случае это не нужно, эту работу выполняет iptables
endpoint_host — ip/url нашего wg сервера
persistent_keepalive — интервал времени, через который отправляются пакеты для поддержки соединения
endpoint_port — порт wireguard на сервере

Ещё в конфигурацию network добавим правило, которое будет отправлять весь трафик, помеченный 0x1, в таблицу маршрутизации "vpn":

Исходные данные

IPv4-адрес нашего сервера в домашней сети: 192.168.1.10 и он назначен как статический.

Настройки на Linux выполняем от root (т.е. перед началом настройки выполняем команду sudo su -).

Установка


Установите software-properties-common — пакет предоставляет возможность добавления и удаления PPA

Генерируем ключи для сервера. Ключи сохраним в директории WireGuard для удобства

Соответственно в файле privatekey-server будет приватный ключ, а в publickey-server — публичный.
Так же сгенерируем сразу ключ для клиента:


Бонусом настроим DNSCrypt

Зачем? Ваш провайдер может заботливо подменять ip-адрес заблокированного ресурса, таким образом перенаправляя вас на свой ip с заглушкой, ну и наш обход по ip в данном случае не поможет. Для подмены не всегда даже нужно использовать dns сервер провайдера, ваши запросы могут перехватываться и ответы подменяться. Ну и к слову, это может делать не только провайдер.

Настраиваем конфиг /etc/config/dnscrypt-proxy примерно так:

Таким образом у нас есть сервис dnscrypt на порту 5353 доступный на localhost.

Настраиваем dnsmasq на работу с dnscrypt. В /etc/config/dhcp комментируем строчку:

для того что бы не были задействованы dns серверы провайдера.

Запись list server 'domain/ip_dns' указывает какой dns сервер использовать для резолва указанного домена. Таким образом мы не задействуем dnscrypt для синхронизации ntp — для работы службе dnscrypt важно иметь актуальное время.

При загрузке роутера, скрипт hirkn запускается быстрее чем стартует dnscrypt, таким образом домен antifilter.download не резолвится и списки не скачиваются. Можно сделать задержку или ещё что придумать, но пока что не вижу смысла.
UPD: необходимо добавить строку

В итоге мы получаем такую вставку в конфиг:

Отключаем использование провайдерских DNS для интерфейса wan
В /etc/config/network добавляем строку

к интерфейсу wan.
Получаем такую конфигурацию

Добавляем в автозагрузку и стартуем dnscrypt:


Илюстрация работы без DNSCrypt и c DNSCrypt

Шаг 4. Дальнейшая настройка

Теперь осталось настроить роутер так, чтобы он правильно маршрутизировал пакеты через VPN-туннель.

Создадим таблицу маршрутизации для VPN, добавив в файл /etc/iproute2/rt_tables строчку следующего вида:

Добавим дефолтный маршрут для VPN через туннельный интерфейс:

Чтобы сделать это изменение постоянным, чтобы оно переживало перезагрузки роутера, создадим файл /etc/hotplug.d/iface/30-rknroute с вот таким содержимым:

В файл /etc/config/network , который мы уже редактировали в процессе настройки WireGuard, добавим правило, которое будет перенаправлять маркированные пакеты в таблицу маршрутизации VPN:

Теперь приступим к настройке файрволла. Это самая важная часть логики, которая просматривает списки заблокированных адресов, и маркирует пакеты. В файл /etc/config/firewall допишем несколько абзацев:

Первый из них настраивает зону для VPN — из неё разрешён лишь выход пакетов и включён маскарадинг.

Второй абзац разрешает переход из зоны lan , где по умолчанию находятся все устройства, подключенные к роутеру, в зону для VPN.

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

Пятый и шестой абзацы отвечают за маркировку пакетов: "если пакет направляется на заблокированный адрес, то добавим ему пометку 0x1 ".

И запустим наш скрипт:

После этого трафик к заблокированным сайтам должен побежать через VPN. Если нет, то попробуйте перезагрузить роутер.

Собственно решение

Requirements for file:// Scheme

If you want to include some local files as the allow-lists or block-lists, you need to install curl :

How To Install

Install simple-adblock and luci-app-simple-adblock packages from Web UI or run the following in the command line:

If simple-adblock and luci-app-simple-adblock packages are not found in the official feed/repo for your version of OpenWrt, you will need to add a custom repo to your router following instructions on GitHub/jsDelivr first.

Почему не BGP?

Под openwrt есть две утилиты реализующих BGP — quagga и bird. Quagg'у мне не удалось заставить забирать данные с antifilter. Bird подружился с сервисом с полпинка, но как заставить добавлять полученным подсетям интерфейс по умолчанию я, к сожалению, не понял. (Буду рад узнать как это можно реализовать).

В комментариях к подобным статьям я видел, что роутеры у людей "призадумывались" на некоторое время, когда те загоняют списки в таблицу маршрутизации. С реализацией через ipset мой Xiaomi mi 3G задумывается на 2 секунды (Asus rt-n16 на 5 секунд), когда скармливаешь ему список из 15ти тысяч подсетей. При дальнейшей работе нагрузки на процессор не замечал.

Все материалы не являются призывом к действию и представлены для ознакомления с функционалом ОС Linux.

Resistance Dog Good Boy

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

Так как большая часть моего трафика всё-таки ходит к незаблокированной части интернета, то логично пускать через VPN лишь тот трафик, который в этом нуждается. Ну нет ведь смысла гонять через VPN просмотр видео на YouTube или какую-нибудь игру? В итоге получится просто более медленный доступ, а профита никакого.

Стоит отметить, что если вам нужен обход блокировок только на одном устройстве, там вам намного проще будет настроить VPN именно на нём. У многих провайдеров VPN есть программы-клиенты, которые в несколько кликов по красивым кнопкам настроят вам всё, что нужно — просто погуглите, сравните цены и условия. Ещё можете посмотреть в сторону таких бесплатных проектов, как АнтиЗапрет.

Опишу свой процесс настройки роутера на OpenWRT с точечным обходом блокировок. Мне уже приходилось делать это пару раз (то переезд со сменой провайдера, то смена роутера), и вот на третий раз я решил наконец задокументировать этот процесс, чтобы в следующие разы было легче. Может и ещё кому пригодится.

Заключение

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

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

P.S. Замечание от GennPen — при использовании DoH вы становитесь зависимыми от наличия у вас интернета и если на счету закончились деньги — то даже в личный кабинет провайдера зайти не сможете, чтобы их заплатить. Поэтому для таких сайтов в этом решении желательно прописать статические записи в Pi-Hole — это можно сделать в консоли командой pihole -a -r или просто вручную в файле /etc/hosts. В веб-интерфейсе для этого инструмент, к сожалению, не заложен.

Различные аспекты эксплуатации DNS уже неоднократно затрагивались автором в ряде статей опубликованных в рамках блога. При этом, основной акцент всегда делался на повышение безопасности этого ключевого для всего Интернет сервиса.

DOH

Отправка DNS-запроса может производится стандартными методами GET и POST. В первом случае запрос трансформируется base64URL-encoded строку, а во-втором — через тело POST-запроса в двоичной форме. При этом при запросе и при ответе DNS используется специальный MIME-тип данных application/dns-message.

Обратите также внимание на заголовок cache-control: в ответе со стороны веб-сервера. В параметре max-age содержится значение TTL для возвращаемой записи DNS (или минимальное значение если возвращается их набор).

Исходя из вышеизложенного, функционирование DoH сервера состоит из нескольких этапов.

Наиболее простым, быстрым и эффективным способом запустить свой собственный DNS-over-HTTPS сервер представляется использование HTTP/2 веб-сервера H2O, о котором автор уже вкратце писал (см. "Высокопроизводительный веб-сервер H2O").

В пользу этого выбора играет тот факт, что весь код собственного DoH сервра может быть полностью реализован средствами интегрированного в сам H2O интерпретатором mruby. Помимо стандартных библиотек, для обмена данными с DNS сервером необходима библиотека (mrbgem) Socket, которая, по счастью, уже включена в текущую девелоперскую версию H2O 2.3.0-beta2 присутствующую в портах FreeBSD. Впрочем, не трудно добавить её и в любую предыдущую версию клонировав репозиторий библиотеки Socket в каталог /deps перед компиляцией.

Конфигурация веб-сервера, в целом, стандартная.

Обратие внимание, что за обработку пакетов DNS отвечает локальный кэширующий сервер, в данном случае Unbound из стандратной поставки FreeBSD. С точки зрения безопасности это оптимальное решение. Впрочем, ничто не мешает заменить localhost на адрес другого DNS, который вы предполагаете использовать.

Отстаётся перезапустить H2O и посмотреть что же из этого получилось.

Итак, проверим результаты отправив вновь пробный запрос и посмотрев сетевой трафик при помощи утилиты tcpdump.

Теперь осталось активировать наш сервер в браузере Firefox. Для этого на страницы конфигурации следует изменить несколько настроек about:config.

Firefox DNS-over-HTTPS configuration

Во-первых, это адрес нашего API по которому браузер будет запрашивать в DNS информацию в network.trr.uri. Рекомендуется также указать IP домена из этого URL для безопасного разрешения в IP средствами самого браузера без обращения к DNS в network.trr.bootstrapAddress. И, наконец, собственно сам параметр network.trr.mode включающий использование DoH. Установка значения в "3" заставит браузер использовать исключительно DNS-over-HTTPS для разрешения имён, а более надёжное и безопасное "2" отдаст приоритет DoH отставив стандартное обращение к DNS в качестве резервного варианта.

Статья была полезной? Тогда прошу не стесняться и поддерживать деньгами через форму доната (ниже).

A simple DNSMASQ/Unbound-based AdBlocking service for OpenWrt.

Конфигурация firewall

Конфигурация фаервола находится в /etc/config/firewall

Добавляем зону для wireguard. В openwrt зоны — это кастомные цепочки в iptables. Таким образом создаётся зона с одним\несколькими интерфейсами и уже на неё вешаются правила. Зона для wg выглядит например вот так:

Мы разрешаем только выход трафика из интерфейса и включаем маскарадинг.

Теперь нужно разрешить переадресацию с lan зоны на wg зону:

Ну и последнее — это формирование списков в iptables с помощью ipset:

loadfile — файл из которого берем список
name — имя для нашего списка
storage, match — здесь указываем как хранить и какой тип данных. Будем хранить тип "подсеть"

UPD: Если хотите использовать список отдельных IP адресов, то вам необходимо увеличить размер списка ipset. В config ipset добавьте

Иначе вы будете получать ошибку

UPD: Добавим два правила маркировки пакетов

Эти правила подразумевают под собой, что все пакеты идущие в подсети из списков vpn_subnets и vpn_ipsum необходимо помечать маркером 0x1.

После этого рестартуем сеть:


и запускаем скрипт:

После отработки скрипта у вас должно всё заработать. Проверьте маршрут на клиенте роутера:

Кратко — логика решения

  1. Устанавливаем и настраиваем Pi-Hole
  2. Устанавливаем и настраиваем cloudflared
  3. Настраиваем ваш домашний роутер
  4. Решаем проблемы

Читайте также: