Чому застосунок не може ввімкнути збережений профіль VPN на Android або iOS
Побудувати власний тунель і ввімкнути збережений профіль — дві різні задачі. Порівняйте, що Android, iOS і десктоп насправді дозволяють застосунку.
Дві зовсім різні задачі потрапляють під назву програмного VPN, і лише одна з них доступна звичайному застосунку на будь-якій із двох мобільних платформ. Перша — увімкнути профіль, який користувач уже зберіг; друга — побудувати тунель у власному процесі. Android дає другу через VpnService, а iOS дає другу через право Network Extension, тоді як перша залишається в системи, власника пристрою або сервера MDM. З’ясування, яка з них справді потрібна, зазвичай робить проєкт меншим.
Дві задачі з однією назвою
Активація збереженого профілю означає сказати наявному тунелю піднятися: хост, облікові дані, протокол — усе вже налаштовано там, де користувач це бачить. Побудова тунелю означає, що ваш код володіє інтерфейсом, циклом пакетів і протоколом. У продуктовому беклозі вони виглядають схоже й майже не ділять реалізацію.
Жодна з двох мобільних платформ не відкриває першу для SDK-застосунку. З’єднання, що з’являється без будь-яких дій користувача, не відрізнити від шкідливого програмного забезпечення, тому обидві системи ставлять браму згоди перед будь-яким застосунком, що переносить трафік.
Android: брама згоди і жодного API профілів
VpnService існує з Android 4.0 і дозволяє застосунку створити інтерфейс tun, а потім читати й записувати пакети. Службу потрібно оголосити з BIND_VPN_SERVICE, а VpnService.prepare() створює системний діалог, який просить користувача дозволити її. Приклад платформи ToyVpn — найясніше твердження задуманої форми: ваш код володіє інтерфейсом і всім, що через нього проходить.
Чого він не робить — не додає запису на екран налаштувань VPN системи. Публічного API для цього немає, а застосунок Налаштування тримає свої профілі в сховищі, до якого звичайний застосунок не дістанеться. Виклики прихованих класів зі звичайного застосунку створюють профілі, які система ніколи не показує, тому код, що, здавалося, працював в одній збірці, тихо перестає працювати в наступній.
Керований шлях окремий. Власник пристрою або профілю може призначити завжди ввімкнений пакет VPN через API політики пристрою, а корпоративний інструмент може надіслати профіль, який користувач потім схвалить. Це повноваження керування пристроєм, а не дозвіл, який застосунок просить під час встановлення. Якщо ваш клієнт — організація, це шлях, для якого треба планувати; якщо ваш клієнт — людина, що встановлює з магазину, він зовсім недоступний.
iOS: право — це межа
iOS ділить ту саму роботу інакше. Клієнт VPN реалізує постачальника пакетного тунелю або проксі застосунку в межах Network Extension, і відповідне право має бути надано обліковому запису розробника. Особиста конфігурація VPN через NEVPNManager існує для простішого випадку й досі працює в тій самій моделі дозволів. Apple документує всю поверхню в довіднику Network Extension, який варто прочитати, перш ніж визначати обсяг роботи.
Немає підтримуваного способу відкрити екран налаштувань VPN, прочитати збережені конфігурації користувача або запустити одну з них. Клієнт може надіслати профіль конфігурації для встановлення користувачем, а потім використовувати отриманий тунель через звичайні мережеві виклики. Тунелювання для кожного застосунку призначає сервер MDM правилом за вимогою, а не вибирає застосунок під час виконання.
Клієнт VPN великого постачальника не є доказом, що ваш обліковий запис може надіслати те саме. Ці права запитуються для кожного облікового запису розробника й переглядаються, тому ризик графіка лежить на Apple, а не в вашому плані спринту.
Десктоп сягає далі, але володіння не змінюється
Windows — дозвільний випадок. Add-VpnConnection створює запис телефонної книги з підвищеної сесії PowerShell, а rasdial підключає або відключає його зі скрипта. Застосунок також може керувати клієнтом постачальника через його документований командний рядок. Створення профілю все ще адміністративна дія, бо запис живе в сховищі всієї машини.
macOS поводиться так само з іншими інструментами. scutil --nc start і stop працюють із уже наявними службами, тоді як створення однієї — задача системного адміністрування. Володіння процесом на ноутбуці не робить вас власником конфігурації.
Що будувати замість цього
Якщо справжня вимога — щоб ваш застосунок діставався внутрішнього API, достатньо тунелю, який користувач уже запускає. Надсилайте звичайні HTTPS-запити, дозвольте системі вибрати шлях, і перестаньте намагатися керувати тунелем. Якщо вимога — щоб тунель використовував лише трафік вашого застосунку, попросіть VPN для кожного застосунку через канал керування або завершіть TLS усередині застосунку перед службою, доступною без нього.
Приховані API — не короткий шлях, який варто обирати. Вони змінюються між випусками, провалюють перевірку застосунків, а збої, які вони спричиняють, тому, хто успадковує код, здаються звичайними мережевими збоями. Порівняння не Android проти iOS; це володіння тунелем проти прохання до платформи спрямовувати трафік, і лише перше — ваше, щоб будувати.