Зачем людям ранее был нужен VPN (кроме мошенников конечно)? Чтоб ходить на Linkedin и обходить всякие разные запреты РКН.
Когда ввели санкции и некоторые сайты перекрасились в сине-желтый цвет, то многие по старой памяти подумали — включим VPN и всё сразу станет как раньше, разве что русские сайты начнут открываться на 50мс медленнее.
Но не тут-то было. Вместе с перекраской сайтов, началась волна DDoS и хакерских атак на различные сервисы в РФ. В итоге, российские сайты закрылись от остального интернета. И с VPN стало очень некомфортно — хочешь пользоваться Terraform или, там, MatterMost скачать — включаешь VPN… И… сразу же не можешь сходить ни на Ozon ни на Госуслуги.
Интернет разделился на InnerNet и OuterNet.
Различные (удачные и не очень) попытки.
Сама собой возникла потребность более умного VPN, который русские сайты отправит по одному маршруту, а не-русские — по другому.
Сделать это можно различными способами.
Первый, который пришел в голову — это конечно же старый добрый squid: ставим два хоста, соединяем тоннелем. На первом хосте, ставим второй апстримом для определенных доменных зон или доменов, настраиваем SSL-BUMP.
Однако такое решение, хоть оно и достаточно эффективное, имеет определенные минусы :
-
Нужно везде прописывать проксю. Когда мы делаем не поделку, а решение — это плохо.
-
Нужно везде грузить сертификаты CA. И если в браузере это +- несложно, то, например, в различных продуктах от JetBrains — их нужно прописывать отдельно. В общем, чтоб завернуть весь трафик из дома или из офиса — нужно СЛИШКОМ МНОГО движений.
-
Ну и заявлять всем : «ребята, я вам сделал удобно, но учтите, что теперь я имею возможность читать весь ваш трафик, переписку и сайты с порнухой» — настолько не очень, что люди не будут пользоваться, или будут так же включать — от случая к случаю. А хочется — set and forget.
Второй вариант — SNI (как, например, работает DPI) — в SSL трафике хостнейм передается (всё реже и реже) открыто. Но, в TLS 1.3 это уже не актуально. Да и в целом — анализировать весь трафик слишком накладно.
В итоге — остаются только айпишки. С ними я и начал работать (после того, как полностью поднял инфру на SQUID + генерацию CA 🙂 )
Получился…
Гео-роутинг.
В принципе зароутить трафик не сложно :
Между входящим ВПН-сервером и второй его головой настраивается тоннель. Настраиваем PBR — то, что пометили в mangle — отправляем на вторую голову. То, что не пометили — выпускаем. Входящий ставим в РФ, второй — там, где остальной мир не будет вас блочить.
Первый этап так же не сложен — распаковываем базу GEOIP и все подсетки, которые находятся в гео RU — помечаем для выпуска сразу. Однако, не подсетками едиными (тут я как раз столкнулся с Ozon) — некоторые русские сервисы хостятся не в РФ (а, например, в Германии), при этом, пускают только русских. Для таких нужен отдельный список и котел в аду за кроссбординг ПД. А еще, мейнтейнить список айпишек несколько неудобно, особенно, если учесть, что айпишки у сайта могут меняться без предупреждения (потому, что часть Озона за клаудфларой).
Когда браузер обращается к сайту, он вначале резолвит имя в айпишник. Выход напросился сам собой : перехватываем DNS-запрос, если он к нужному сайту или нужной зоне — добавляем айпишник в iptables. Причем, в отличие от решения с SNI — мы успеем добавить айпишник еще до соединения браузера с сайтом. Главное делать это быстро : секунда-две на каждый запрос к ресурсу в пост-модемные времена — непозволительно долго.
Здесь мне помог PowerDNS — отличное решение, которое позволяет делать пост-обработку ответов DNS через LUA :
-
Ловим каждый запрос.
-
Отправляем по вебсокету демону на питоне.
-
Демон принимает решение и настраивает IPT.
Конечно, помня, что в DNS есть еще и CNAMEs, простейшим алгоритмом не обойтись — приходится строить цепочки записей и обходить их как слева направо, так и справа налево. Тем не менее работает достаточно эффективно — в пределе, на самой дешевой яндексовской виртуалке, обработка DNS-запроса занимает 100мс. А обычно, укладываемся в несколько мс.
В отдельных случаях, при холодном старте, всё-таки не всегда успевает добавить в IPT для отдельных сайтов. Поэтому, тот же озон при холодном старте инфраструктуры, на первое обращение часто отдает 403. Чистка кеша на клиенте и последующий релоад страницы приводит роутинг в чувства.
NFTables.
Изначально, я хотел использовать NFTables — я их очень люблю, и они в целом эффективнее чем iptables/netfilter. Позволяют творить такое, что IPT/NF даже не снилось. Но, не тут-то было. Большой набор рул в nft не загрузить потому, что nft работает через RT_NETLINK так, что туда много не влезает. В аутернетах есть бенчи, которые показывают, что nft весьма медленно добавляет рулы по сравнению с IPT/NF.
Итог.
В итоге, получился MRVPN, который можно скачать отсюда : https://github.com/AlexMKX/mrvpn
Деплой осуществляется через ansible role, что современно модно и молодежно.
Для клиентов используется FireZone — один из лучших фронтов для WireGuard, который поддерживает гугловый SAML (а в коммерческой версии и другие), что важно для корпов.
ссылка на оригинал статьи https://habr.com/ru/articles/668388/
Добавить комментарий