Как стать автором
Обновить

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

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

DNS некоторых сервисов (да хотя бы фейсбука) выдаёт разные IP в зависимости от геолокации клиента. И может внезапно выясниться, что полученный нашим маршрутизатором IP вообще недоступен с того зарубежного сервера, через который мы его маршрутизируем... и вот что с этим делать, решительно непонятно :(

У dnsmasq в OpenWrt есть такая настройка. Вы можете поднять dnsmasq на своём VPN-сервере и форвардить резолвинг для фейсбука (и других доменов, которые пропишете) на этот резолвер.

В Вашем упрощённом примере, когда маршрутизация идёт только по доменным именам, это сработает, да. Но обычно доменные имена - это только один из критериев. У меня, скажем, в правиле маршрутизации может быть либо IP, либо подсеть, либо номер AS, либо код страны для GeoIP, либо доменное имя. После чего всё это складывается/вычитается, суммаризуется, чтобы избежать повторов и пересечений, и формируются BGP community на каждую "точку выхода" (у меня их три - Нидерланды, Россия и Турция). Даже если на стадии ресолвинга доменных имён использовать для каждой точки свой DNS-сервер, это не помогает, когда тот самый "геоспецифичный" IP попал в маршруты по другому критерию.

Генацвале, статья называется "Маршрутизация по DNS в OpenWrt", а не "Решаем все проблемы фрагментации Интернета". Тем не менее, вы в своём каменте сформулировали потенциальную проблему, вам было дано решение сформулированной проблемы. Далее вы пытаетесь мне сказать, что это не универсальное решение - ну дак я и не претендую на его универсальность.

У меня, скажем, в правиле маршрутизации может быть либо IP, либо подсеть, либо номер AS, либо код страны для GeoIP, либо доменное имя.

У вас, скажем, это на какой железяке и ОС такие фокусы можно вытворять?

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

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

Ничего не понял. Если вы скажем для домена facebook.com делаете настойку, что его нужно резолвить через, скажем, Нидерланды, то логично и в policy routing прописать, что этот домен нужно роутить через Нидерланды. Тогда все карты вроде бы сходятся. Это ведь не так происходит, что facebook.com будет резолвится другим резолвером и поэтому не попадет в нужный nft set. Это именно, что его локальный dnsmasq прорезолвит и добавит его в nft set, просто он сделает это не через дефолтовый DNS-сервер, а через указанный.

Для Вашего примера из поста проблема будет, поэтому я про неё написал.
Вы ответили, как её для этого примера решить - ОК, это достаточно очевидно. Но поскольку вряд ли, как я предположил, весь используемый Вами механизм выборочной маршрутизации сводится к этому примеру (в конце концов, для того же FB Вы вряд ли будете вылавливать все его домены, а просто завернёте в тоннель всю AS32934) - то я написал ещё одно уточнение. В ответ Вы зачем-то возбудились и перешли на грузинский :)

Генацвале, статья называется "Маршрутизация по DNS в OpenWrt", а не "Решаем все проблемы фрагментации Интернета".

На Хабре обычно комментарии к статьям в 10 раз полезнее самих статей, в т.ч. и тем, что расширяют её предмет на смежные вопросы :)

У вас, скажем, это на какой железяке и ОС такие фокусы можно вытворять?

Linux, bird, unbound, много самописного кода. Но не суть, речь про принципы, реализация вопрос десятый. Тот же dnsmasq так, как Вы написали, умеет не только под OpenWRT, но и везде, куда его можно поставить (и вот это, кстати, неочевидная его фича и самое ценное открытие из Вашего поста - спасибо, буду думать, как его в своём случае применить).

Ничего не понял

Ещё раз - если Вы только по доменным именам настраиваете маршруты, то да, есть решение. Но Вы вряд ли так делаете, поскольку это долго и непродуктивно, доменные имена хороши для отдельных исключений, когда какой-то сайт ведёт себя странно, - а за базу мы всё-таки берём GeoIP, номера автономных систем или готовые списки заблокированных сайтов. И вот в этом случае, если facebook.com, как указано выше, попал в маршруты не в результате ресолвинга, а в составе AS32934 или списка от zapret-info/antifilter, - проблема будет.

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

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

Поэтому что касается фейсбука, то я вообще не буду добавлять его в какие-либо исключения, ибо у меня он не забанен.

Но! Давайте я пофантазирую, на тему того, как бы это сделал я, если бы у меня не было никаких списков, и стояла бы задача настроить это дело в РФ.

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

Да! Поэтому я бы настроил в дефолтовой таблице маршрутизации default route через VPN. Создал бы правило, заворачивающее всю зону .ru и .su в wan по указанному в статье методу. И дальше в процессе использования я бы понял, что с фейсбуком что-то не то, и добавил бы его в список особенного резолвинга в настройках dnsmasq. Всё как вы говорите - общий сетап с точечной настройкой исключений.

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

  • для пользователей в РФ - заблокированные в РФ (готовый список + дополнения в виде отдельных AS и доменов) или самостоятельно огородившиеся от российских IP (тут сборная солянка, добавляю по мере выявления) через Голландию, турецкие (тоже те ещё любители отгородиться от иностранных IP) - через Турцию, остальное напрямую;

  • для пользователей в Турции - российские через РФ, заблокированные в Турции через Голландию (последнее пока не реализовано ввиду малой востребованности, но есть наброски - там чуть сложнее, т.к. нет готового списка), остальное напрямую;

  • для пользователей вне РФ и Турции - российские через РФ, турецкие через Турцию, остальное напрямую.

И всё это в разных вариантах (VPN для мобильных пользователей, микротики для дома/офиса), по три протокола туннелей (по убыванию приоритета WG -> Amnezia-WG -> WG over Cloak) между всеми точками и OSPF для автоматического выбора хоть какого-то живого маршрута на случай блокировок VPN... В общем, хватает головной боли :)

И DNS реально добавляет проблем. Ладно геоспецифичные IP, их мало. Есть ещё CDN. А есть тупо ситуация, что у пользователя скэшировался IP от предыдущего подключения (например, мобильного интернета), а он приходит в дом/офис, где DNS-сервер уже другой... Короче, вот прям беспроблемный опыт, чтобы был доступ ко всему и вся подкапотная работа по маршрутизации была для пользователя вообще не видна, не получается никак...

Интересный сетап. Если запилите статью, то я с удовольствием почитаю её.

WG, конечно, бяка в том плане, что всегда сигнализирует, что всё ОК и линк якобы есть. Тут OSPF, конечно, кстати.

Не, статью я точно не осилю, там такой говнокод, прости Господи, что выкладывать стыдно (как обычно, всё начиналось с маленького скрипта для конкретной задачи, который потом оброс функциями и костылями и надо бы переписать с нуля нормально, но некогда, да вроде и так работает :) А без кода это будет как у той совы из анекдота, которая стратег, а как реализовать - придумайте как-нибудь сами :)

Создал бы правило, заворачивающее всю зону .ru и .su в wan по указанному в статье методу

Из России наружу - да. Но теоретически российские сайты с доменными именами в других зонах тоже могут огораживаться от зарубежных IP (хотя навскидку примеров не вспомню).

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

В общем, GeoIP в любом направлении получается гораздо более надёжным способом. А там уже можно исключения точечно добавлять.

В Вашем упрощённом примере, когда маршрутизация идёт только по доменным именам

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


Спасибо за статью. Очень обстоятельно и понятно написано.

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

Однако, получилось несколько отличий.

В качестве  домашнего маршрутизатора я использую виртуальную машину на x86 сервере. Обычный libvirt/qemu. Туда прекрасно встал образ OpenWRT для ПК.

На VPS хостинг где должен стоять VPN сервер тоже залит x86 образ OpenWRT. Исключительно из-за компактности, простоты настройки и нетребовательности по ресурсам.

Вместо WG, я использую ZeroTier в режиме  Ethernet моста без автоконфигурации IP. В этом случае VPNы выглядят как обычные Ethernet интерфейсы, и, соответственно настраиваются. Это удобно.

На сколько я понимаю, ZeroTier работает через userspace приложение, которое и осуществляет шифрование. То есть пакет при отправке проделывает следующий путь:

1) Ядро понимает, что пакет подлежит маршрутизации в VPN-интерфейс, и ставит его в очередь этого интерфейса

2) Юзерспейс апп вычитывает этот пакет и шифрует его, после чего отправляет его как обычный UDP пакет, пакет снова уходит в ядро

3) UDP пакет с шифрованным payload'ом отправляется через реальный интерфейс.

Таким образом, получается что на каждый акт маршрутизации пакета в VPN возникает необходимость сходить в юзерспейс и обратно. А WireGuard делает всё внутри ядра. Для железяки x86 это, полагаю, не суперважно, но на дохлых домашних роутерах, можно запросто уперется в CPU при большом потоке через VPN-интерфейс. Это надо иметь ввиду.

Да. Все верно. WG тут исключение из правил, он быстрее, и идеально подходит для создания постоянных L3 тоннелей на слабых роутерах.  И, если бы он умел L2 тоннели, было бы совсем хорошо. Правда, все не на столько плохо у остальных VPN-ов, т.к. в ядро можно сходить сразу за большой пачкой пакетов за раз, а не за каждым отдельно. Но, накладные расходы, конечно, все равно выше.

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

ZT исповедует принцип полного отсутствия конфигурации (zero config). Его не надо настраивать на роутере совсем. Только установить. Что удобно.

У ZT в российских реалиях есть один фатальный недостаток - он по умолчанию завязан на вполне конкретные корневые серверы, которые, если протокол станет хоть сколько-то распространён и обратит на себя внимание, будут элементарно заблокированы тупо по IP. А поднятие собственных корневых серверов (moons) - это уже совсем не zero config, да и клиентскими устройствами не всегда поддерживается (здравствуй, Микротик...)

Блокировать корневые сервера относительно бесполезно, т.к. сделать зеркало на VPS можно. Это вроде даже DNAT-ом/SNAT-ом сделать можно. Но, конечно, кастомный адрес для пира прописывается в конфиге. Так что, да, не zero conf, конечно, будет уже.

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

В конце концов, в РФ вроде не VPN запрещен, а обход блокировок с помощью VPN. Мы же тут, вообще, решаем обратную задачу.

Что никому не помешало блокировать тупо протоколами. И тут совершенно всё равно, для чего он используется. Блокировались в т.ч. туннели, у которых обе стороны вообще внутри России и они даже теоретически для обхода блокировок использованы быть не могут. Сейчас, вроде, отпустило после осенних "учений" (отчёты о блокировках продолжают люди писать, меня лично давно не задевало), но что-то мне подсказывает, что чем ближе к марту - тем всё будет хуже.

Так что готовимся. Поэтому у меня по умолчанию обычный WG, который уже легко блокировали на практике, если он отвалится - трафик переключается на туннель Amnezia-WG, которая почти не уступает в скорости, но тоже может быть заблокирована, если начнут оставлять белые списки протоколов (пока такое на практике делали только на Юге после заварушки в махачкалинском аэропорту - но было, так что если захотят, повторят в национальном масштабе), ну и если отвалится и он - то вступает в дело Cloak, который раза в 3 тормознее WG, но и заблокировать его уже куда сложнее. В принципе, если бы не микротики, к которым для работы Amnezia-WG и Cloak на приемлемой скорости пришлось прикрутить по Orange Pi в комплект, я бы обычный WG вообще заменил на Amnezia-WG сразу, и оставил только два протокола.

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

И вот те самые Микротики, будь они трижды неладны, такой опции не имеют :( Откуда я всё это про ZT и узнал, рассматривал его как альтернативу тоже, но этот факт остановил.

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

Вся эта конструкция, исключительно для удобства. А не для обхода блокировок органов же.

Когда бизнес в России, а сам за границей (да и когда сам в России тоже - ибо любые минимально ценные данные всё равно лучше держать за границей) работающий VPN между своими российскими пользователями/серверами и своими заграничными пользователями/серверами совершенно критичен. Да и вообще в любом сценарии, где хотя бы один удалённый сотрудник отделён российской границей от корпоративного сервера (неважно, кто из них с какой стороны). Или ладно, пусть не сотрудник и бизнеса вообще никакого нет, а Ваш родственник из России, которому Вы тоже в Ваше личное частное облако на европейском сервере бекап настроили. Да мало ли вариантов...

Тоже пытаюсь настроить Zerotier как vpn в режиме моста.

На OpenWrt роутере zt-девайс добавлен в lan-br интерфейс. Фаервол lan, wan по умолчанию.

На VPS настроен SNAT/DNAT, в сети Zerotier прописан маршрут к VPS, как для Full Tunnel. Соответственно в режиме Full Tunnel zt-клиенты ходят в интернет через VPS, видят все lan-хосты и наоборот, но pbr-zt маршруты не работают.

Не подскажите, что может быть не так?

table inet fw4 {

set pbr_zt_4_dst_ip_cfg066ff5 {

type ipv4_addr

flags interval

counter

auto-merge

comment "ifconfig.me"

elements = { 34.117.118.44 counter packets 1 bytes 60 }

}

}

ip route list table pbr_zt

default via 192.168.56.184 dev ztw4lea2bk (192.168.56.184 - адрес ztw4lea2bk)

curl ifconfig.me

curl: (7) Failed to connect to ifconfig.me port 80: Connection refused

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

Connection refused - это довольно странная ошибка в этом случае.Попробуйте сдампить трафик на VPS'е и посмотреть что к чему в WireShark'е

Не пойму, что я делаю не так? Указал всё тоже самое, но сервис выдает ошибки, если указан просто суфикс (ru, net, com). При указании явного домена - всё прожевывает.

"Use resolver set support for domains" установлено в Dnsmasq nft?

Да, проблема была в этом. А можно поподробнее по настройке самого VPN интерфейса - какую метрику ему ставить? Ставил выше WAN, тогда после настройки pbr то работает, то нет. Ставил ниже - весь трафик идёт на VPN, на WAN ничего идти не хочет.

Судя по вашему скрину, если вы зону ru форвардите в wg0, то смею предположить, что вы из-за бугра хотите в рунет через VPN ходить. Если всё так, то в настройке peer'а на интерфейсе WireGuard, нужно убрать эту галочку:

В этом случае вообще не будет создан default route с маршрутом через VPN в главной таблице маршрутов, поэтому не нужны никакие метрики, так как не будет никаких конфликтов.

Без установки "Use resolver set support for domains" в "Dnsmasq nft set" роутер работает в режиме preresolve. То есть указанные домены он резолвит на старте и добавляет их в нужный set. Поэтому в этом режиме можно указывать только конкретные домены, которые можно во что-то прорезолвить. При этом не будут работать субдомены указанных доментов. В режиме же "Dnsmasq nft set" всё выполняется на лету и резолвер по ходу дела понимает какие домены надо заносить в nft set и поэтому возможна более гибкая настройка, когда указывается только верхний поддомент.

Можно подробней про косяк номер пять: "не будет работать, если на вашем гаджете настроен кастомный резолвер (а получаемый от роутера по DHCP игнорируется)"?

Похоже действительно не работает. У меня установлен Nextdns, также пробовал Dnscrypt-proxy, Stubby. Домены из nft sets не резолвятся (из Pbr или прописанные вручную). Если в Pbr Use resolver set support for domains = Disabled, то розолвятся без dnsmasq, но это занимает кучу времени если записей много.

Что делать для шифрования DNS? Поднимать сервер на VPS?

Если у вас на клиенте роутера используется кастомный DNS, то тут ничего не попишешь (

Если вы готовы рассмотреть возможность сделать так, чтобы роутер форвардил DNS запросы на nextdns, а клиент переключить на использование резолвера роутера, то это делается путем установки пакета https-dns-proxy. Настройка либо из консоли, либо через Web UI после установки пакета luci-app-https-dns-proxy. По дефолту он, кажется, на гугловые серверы слать будет.

Я так и делал с Dnscrypt-proxy и Stubby, прописывал форвардер, все lan-клиенты и local резолвились, а nft sets нет!

Пробую с провайдерскими DNS, для нужно было включить "Use DNS servers advertised by peer" в luci для wan интерфейса и nft sets начали резолвится!

Теперь не меняя настройки wan, настраиваю форвардинг в Stubby в /etc/config/dhcp

option localuse '1'
option noresolv '1'
list server '127.0.0.1#5453'
list server '0::1#5453'

перезапускаю dnsmasq и чудо, все резолвится через прописанные в Stubby сервера nextdns (я это вижу в логах my.nextdns.io).

Если ставить пакет nextdns, то резолвинг nft sets не работает. Жаль, я настраивал разные профили на разные девайсы.

C пакетом nextdns nft sets тоже резолвятся, но только без кеша:

nextdns config set -cache-size=0

Не знаю почему

Честно говоря, я ничего про nextdns не знаю, мне надо погрузиться в тему, чтобы дать более обстоятельный ответ. Я думал, что это просто DoH и нужно прописать его url, чтобы это заработало. Но судя по тому что вы пишете и что бегло нагуглил - это какой-то резолвер, который ставиться вместо dnsmasq, судя по всему сделанный при этом на базе самого dnsmaq потому что список опций его конфигурации во много совпадает с опциями dnsmasq.

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

Честно говоря, я до сих пор не понял, каким образом и в какой момент при его установке, он сопрягается с dnsmasq, но как я понял при правильной конфигурации запросы принимает dnsmasq и форвардит их на другой порт на localhost'е в nextdns.

Да, это самостоятельный резолвер, опция setup-router настраивает dnsmasq на форвардинг к нему.

Установил кеш в dnsmasq вместо nextdns, командой dig google.com повторяю запросы, в ответе query time не меняется и больше 70 мс, т.е. кеш отключен. Полагаю dnsmasq не кеширует запросы форвардеру.

 cat /tmp/dnsmasq.d/nextdns.conf 

# Configuration generated by NextDNS

no-resolv

server=127.0.0.1#5342

add-mac

add-subnet=32,128

cat /etc/config/dhcp

config dnsmasq

option domainneeded '1'

option localise_queries '1'

option rebind_protection '1'

option local '/lan/'

option domain 'lan'

option expandhosts '1'

option cachesize '1000'

option authoritative '1'

option readethers '1'

option leasefile '/tmp/dhcp.leases'

option localservice '0'

option ednspacket_max '1232'

option localuse '1'

option noresolv '1'

option proxydnssec '1'

В процессе обработки запроса на резолв с участием форвардинга dnsmasq вызывает эту функцию. В неё передаётся указатель на флаг cacheable, который при определенных обстоятельствах сбрасывается в 0 и ответ на такой запрос в последствии не кэшируется. Можете проверить, попадает ли ваш кейс в данные ограничения.

Да, получается, что параметры dnsmasq которые nextDNS передает в автоматической настройке: --add-mac --add-subnet=32,128 без кеша. Попробую разобраться и в ручную сконфигуровать dnsmasq. Спасибо!

Буквально вчера закончил восстановление конфигурации роутера после замечательного (нет) обновления прошивки на nft. Живу в Крыму, поэтому нужно два ВПН - один московский (Ihor), другой - зарубеж (1.1.1.1 WARP). Поднял два ВГ-интерфейса и поставил ПБР. А дальше скрипт на ucode раз в сутки парсит 2 конфига, где я могу задавать адрес, сеть или АС и создает списки адресов для обоих айписетов. Также льется свежий список с антизапрет.ру и скармливается в зарубежный айписет. И помимо этого пара сайтов по доменным именам в конфигурации ПБР висит.

А чем вам плох представленный в статье способ? Ваше скрипты, кажется, это закат солнца вручную.

  1. Я могу маршрутизировать АС. Нужно для фб и инсты.

  2. Решается "косяк номер два" по отношению к указанным АС и списку адресов антизапрет.ру.

Не в курсе про фб и инсту. Что за надобность в маршрутизации автономной системы? Можете описать подробнее?

Надобность может быть, если нужно обойти что-нибудь большое, типа Гитхаба, который банил крымчан и не давал создавать приватные репозитории (сейчас сняли ограничение), Майкрософта, ФБ и инсты, т.е., систем, где могут быть десятки серверов. А так добавил АС и живешь спокойно.
Сейчас полез в конфиг, а там нет ни фб, ни инсты. Не сразу понял, что я их оттуда убрал, т.к. их адреса подгружаются из списка антизапрета. Изначально у меня обход блокировки по АС был, а когда появился антизапрет - я убрал.
Получается, что сейчас у меня нет особой нужды АСами маршрутизировать, но если такая необходимость понадобится снова - я буду готов.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории