Skip to content

Latest commit

 

History

History
222 lines (150 loc) · 25.5 KB

File metadata and controls

222 lines (150 loc) · 25.5 KB

SwByeDPI - Swift-обертка для byedpi

Логотип ByeDPI

Русский | English

Swift5 Swift6 LatestRelease

Swift Package Manager compatible SPMPlatform SPMLicense

PodVersion PodPlatform PodLicense

Репозиторий является Swift-библиотекой, которая является оберткой над нативным C byedpi

Благодарность romanvht за его форк реализации Android-приложения над byedpi, которая вдохновила на создание данного проекта вместе с iOS-приложением, работающим на данном модуле

Содержание

Вступление

Модуль, в первую очередь, нацелен на iOS, минимальная версия - 10.0 и новее. Другие Apple-платформы (macOS 10.12+, tvOS 10.0+, watchOS 3.0+, visionOS 1.0+) заявлены как доступные, но имеют экспериментальную поддержку

Также есть возможность собрать решение для других платформ (Android, Linux), но не факт, что оно будет нормально работать - лучше нативно собрать byedpi под конкретную платформу как исполняемый файл и использовать напрямую. Может быть использовано скорее для целей разработки модуля на ОС Linux, нежели использования, что и применялось, так как данное решение писалось параллельно на macOS (XCode) и Linux (VSCode с Swift SDK)

Установка и настройка

Swift Package Manager

SwByeDPI доступен к подключению в проект через SPM

Для работы доступны 3 модуля-библиотеки:

  1. ByeDPIC - Низкроуровневый скомпилированный C-модуль в режиме C-interoperability. Не содержит какого-либо ObjC/Swift кода и, в теории, может быть использован на самых старых устройствах экосистемы Apple. Не рекомендовано к использованию
  2. ByeDPIKit - Минимальная обертка над ByeDPIC, позволяющая запускать/останавливать нативный byedpi SOCKS-прокси с параметрами для DPI. Не содержит никаких Apple-платформенных проверок параметров ByeDPI в контексте Swift-окружения
  3. SwByeDPI - Расширенная обертка над ByeDPIC, которая базируется на ByeDPIKit'е. Содержит абстракции для конфигураций запуска, инструменты для создания URL-сессий под SOCKS-пркоси, предварительно добавленные наборы стратегий и доменов для тестирования и дальнейшего использования в byeDPI, а также функционал по тестированию и аналитике стратегий и доменов

Подключение SwByeDPI

//Package dependencies parameter
.package(url: "https://github.com/mIwr/SwByeDPI.git", .from(from: "0.17.3"))

//Target dependencies parameter (SwByeDPI)
.product(name: "SwByeDPI", package: "SwByeDPI")
//Target dependencies parameter (ByeDPIKit)
.product(name: "ByeDPIKit", package: "SwByeDPI")
//Target dependencies parameter (ByeDPIC)
.product(name: "ByeDPIC", package: "SwByeDPI")

CocoaPods

Все 3 модуля, по аналогии с SPM, доступны к подключению через CocoaPods. Имена pod'ов идентичны SPM

Примечание: согласно информации по CocoaPods, обновления модулей будут публиковаться на CocoaPods до декабря 2026 г.

Работа с ByeDPI

Запуск byedpi в ByeDPIKit и SwByeDPI идентичен:

  1. Определяется команда для запуска ByeDPI SOCKS прокси, согласно документации
  2. Непосредственно запуск с передачей аргументов запуска ByeDPI SOCKS прокси
#if canImport(SwByeDPI)
import SwByeDPI
#else
    #if canImport(ByeDPIKit)
import ByeDPIKit
    #endif
#endif

var args: [String] = []
//...Определение команды для запуска
ByeDPI.start(args: args) { BDError in
    //Обработка ошибки запуска
}
  1. Спустя время, завершение работы ByeDPI
// В общем случае работу можно завершать так
_ = ByeDPI.stop()
// Если же при повторном запуске возникает ошибка bind error: Address already in use, то лучше останавливать через forceStopDPI()
_ = ByeDPI.forceStop()

Дополнительно

SwByeDPI. Тестирование стратегий

Для более эффективной работы ByeDPI в разных условиях (различные провайдеры интернета, геолокация, устройства, ОСи итд) был реализован механизм проверки стратегий на некотором списке доменов.

Для тестирования можно задать следующие параметры:

  • Задержка между запросами к доменам (секунды). Увеличение значения улучшает достоверность тестирования. Оптимальное значение в ходе тестов - 1 секунда
  • Количество запросов к домену. Увеличение значения увеличивает точность, но снижает общую скорость проверки. Оптимальное значение в ходе тестов - 2 запроса
  • Количество потоков-worker'ов. Увеличение значения ускоряет проверку, но снижает достоверность проверки. Оптимальное значение в ходе тестов - Колиество ядер CPU * 2
  • Ожидание ответа на запрос (секунды). Увеличение значения замедляет общую скорость проверки, но улучшает достоверность тестирования. Оптимальное значение в ходе тестов - 5 секунд
  • Списки доменов для тестирования. Для подбора более универсальной стратегии и будущего анализа результатов лучше выбрать больше доменов. Если же задача открыть доступ только к некоторым ресурсам, то стоит выбрать (Если же их нет, то сначала добавить новый список) только их. Большой пулл доменов для проверки, логично, замедляет общую скорость теста
  • Списки стратегий для тестирования. По умолчанию доступен только встроенный в SwByeDPI список стратегий

Под успешным запросом к домену через ByeDPI подразумевается ответ со статус-кодом 200..299 или любой другой, но с заголовком Content-Length (факт отправки и получения информации в теле ответа)

Так, проведя тестирование, можно отобрать универсальную стратегию (Важное уточнение - не самую лучшую для конкретных тестируемых доменов) по критерию Больше успешных запросов к доменам - лучше стратегия

Для более тонкой настройки необходимо использовать анализ результатов тестирования стратегий

SwByeDPI. Анализ результатов тестов и подбор оптимальной стратегии

Стратегии, проверенные на определенных доменах и показавшие свою эффективность (Наибольшее количество успешных запросов, прошедших DPI), уже можно использовать в ByeDPI. Однако в случае, когда необходимо тонко настроить работу ByeDPI (Настроить bypass для определенных доменов, использовать для определенных доменов самые эффективные стратегии, определить универсальную стратегию), простого выбора стратегии из результатов тестов недостаточно

Для этого в SwByeDPI был реализован модуль анализа результатов, результатом работы которого будет композитная стратегия, состоящая из:

  • Bypass для DNS (53 порт) - больше используется при работе ByeDPI в туннеле
  • Список доменов, на которых ByeDPI работать не будет - блок черного списка или ByeDPI-bypass. По документации byedpi в секции "Подробнее --auto --hosts" этот блок всегда будет идти в начале композитной стратегии
  • Список или списки доменов, для которых из протестированных отобраны самые эффективные стратегии - блок белого списка ByeDPI. Данный блок может находиться в начале, если отсутствует черный список доменов, или в середине/конце композитной стратегии
  • Стратегия, которая может быть не самой лучшей для конкретного домена, но показавшая наилучшие результаты (Наибольшее количество успешных запросов, прошедших DPI), является универсальной, и может быть использована для "остальных" доменов при работе ByeDPI - блок универсальной стратегии. Этот блок всегда будет находиться в конце композитной стратегии

Базовая операция над результатами тестирования стратегий, на которой работает весь анализ - расчет покрытия стратегии на список доменов (Успешные запросы к доменам в списке). Вся логика по анализу расположена в SBDTestResultAnalyticsUtil.swift

Примечание 1: Использование каждого блока опционально, т.е. можно задать использование всех блоков в композите, использование только белых списков итд

Примечание 2: Списки доменов для тестирования в исходном виде не оптимально использовать в ByeDPI --hosts. Так как для ByeDPI достаточно указать лишь домены второго уровня (Пример: если указать в --hosts домен googlevideo.com, то ByeDPI будет обрабатывать и все поддомены), можно сгенерировать новый список (Анализатор стратегии именно это и делает), состоящий только из уникальных доменов второго уровня. Чтобы сделать это, можно воспользоваться функицей retrieveSLDList()

var domainList: SBDDomainList
//...
let sldList = domainList.retrieveSLDList()

Примечание 3: Для связности между блоками (Черный/белый список и универсальная стратегия) и стратегиями внутри (Стратегии под разные списки доменов в белом списке) используется связка вида -An

SwByeDPI. Кодогенерация

В SwByeDPI добавлены списки сайтов для тестирования и ByeDPI-bypass, а также стратегии в виде текстовых файлов, из которых потом генерируются *.swift-файлы, компилируемые в результирующий модуль (Built-in домены и стратегии). Можно изменять или удалять текущие списки, а также добавлять новые.

Генерация происходит через скрипт-кодогенератор в ручном режиме, который определяет в Assets все файлы с расширениями *.strategies и *.domains. Примечание: формат файлов списков един и для стратегий, и для доменов - по одной(-ому) на строку

Example-приложение

В качестве Example-приложения реализовано iOS-приложение (iOS 14+, SwiftUI). Проект может быть собран и под другие платформы (Экспериментальная поддержка для tvOS 17.0+ и macOS 11.0+)

Приложение локально запускает ByeDPI и может перенаправлять трафик других приложений и устройств в локальной сети через него

Возможности

Приложение позволяет:

  • Устанавливать настройки запуска ByeDPI (прослушиваемый IP адрес, порт SOCKS прокси, аргументы командной строки)
  • Автоматически исправлять параметры стратегии ByeDPI, если они не поддерживаются устройством и/или ОСью
  • Проводить тестирование стратегий и сохранять последний прогон тестирования
  • Анализировать и составлять наиболее оптимальные стратегии на основе результатов тестирования
  • При составлении оптимальных стратегий можно указывать черные (ByeDPI bypass), белые (конкретные стратегии работают только для конкретных доменов) списки доменов. Подробнее --auto --hosts
  • Добавлять/изменять/удалять домены для тестирования стратегий, фильтрации доменов для ByeDPI bypass
  • Добавлять/изменять/удалять стратегии для их тестирования
  • Устанавливать DNS (DoH/DoT) - доступно только в контексте сборки полноценного VPN-клиента

Примечание: по сравнению с Android, VPN Network Extension в iOS не может управлять туннелированием для конкретных приложений. Для этого используется функционал самого byedpi с указанием конкретных доменов второго уровня (черные/белые списки)

Для продвинутого использования можно ознакомиться с комплексной инструкцией от комьюнити ByeByeDPI-Manual.

Сборка

Возможны 2 варианта сборки приложения:

  • Полноценный VPN клиент (ByeByeDPI) ByeDPI -> Tun2SocksKit -> NEVPN + DNS - требует наличия платной лицензии разработчика: для разработки, отладки и загрузки в TestFlight достаточно уч. записи физ. лица, для релиза в App Store - только юр. лицо или ИП, согласно нормативами Apple Developer 5.4. Примечание: приложение не является VPN-клиентом в чистом виде, так как ByeDPI работает локально на устройстве - трюк с VPN нужен для возможности работы функционала ByeDPI в фоне (приложение свернуто или вовсе не запущено) и возможности обработки интернет-трафика всех приложений в смартфоне и устройств в локальной сети (Необходимо дать разрешение на доступ к локальной сети приложению). Поддержка в NetworkExtension DoH/DoT дает возможность обходить гео-блокировки некоторых сервисов
  • ByeDPI SOCKS прокси-сервер (ByeDPI) - для запуска на собственных устройствах, не требует наличия платной лицензии разработчика. Данная сборка идеально подходит для отладки и тестирования функционала приложения на конечных устройствах: можно протестировать стратегии, собрать оптимальный композит через анализатор. Нюанс здесь в том, что ByeDPI будет работать, только пока приложение открыто (foreground)
  1. Клонируйте текущий репозиторий:
git clone https://github.com/mIwr/SwByeDPI
  1. Добавьте в связку ключей сертификаты и закрытые ключи для подписи приложения, импортируйте профили разработки

В Apple Developer для приложения (VPN клиент) необходимо выполнить следующее (При условии, что уже есть сертификат хотя бы для разработки и управление подписями идет в ручном режиме):

  • Зарегистрировать App Group ID, который будет объединять приложение-хост и Network Extension
  • Зарегистрировать App ID для приложения-хоста. В Entitlements указать App Groups (с указанием ранее созданной), Network Extensions и Personal VPN
  • Зарегистрировать App ID для Network Extension. В Entitlements указать те же пункты, что и для приложения-хоста
  • Создать профили разработки для приложения-хоста и Network Extension
  • Импортировать профили в XCode
  1. Запустите сборку приложения (ByeByeDPI или ByeDPI) через GUI XCode или Terminal

Проблемы и решения

  • VPN-туннель запустился, но сайты не открываются и в логах (Console.app) циклично появляется лог 'udp session start - connect - destruct'. Связано с адресом ByeDPI 127.0.0.1/localhost - В Network Extenson ОС отбрасывает все пакеты на такой адрес. Необходимо указывать любой другой локальный адрес. Примечание: при подключенном Wi-Fi в провайдере локальный IP адрес автоматом подставится, если указан на вход 127.0.0.1, ::1, 0.0.0.0 или ::.
  • До iOS 14 приложение будет работать крайне нестабильно ввиду жестких лимитов для Network Extension - 15 Мб. После превышения этого лимита ОС без предупреждения и краша убьет VPN туннель. Решение - использовать приложение на смартфонах iOS 15+, где лимит уже 50 Мб. Примечание: в ходе тестов было установлено, что при правильном конфиге Tun2SOCKS потребление ОЗУ не превышает даже 15 мб (В среднем держалось на уровне 4.3-4.8 мб), так что, теоретически, данный NetworkExtension можно перенести на рельсы UIKit'а, чтобы дать поддержку даже для iOS 10.0+ с ограничением 15 мб на Network Extension
  • Постоянное нарастание используемой ОЗУ в процессе работы тунеля (веб-серфинг итд) от самого старта вплоть до SIGKILL от ОС - включен редирект логов из stdout/stderr (hev-socks-tunnel, byedpi), который необходимо выключить/закомментить в коде, включая команды для установки уровня логирования для byedpi/Tun2SOCKS

Скриншоты