API за VPN в iOS: NEVPNManager, доставчик на тунел или профил?
Изберете API според транспорта, на който трябва да говорите, после докажете, че тунелът пренася трафик: ред на запазване, зареждане и стартиране, права на доставчика и правила за работа при поискване.
Три различни продукта отговарят на името VPN в iOS и те не споделят един API. Личният VPN работи върху вградените в системата транспорти IPsec и IKEv2. Собственият тунел пуска вашия протокол вътре в разширение за мрежа. А конфигурационният профил настройва всеки от двата и може да добави поведение при поискване. Изборът според транспорта, на който трябва да говорите, е по-бърз от избора според урока, който първи се е компилирал.
Изпълнете проверките по-долу по ред, защото всяка стъпка предполага, че предишната е дала валидна конфигурация.
Стъпка 1: избор според транспорта
Ако сървърът е IKEv2 или IPsec в стил Cisco, NEVPNManager е достатъчен и системните транспорти идват безплатно. Ако сървърът говори OpenVPN, WireGuard или нещо друго, NEVPNManager не може да помогне: в него няма кука за протокол на трета страна. Този случай изисква NETunnelProviderManager с доставчик на пакетен тунел, който реализира протокола. Профилът само разпространява конфигурация и не може да добави транспорт, който операционната система няма.
PPTP не е цел на настоящите системи. IPsec с обща тайна все още очаква името на групата в remoteIdentifier, елемент от ключодържателя с тайната и разширено удостоверяване, когато сървърът поиска потребителско име. Всяка липсваща част се проявява като същата обща грешка в конфигурацията, затова ги добавете всички, преди да отстранявате нещо друго.
Стъпка 2: спазвайте реда запазване, зареждане, стартиране
NEVPNManager записва в предпочитанията, прочита ги обратно и само след това стартира. Попълнете обектите на протокола и на мениджъра, извикайте saveToPreferences, извикайте loadFromPreferences и извикайте startVPNTunnel от манипулатора за завършване на зареждането. Стартиране преди зареждането да се върне дава грешка за невалидна конфигурация, код 1 в NEVPNErrorDomain, при конфигурация, която иначе е правилна.
Формата е достатъчно кратка, за да се пази на едно място:
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }
startVPNTunnel се връща, когато заявката е приета, а не когато тунелът е вдигнат. Наблюдавайте NEVPNStatusDidChange и четете connection.status за действителното състояние. Приложение, което приема успех на мястото на извикването, съобщава за свързан VPN, докато разширението още преговаря. Състояние на свързване е нормално за момент; състояние, което никога не го напуска, е повредата, която си струва да се запише.
Стъпка 3: дайте на процеса на доставчика каквото му е нужно
Собственият транспорт работи в отделен процес със свой идентификатор на пакета и свои права. И приложението-контейнер, и доставчикът се нуждаят от правото за разширение на мрежа при подписване, а изграждане с Developer ID извън App Store все още трябва да го носи в профила за осигуряване. Липсващо право изглежда като грешка в протокола, защото разширението просто не стартира.
Няма публичен дескриптор на сокет за заемане. NEPacketTunnelProvider ви дава NEPacketTunnelFlow с read, write и cancel, а код, който посяга към частни пътища на ключове, се чупи между изданията. Доставчикът продължава да работи, докато приложението е във фонов режим, така че контейнерът не се нуждае от фонов режим за това.
Стъпка 4: работата при поискване е набор от правила, а не ключ
isOnDemandEnabled само зарежда правилата; NEOnDemandRuleConnect и подобните му решават кога тунелът се вдига. Правило за оценка на връзка с пробен URL е толкова добро, колкото е този URL. Ако пробата отговори без тунела, правилото заключава, че частната мрежа вече е достъпна, и никога не се свързва, затова го насочете към нещо, което отговаря само отвътре.
Постоянната работа е отделно обещание. Тя изисква наблюдавано устройство и управляван профил, а потребител без наблюдение може да премахне профил когато пожелае. Не доставяйте дизайн, който зависи от постоянна работа, освен ако паркът не е под наблюдение.
Стъпка 5: докажете пътя, а не етикета
Сканирането за интерфейси tun, tap, ppp или ipsec доказва, че VPN е конфигуриран, а не че заявката ви го е използвала. NWPathMonitor с usesInterfaceType(.other) казва, че виртуален интерфейс е наличен, а манипулатор за жизнеспособност може да тества един хост. Нито едно от двете не доказва изходния път, затова ги съчетайте със заявка към ресурс, който само тунелът може да достигне. Имената на интерфейсите са диагностично помагало, никога порта, на която логиката на приложението трябва да се разклонява.
За проверка на място сравнете публичния адрес с тунела и без него и изтеглете страница, достъпна само отвътре. Извикване за състояние може да съобщи свързано, докато доставчикът преговаря, затова оставете резултата от ресурса да решава, а състоянието третирайте като подкрепящо доказателство.