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

Моя борьба с санкциями или как появился умный VPN

Время на прочтение3 мин
Количество просмотров76K

Зачем людям ранее был нужен VPN (кроме мошенников конечно)? Чтоб ходить на Linkedin и обходить всякие разные запреты РКН.

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

Но не тут-то было. Вместе с перекраской сайтов, началась волна DDoS и хакерских атак на различные сервисы в РФ. В итоге, российские сайты закрылись от остального интернета. И с VPN стало очень некомфортно - хочешь пользоваться Terraform или, там, MatterMost скачать - включаешь VPN... И... сразу же не можешь сходить ни на Ozon ни на Госуслуги.

Интернет разделился на InnerNet и OuterNet.

Различные (удачные и не очень) попытки.

Сама собой возникла потребность более умного VPN, который русские сайты отправит по одному маршруту, а не-русские - по другому.

Сделать это можно различными способами.

Первый, который пришел в голову - это конечно же старый добрый squid: ставим два хоста, соединяем тоннелем. На первом хосте, ставим второй апстримом для определенных доменных зон или доменов, настраиваем SSL-BUMP.

Однако такое решение, хоть оно и достаточно эффективное, имеет определенные минусы :

  1. Нужно везде прописывать проксю. Когда мы делаем не поделку, а решение - это плохо.

  2. Нужно везде грузить сертификаты CA. И если в браузере это +- несложно, то, например, в различных продуктах от JetBrains - их нужно прописывать отдельно. В общем, чтоб завернуть весь трафик из дома или из офиса - нужно СЛИШКОМ МНОГО движений.

  3. Ну и заявлять всем : "ребята, я вам сделал удобно, но учтите, что теперь я имею возможность читать весь ваш трафик, переписку и сайты с порнухой" - настолько не очень, что люди не будут пользоваться, или будут так же включать - от случая к случаю. А хочется - set and forget.

Второй вариант - SNI (как, например, работает DPI) - в SSL трафике хостнейм передается (всё реже и реже) открыто. Но, в TLS 1.3 это уже не актуально. Да и в целом - анализировать весь трафик слишком накладно.

В итоге - остаются только айпишки. С ними я и начал работать (после того, как полностью поднял инфру на SQUID + генерацию CA :) )

Получился...

Гео-роутинг.

В принципе зароутить трафик не сложно :

Между входящим ВПН-сервером и второй его головой настраивается тоннель. Настраиваем PBR - то, что пометили в mangle - отправляем на вторую голову. То, что не пометили - выпускаем. Входящий ставим в РФ, второй - там, где остальной мир не будет вас блочить.

Первый этап так же не сложен - распаковываем базу GEOIP и все подсетки, которые находятся в гео RU - помечаем для выпуска сразу. Однако, не подсетками едиными (тут я как раз столкнулся с Ozon) - некоторые русские сервисы хостятся не в РФ (а, например, в Германии), при этом, пускают только русских. Для таких нужен отдельный список и котел в аду за кроссбординг ПД. А еще, мейнтейнить список айпишек несколько неудобно, особенно, если учесть, что айпишки у сайта могут меняться без предупреждения (потому, что часть Озона за клаудфларой).

Когда браузер обращается к сайту, он вначале резолвит имя в айпишник. Выход напросился сам собой : перехватываем DNS-запрос, если он к нужному сайту или нужной зоне - добавляем айпишник в iptables. Причем, в отличие от решения с SNI - мы успеем добавить айпишник еще до соединения браузера с сайтом. Главное делать это быстро : секунда-две на каждый запрос к ресурсу в пост-модемные времена - непозволительно долго.

Здесь мне помог PowerDNS - отличное решение, которое позволяет делать пост-обработку ответов DNS через LUA :

  1. Ловим каждый запрос.

  2. Отправляем по вебсокету демону на питоне.

  3. Демон принимает решение и настраивает 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 (а в коммерческой версии и другие), что важно для корпов.

Теги:
Хабы:
Всего голосов 40: ↑33 и ↓7+32
Комментарии130

Публикации

Истории

Ближайшие события

15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань