Результат будет зависеть от конфига VPN-клиента и системы. Но добиться нужного результат вполне реально.
Если исключаем приложение из TUN, то доступ к TUN будет закрыт, если на уровне системы включена настройка блокировки соединений без VPN.
Если такая системная настройка выключена, то соединение попадает в VPN-клиент. Но при этом в нем может быть настроено, что по умолчанию всё блокируем или пускаем в direct, а избранные приложения по имени пакета попадают в прокси (тогда тоже всё будет хорошо).
Если по умолчанию прокси, а блокировка (или direct) через правило по имени пакета (список плохих пакетов), то да, плохая программа попадет на прокси, потому что её имя определить нельзя в таком случае (определение имен не работает). Поэтому в новом sing-box добавлена возможность правилами ловить приложения, где имя определить не удалось (или те, кто полез сам в tun, или какие-то особые случаи системных приложений).
Теперь понятно. У вас по умолчанию блокируется. Когда указывается tun0, то имя пакета не определяется, идёт блокировка. Без tun0 имя пакета определяется. Выходит нужно перечислить вообще все программы, а потом новые добавлять, чтобы у них работал интернет.
В GrapheneOS это фиксили похоже: https://grapheneos.org/releases#2025072700 This release resolves 2 upstream Android VPN leaks discovered by GrapheneOS and our community testers.
prevent using SO_BINDTODEVICE to bypass VPN lockdown mode (leak protection) to resolve an upstream Android VPN leak discovered by GrapheneOS testers where code specifies a specific interface via a special system call to bypass the VPN
prevent using NsdService#connect for components restricted by VPN lockdown mode to prevent a very limited upstream Android local network VPN leak discovered by GrapheneOS
Изучил. Если приложение привязывается к конкретному интерфейсу, то per-app правила не работают, так как в этом случае невозможно определить пакет по соединению. Функция getConnectionOwnerUid не находит UID, если интерфейс указан принудительно. Поиск в функции выполняется по связке интерфейс (idiag_if), протокол, local, remote, а в качестве интерфейса всегда указывается 0 (и заменить значение нельзя). То есть это не баг в sing-box, а системное ограничение.
Спасибо огромное за находку. По-моему она важнее, чем то, что написано в статье. Проверил сейчас с чистым sing-box. И правда приложение может выбирать интерфейс, правила исключения из tun тогда не работают. Если включить в системе "Block connections without VPN", то выбрать wan0 уже не получится. Но если выбрать принудительно tun0 (а не просто по умолчанию в tun0), то процесс идет в прокси, даже если есть правило по имени пакета не пускать его в прокси (в секции route). Почему-то при ручном выборе интерфейса sing-box не может определить имя пакета. В debug-логах появляется ошибка: router: failed to search process: android: connection owner not found. Пытаюсь разобраться в причине, может быть баг, а может системное ограничение.
WebView да, но пишут, что при Chrome Custom Tabs имя пакета уже не наследуется. Сам не проверял. Мы в целом накидываем разные варианты в режиме паранойи. Понятно, что может и вообще ничего делать не будут. С другой стороны сложно было поверить, что и до таких методичек дойдёт. Поживём увидим.
Вот только оно может внутри себя открыть вкладку хрома через стандартный механизм встроенных вкладок. Или открыть браузер по умолчанию со ссылкой. Например, при входе в аккаунт с быстрым редиректом.
Не знаю. Я как раз и начал эту ветку с того, что непонятно почему начали форсить, что iOS безопаснее в плане обхода блокировок. Уже со всех сторон эта информация летит. Понять включен или нет можно везде (iOS, Android). А вот раздельного туннелирования по приложениям на iOS нет, что в данном случае важнее.
Именно по приложениям на iOS раздельного туннелирования нет, а на Android есть. Если вы пустите домены телеграм через прокси, то любое приложение или сайт будет идти к телеграм через прокси, а не только сам телеграм.
Конкретного статуса включён или нет у них нет. Только по косвенным признакам могут определить раздельное туннелирование, выполняя запросы к разным сетям, чтобы вычислить IP вашего прокси. Более активные действия требуются.
В бесплатном Karing, который на ядре sing-box, есть naive:
https://apps.apple.com/us/app/karing/id6472431552
В Shadowrocket есть naive
Да, скорее всего поддерживает, потому что там внутри ядро sing-box.
Только с root. В sing-box функция есть, но без root недоступна.
Результат будет зависеть от конфига VPN-клиента и системы. Но добиться нужного результат вполне реально.
Если исключаем приложение из TUN, то доступ к TUN будет закрыт, если на уровне системы включена настройка блокировки соединений без VPN.
Если такая системная настройка выключена, то соединение попадает в VPN-клиент. Но при этом в нем может быть настроено, что по умолчанию всё блокируем или пускаем в direct, а избранные приложения по имени пакета попадают в прокси (тогда тоже всё будет хорошо).
Если по умолчанию прокси, а блокировка (или direct) через правило по имени пакета (список плохих пакетов), то да, плохая программа попадет на прокси, потому что её имя определить нельзя в таком случае (определение имен не работает). Поэтому в новом sing-box добавлена возможность правилами ловить приложения, где имя определить не удалось (или те, кто полез сам в tun, или какие-то особые случаи системных приложений).
А почему первый пакет пройдет?
Теперь понятно. У вас по умолчанию блокируется. Когда указывается tun0, то имя пакета не определяется, идёт блокировка. Без tun0 имя пакета определяется. Выходит нужно перечислить вообще все программы, а потом новые добавлять, чтобы у них работал интернет.
Странно. У меня правило по имени пакета в route не работает, если принудительно указать tun0. В том числе с strict_route.
Можете, пожалуйста, перепроверить?
В GrapheneOS это фиксили похоже: https://grapheneos.org/releases#2025072700
This release resolves 2 upstream Android VPN leaks discovered by GrapheneOS and our community testers.
prevent using SO_BINDTODEVICE to bypass VPN lockdown mode (leak protection) to resolve an upstream Android VPN leak discovered by GrapheneOS testers where code specifies a specific interface via a special system call to bypass the VPN
prevent using NsdService#connect for components restricted by VPN lockdown mode to prevent a very limited upstream Android local network VPN leak discovered by GrapheneOS
https://github.com/GrapheneOS/os-issue-tracker/issues/2381
Фикс: https://github.com/GrapheneOS/platform_packages_modules_Connectivity/pull/33/changes (запретили SO_BINDTODEVICE пакетам из списка)
Изучил. Если приложение привязывается к конкретному интерфейсу, то per-app правила не работают, так как в этом случае невозможно определить пакет по соединению. Функция getConnectionOwnerUid не находит UID, если интерфейс указан принудительно. Поиск в функции выполняется по связке интерфейс (idiag_if), протокол, local, remote, а в качестве интерфейса всегда указывается 0 (и заменить значение нельзя). То есть это не баг в sing-box, а системное ограничение.
Спасибо огромное за находку. По-моему она важнее, чем то, что написано в статье. Проверил сейчас с чистым sing-box. И правда приложение может выбирать интерфейс, правила исключения из tun тогда не работают. Если включить в системе "Block connections without VPN", то выбрать wan0 уже не получится. Но если выбрать принудительно tun0 (а не просто по умолчанию в tun0), то процесс идет в прокси, даже если есть правило по имени пакета не пускать его в прокси (в секции route). Почему-то при ручном выборе интерфейса sing-box не может определить имя пакета. В debug-логах появляется ошибка:
router: failed to search process: android: connection owner not found. Пытаюсь разобраться в причине, может быть баг, а может системное ограничение.Все-таки это не критическая уязвимость. И это не относится к VLESS. Но тема открытого socks поднята верно, хоть и немного истерично.
WebView да, но пишут, что при Chrome Custom Tabs имя пакета уже не наследуется. Сам не проверял. Мы в целом накидываем разные варианты в режиме паранойи. Понятно, что может и вообще ничего делать не будут. С другой стороны сложно было поверить, что и до таких методичек дойдёт. Поживём увидим.
Вот только оно может внутри себя открыть вкладку хрома через стандартный механизм встроенных вкладок. Или открыть браузер по умолчанию со ссылкой. Например, при входе в аккаунт с быстрым редиректом.
Не знаю. Я как раз и начал эту ветку с того, что непонятно почему начали форсить, что iOS безопаснее в плане обхода блокировок. Уже со всех сторон эта информация летит. Понять включен или нет можно везде (iOS, Android). А вот раздельного туннелирования по приложениям на iOS нет, что в данном случае важнее.
На iOS по приложениям вообще не разделить, поэтому условный ozon может попытаться отправить запрос к домену WhatsApp.
Сами проверят. Включат vpn и запустят приложение.
Именно по приложениям на iOS раздельного туннелирования нет, а на Android есть. Если вы пустите домены телеграм через прокси, то любое приложение или сайт будет идти к телеграм через прокси, а не только сам телеграм.
Может через getifaddrs() — системный вызов, который отдаёт список сетевых интерфейсов. Если среди них есть utun, ipsec или ppp — значит VPN поднят.
Конкретного статуса включён или нет у них нет. Только по косвенным признакам могут определить раздельное туннелирование, выполняя запросы к разным сетям, чтобы вычислить IP вашего прокси. Более активные действия требуются.