Роутинг для белых списков

4 мин. чтения

Все по-разному пользуются интернетом. Для кого-то, это что-то базовое: посидеть в ВК, скинуть квитанцию в чат садика в Максе, посмотреть погоду в яндексе и вызвать там же такси. Бывают и другие сценарии: например, мне нужен YouTube, нейронки и доступ к зарубежным исследованиям и статьям. Всё это мало возможно без VPN. Заходя на какой-то сайт, нужно либо включать его, либо выключать (поэтому я вообще назначил команду на физическую кнопку в телефоне). Обычно он всё же включён и, заходя на тот же Кинопоиск или в приложение Сбера, для сервиса мы выглядим как гражданин Нидерландов. И в этом есть минусы, поскольку для нас могут убрать какие-то фильмы, а перевод вообще заблокировать. С введением так называемых белых списков, когда не работает ничего кроме сайтов из этого списка (у нас в Костроме этот режим стал постоянным — скорость к ресурсам не из БС режется до 0,2 Мб/с), всё стало ещё неудобнее.

Решение 1 — роутинг в приложении

На телефоне я пользуюсь Streisand, куда добавляю свою конфигурацию c VLESS + Reality. Есть и другие вариации (к примеру, v2RayTune или v2Box. Суть и них примерно одинаковая, думаю, движок тоже один. Но именно Streisand мне нравился больше (не добавляет периодически дубликаты профилей, стабильнее находит интернет при смене WiFi на сотовые данные).

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

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

streisand://aW1wb3J0L3JvdXRlOi8vWW5Cc2FYTjBNRERWQVFJREJBVUdCd2dKQ2xSdVlXMWxWSFYxYVdSZVpHOTRZV2x1VTNSeVlYUmxaM2xkWkc5dFlXbHVUV0YwWTJobGNsVnlkV3hsYzFKU1ZWOFFKRGRCUXpneE1qSXdMVEZGTmtNdE5EUXlPQzFDT0VFekxVWXhNVFJGTVVZd01qZERNbGxKVUU5dVJHVnRZVzVrVm1oNVluSnBaS01MUUZEVEJBd05DUTQvVm1SdmJXRnBibHR2ZFhSaWIzVnVaRlJoWjY4UU1BOFFFUklURkJVV0Z4Z1pHaHNjSFI0ZklDRWlJeVFsSmljb0tTb3JMQzB1THpBeE1qTTBOVFkzT0RrNk96dzlQbGd5WjJsekxtTnZiVmN5WjJsekxuSjFXVFEzYm1WM2N5NXlkVnRoYkdaaFltRnVheTV5ZFZ4aGRYUm9MVzV6WkdrdWNuVlhZWFYwYnk1eWRWaGhkbWwwYnk1eWRWaGhkbWwwYnk1emRGNWpaRzR0ZEdsdWEyOW1aaTV5ZFZsalpHNDRkbXN1Y25WWVkybHJjbVl1Y25WWFpIcGxiaTV5ZFZ4bmIzTjFjMngxWjJrdWNuVldaMjkyTG5KMVdHZDFMWE4wTG5KMVcybDZZbWx5YTI5dExuSjFYR3RwYm05d2IybHpheTV5ZFZ4c1pXMWhibUZ3Y204dWNuVlpiRzE5ZFM1MFpXTm9WMjFoYVd3dWNuVldiV0Y0TG5KMVdXMXlZV1I0TG01bGRGVnZheTV5ZFZkdmEyTmtiaTV5VjI5dVpXMWxMbkpYYjNwdmJpNXlkVmh2ZW05dVpTNXlkVnR5WlhNdGJuTmthUzV5ZFZseWRYUjFZbVV1Y25WZGNuVjBkV0psYkdsemRDNXlkVlp5ZW1RdWNuVlhjMkpsY2k1eWRWdHpZbVZ5WW1GdWF5NXlkVlYwTWk1eWRWaDBZbUZ1YXk1eWRWdDFjMlZ5WVhCcExtTnZiVjEyYXkxd2IzSjBZV3d1Ym1WMFZuWnJMbU52YlZWMmF5NXlkVloyZEdJdWNuVlZkMkl1Y25WZWQybHNaR0psY25KcFpYTXVjblZWZWdFdWNuVmFlV0Z1WkdWNExtTnZiVmg1WVc1a1pYZ3VibVYwV1hsaGJtUmxlQzV5ZFZ4NVlYTjBZWFJwWXk1dVpYUmFZbVZsYkdsdVpTNXlkVlprYVhKbFkzVFVCQXhCRFFsQ1RrOVNhWkZyUjBSRlRVZElTVXBMVEUxYmVXOTFkSFZpWlM1amIyMWJhUzU1ZEdsdFp5NWpiMjFiWjNOMFlYUnBZeTVqYjIxZGVYUXpMbWRuY0doMExtTnZiVjhRRDJkdmIyZHNaWFpwWkdWdkxtTnZiVjhRRldSbGRtVnNiM0JsY25NdVoyOXZaMnhsTG1OdmJWOFFGV2R2YjJkc1pYVnlaVzl1YVhSbGNubFZkR1Z1YzI4dVkyOWs=

Это прекрасно работало, пока список из доменов не вырос. Теперь при попытке импорта приложение просто вылетает, записывая EXC_BAD_ACCESS (Thread stack size exceeded due to excessive recursion) в отчёт Panic. Я писал разработчику, подробно описывал ситуацию, скидывал пример, но он так и не понял, что я от него хочу. Поэтому идём дальше.

Решение 2 — роутинг в приложении и файл формата geosite

Уважающие себя VPN клиенты (во всех значениях) умеют строить правила опираясь на файлы geosite.dat и geoip.dat. Суть такая: пишем вместо домена что-то типа geoip:ru и все сайты с русским IP-адресом попадают в наше правило. Либо, добавив geosite:google, получаем набор всех доменов, принадлежащих Google. Конечно, кто-то заботливо собирает эти данные, запаковывает в бинарный формат и выкладывает в открытый доступ. Но поиски такой волшебной geosite:ru-whitelisted ничего не дали. Более того, нет вообще какого-то вменяемого списка этих ресурсов (Минцифры публиковало новости в формате “добавлено …”). Самая полная информация есть у операторов сотовой связи. Вот это и было взято за основу для формирования своего списка с доменами.

Создал репозиторий на GitHub, в папке lists разместил два текстовых файла direct.txt и proxy.txt. При изменении репозитория, они скриптом на Go компилируются в файл custom.dat, который, благодаря GithubPages, доступен по отдельному адресу.

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

Заходим в Streisand → Настройки → Роутинг → Настройки → Геофайлы, удаляем преднастроенные источники (свайпом влево), нажимаем сверху Плюс, вставляем https://geofiles.bolotov.dev/custom.dat, включаем автообновление.

Теперь правила можно сделать максимально простыми:

Заметьте, вместо стандартных IPifNonMatch (IPOnDemand) мы включили AsIS. Поскольку наш спискок содержит только текстовые домены без IP-адресов, проверять, нужен ли VPN, можно не делая запрос к DNS серверу. Казалось бы милисекунды экономии времени, но если есть проблемы с сетью, это становится критичным.

Разумеется, новый роутинг можно добавить через кнопку Плюс на главном экране приложения, скормив приложению QR-код со скрина ниже или это:

streisand://aW1wb3J0L3JvdXRlOi8vWW5Cc2FYTjBNRERWQVFJREJBVUdCd2dKQ2xSdVlXMWxWSFYxYVdSZVpHOXRZV2x1VTNSeVlYUmxaM2xkWkc5dFlXbHVUV0YwWTJobGNsVnlkV3hsYzF0WGFHbDBaV3hwYzNSbFpGOFFKRGt5T1VJeE0wUkZMVUZDUWtNdE5EaEJRaTA0TTBKR0xUQTBOVFpFTXpGQ1JqUkVSVlJCYzBselZtaDVZbkpwWktJTEVkTUVEQTBKRGhCV1pHOXRZV2x1VzI5MWRHSnZkVzVrVkdGbm9ROWZFQlJsZUhRNlkzVnpkRzl0TG1SaGREcHdjbTk0ZVZWd2NtOTRlZE1FREEwSkVoU2hFMThRRldWNGREcGpkWE4wYjIwdVpHRjBPbVJwY21WamRGWmthWEpsWTNRSUV4Z2RMRHBBVEhONGY0S0prSnlldGJ2Q3hOd0FBQUFBQUFBQkFRQUFBQUFBQUFBVkFBQUFBQUFBQUFBQUFBQUFBQUFBNHc9PQ==

а затем включив в настройках

Перезапускаем туннель и видим, что для Гугла и Яндекса мы в России, YouTube работает, нейронки тоже.

Что может быть прекраснее этого?