VPN на iOS и macOS: ограничения Network Extension, always-on режим и per-app туннелирование

На iOS и macOS сторонние приложения не имеют прямого доступа к TUN/TAP-интерфейсам. Единственный легальный способ реализовать VPN-туннель — фреймворк Network Extension, который Apple предоставляет с жёсткими рамками: лимиты памяти, требования к MDM для always-on и per-app режимов, изолированный процесс расширения. Эти ограничения определяют, что может и чего не может делать VPN-клиент на платформах Apple.

Архитектура Network Extension​


Network Extension — это набор классов, позволяющих расширять сетевую функциональность системы без модификации ядра. Для VPN релевантны два провайдера:

  • NEPacketTunnelProvider — создаёт виртуальный сетевой интерфейс и перехватывает IP-пакеты на уровне L3. Именно его используют WireGuard, OpenVPN Connect, Outline и большинство коммерческих VPN-клиентов.
  • NEAppProxyProvider — работает на уровне L4 (TCP/UDP-соединения) и позволяет проксировать трафик отдельных приложений. Используется реже, но именно он лежит в основе per-app туннелирования без MDM на macOS.

На iOS расширение работает как отдельный процесс, изолированный от основного приложения. Пользователь видит только приложение-оболочку, а всю работу выполняет extension. На macOS начиная с Catalina Network Extension реализуется через System Extension (замена kernel extensions), что также означает отдельный процесс с собственным sandbox.

Жизненный цикл процесса расширения​


Система управляет процессом VPN-расширения по собственным правилам:

  1. Расширение запускается при активации туннеля (пользователем, MDM-профилем или on-demand правилом).
  2. При переходе устройства в сон или при нехватке памяти система может приостановить или завершить процесс.
  3. После завершения процесса туннель разрывается. Если включён always-on, система попытается перезапустить расширение.
  4. Расширение не может выполнять фоновую работу, когда туннель неактивен.

Это означает, что VPN-клиент на iOS не может «держать соединение» в фоне произвольно долго — он живёт ровно столько, сколько система считает нужным.

Лимиты ресурсов​


Процесс Network Extension работает в sandbox с ограниченной памятью. На iOS лимит составляет порядка 50 МБ для процесса расширения (точное значение зависит от версии ОС и устройства). При превышении лимита система завершает процесс без предупреждения.

Практические следствия:

  • WireGuard на iOS хранит в памяти только криптографическое состояние и таблицу пиров, что укладывается в лимит благодаря минималистичному дизайну протокола. Протокол оперирует ассоциацией публичных ключей с AllowedIPs и не требует TLS-рукопожатий или сложных состояний сессии.
  • OpenVPN-клиенты, использующие TLS с цепочками сертификатов и буферами, ближе к границе лимита.
  • Клиенты с агрессивным логированием или кэшированием DNS-запросов могут получить неожиданное завершение процесса.

На macOS лимиты мягче, но sandbox всё равно ограничивает доступ к файловой системе и системным вызовам. Расширение не может читать произвольные файлы, запускать дочерние процессы или открывать сокеты вне туннеля.

Always-on VPN​


Always-on — режим, при котором VPN-соединение устанавливается автоматически при загрузке устройства и не может быть отключено пользователем. На iOS и macOS он реализуется по-разному.

Требования к always-on на iOS​


На iOS always-on VPN требует выполнения двух условий:

  • Устройство должно находиться в режиме Supervised (активируется через Apple Business Manager или Apple Configurator при первоначальной настройке).
  • MDM-сервер устанавливает конфигурационный профиль с VPN-payload, в котором ключ AlwaysOn установлен в true.

Пользователь не может отключить такой VPN через настройки — переключатель становится неактивным. Без Supervised-режима и MDM always-on на iOS невозможен. Это ограничение на уровне ОС, обойти его средствами приложения нельзя.

Always-on на macOS через профиль​


На macOS always-on VPN можно настроить двумя способами:

  • Через MDM-профиль (аналогично iOS, но Supervised-режим не требуется).
  • Через конфигурационный профиль, установленный вручную (.mobileconfig файл), с ключом AlwaysOn.

В обоих случаях система будет автоматически переподключать VPN при разрыве соединения и не позволит пользователю отключить его через системные настройки без удаления профиля.

On-Demand Rules как альтернатива​


Если always-on слишком жёсткий, Network Extension поддерживает On-Demand Rules — набор условий, при которых туннель активируется или деактивируется автоматически. Правила могут учитывать:

  • SSID текущей Wi-Fi сети.
  • Наличие или отсутствие определённых DNS-серверов.
  • URL-адрес, к которому приложение пытается подключиться (probe URL).
  • Тип интерфейса (Wi-Fi, сотовая сеть, Ethernet).

On-Demand Rules настраиваются в конфигурации провайдера и работают без MDM на обеих платформах. Это компромисс: VPN не активен постоянно, но включается автоматически при соблюдении условий.

Per-app туннелирование​


Per-app VPN позволяет направить через туннель трафик только определённых приложений, а остальной трафик пустить напрямую. Механизм зависит от платформы.

Привязка per-app к MDM на iOS​


На iOS per-app VPN реализуется исключительно через MDM-профиль. В payload указываются bundle identifier приложений, трафик которых должен идти через туннель. Без MDM приложение не может программно ограничить туннель определёнными процессами.

Типичный сценарий: корпоративное устройство, где через VPN должен работать только почтовый клиент и внутренний мессенджер, а браузер и личные приложения используют прямое соединение.

Ограничения per-app на iOS:

  • Нельзя указать per-app правила из самого приложения — только через MDM.
  • Если приложение не указано в списке, его трафик идёт напрямую (или блокируется, в зависимости от политики).
  • Системные сервисы (iCloud, App Store, push-уведомления) не подчиняются per-app правилам и всегда используют прямое соединение.

NEAppProxyProvider на macOS​


На macOS per-app туннелирование возможно без MDM через NEAppProxyProvider. Этот провайдер перехватывает TCP- и UDP-соединения на уровне сокетов и может принимать решение для каждого соединения отдельно: проксировать через туннель или отклонить.

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

WireGuard и Network Extension​


WireGuard на iOS и macOS реализован как NEPacketTunnelProvider. Официальный клиент использует минимальную конфигурацию: приватный ключ, список пиров с публичными ключами и AllowedIPs. Модель Cryptokey Routing — ассоциация публичных ключей с разрешёнными IP-адресами — позволяет обходиться без сложных таблиц состояний и TLS-сессий.

При отправке пакета WireGuard определяет пира по адресу назначения из таблицы AllowedIPs, шифрует пакет его публичным ключом и отправляет на последний известный endpoint. При получении — расшифровывает, проверяет источник и сверяет с AllowedIPs. Эта простота напрямую влияет на потребление памяти и стабильность в условиях sandbox.

Однако даже WireGuard сталкивается с платформенными ограничениями:

  • На iOS без MDM невозможно включить always-on или per-app режим.
  • При завершении процесса расширения (нехватка памяти, сон устройства) туннель разрывается. WireGuard автоматически переподключается при возобновлении работы, но разрыв неизбежен.
  • На iOS расширение не может выполнять keepalive-пакеты, когда процесс приостановлен системой.

Диагностика проблем с Network Extension​


Когда VPN-расширение нестабильно или не запускается, полезны следующие шаги.

Диагностика на iOS​


  1. Проверка статуса в настройках: Настройки → VPN. Если отображается ошибка, система обычно указывает код (например, NEVPNErrorConfigurationInvalid).
  2. Системный лог через Console.app: подключите устройство к Mac, откройте Console.app и фильтруйте по имени процесса расширения. Ищите записи с nesessionmanager и именем вашего провайдера.
  3. Проверка MDM-профиля: Настройки → Основные → Управление устройством. Убедитесь, что профиль установлен и не повреждён.

Диагностика на macOS​


  1. systemextensionsctl: команда systemextensionsctl list показывает установленные системные расширения и их статус.
  2. Log Stream: log stream --predicate 'subsystem == "com.apple.networkextension"' выводит события Network Extension в реальном времени.
  3. Проверка sandbox-нарушений: в логах ищите записи Sandbox: deny с указанием расширения — это означает, что процесс пытается выполнить запрещённую операцию.

Типичные ошибки и их причины​


СимптомВероятная причина
Расширение не запускаетсяНе выдано разрешение пользователем (macOS) или не установлен MDM-профиль (iOS)
Туннель обрывается через 30–60 секундПревышен лимит памяти, система завершила процесс
Always-on не работаетУстройство не в Supervised-режиме (iOS) или профиль не содержит ключ AlwaysOn
Per-app не применяетсяПрофиль установлен без MDM (iOS) или bundle identifier указан с ошибкой
Трафик идёт мимо туннеляAllowedIPs не покрывает нужные подсети или on-demand правила конфликтуют с маршрутами

Архитектурные ограничения, которые нельзя обойти​


Ряд ограничений Network Extension является фундаментальным и не обходится средствами приложения:

  • Нет доступа к raw sockets из расширения.
  • Нельзя создать более одного активного packet tunnel одновременно (система позволяет только один NEPacketTunnelProvider в активном состоянии).
  • Расширение не может модифицировать системную таблицу маршрутов напрямую — только через параметры туннеля, переданные системе.
  • На iOS приложение-оболочка и расширение не разделяют память; обмен данными возможен только через App Group (UserDefaults, файлы в общем контейнере).
  • Расширение не может инициировать сетевые соединения вне туннеля для собственных нужд (например, для обновления конфигурации) — весь исходящий трафик проходит через туннель или блокируется.

Эти рамки определяют, что любой VPN-клиент на платформах Apple — это компромисс между гибкостью и требованиями sandbox. Для корпоративного развёртывания с always-on и per-app необходим MDM; для индивидуального использования доступны on-demand rules и ручное управление туннелем.

Источники​


 
Назад
Верх Низ