API за VPN на iOS-у: NEVPNManager, добављач тунела или профил?
Изаберите API према транспорту са којим морате да разговарате, затим докажите да тунел носи саобраћај: редослед save-load-start, provider entitlement-и и on-demand правила.
Три различита производа одговарају на назив iOS VPN и не деле један API. Personal VPN користи уграђене IPsec и IKEv2 транспорте система. Custom tunnel покреће ваш сопствени протокол унутар network extension-а. Configuration profile конфигурише било који од њих и може да дода on-demand понашање. Избор према транспорту са којим морате да разговарате бржи је од избора према оном упутству које се прво компајлирало.
Покрените провере испод редом, јер сваки корак претпоставља да је претходни произвео важећу конфигурацију.
Корак 1: изаберите према транспорту
Ако је сервер IKEv2 или IPsec у Cisco стилу, NEVPNManager је довољан и системски транспорти долазе бесплатно. Ако сервер говори OpenVPN, WireGuard или било шта друго, NEVPNManager не може да помогне: нема куку за протокол треће стране. Тај случај захтева NETunnelProviderManager са packet tunnel provider-ом који имплементира протокол. Профил само дистрибуира конфигурацију и не може да дода транспорт који оперативни систем нема.
PPTP није циљ на тренутним системима. IPsec са заједничком тајном још увек очекује назив групе у remoteIdentifier-у, keychain ставку која чува тајну и проширену аутентификацију када сервер затражи корисничко име. Сваки део који недостаје појављује се као иста општа грешка конфигурације, зато их додајте све пре него што почнете да отклањате било шта друго.
Корак 2: поштујте редослед чувања, учитавања и покретања
NEVPNManager пише у preferences, чита их назад и тек онда покреће. Попуните објекте протокола и manager-а, позовите saveToPreferences, позовите loadFromPreferences и позовите startVPNTunnel из load completion handler-а. Покретање пре него што се учитавање врати производи грешку configuration-invalid, NEVPNErrorDomain code 1, на конфигурацији која је иначе исправна.
Облик је довољно кратак да стане на једно место:
manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }startVPNTunnel се враћа када је захтев прихваћен, а не када је тунел подигнут. Посматрајте NEVPNStatusDidChange и читајте connection.status за стварно стање. Апликација која претпоставља успех на месту позива пријављује повезан VPN док extension још преговара. Стање connecting је нормално на тренутак; стање из којег се никада не излази је квар који вреди забележити.
Корак 3: дајте provider процесу оно што му је потребно
Custom transport ради у засебном процесу са сопственим bundle identifier-ом и сопственим entitlement-ом. И container апликација и provider потребни су network-extension entitlement при потписивању, а Developer ID build ван App Store-а мора ипак да га носи у provisioning profile-у. Entitlement који недостаје изгледа као грешка протокола јер се extension једноставно не покреће.
Нема јавног socket descriptor-а да се позајми. NEPacketTunnelProvider вам даје NEPacketTunnelFlow са read, write и cancel, а код који посеже за приватним путањама кључева крши се између издања. Provider наставља да ради док је апликација у позадини, па container апликацији за то не треба позадински режим.
Корак 4: on-demand је скуп правила, а не прекидач
isOnDemandEnabled само активира правила; NEOnDemandRuleConnect и његова браћа одлучују када се тунел подиже. Правило evaluate-connection са probe URL-ом вреди онолико колико вреди тај URL. Ако probe одговори без тунела, правило закључује да је приватна мрежа већ достижна и никада се не повезује, зато га усмерите ка нечему што одговара само изнутра.
Always-on је одвојено обећање. Потребан му је надгледани уређај и управљани профил, а ненадгледани корисник може да уклони профил кад год пожели. Не испоручујте дизајн који зависи од always-on-а осим ако флота није надгледана.
Корак 5: докажите пут, а не етикету
Скенирање tun, tap, ppp или ipsec интерфејса доказује да је VPN конфигурисан, а не да га је ваш захтев користио. NWPathMonitor са usesInterfaceType(.other) каже да је виртуелни интерфејс доступан, а viability handler може да тестира један хост. Ниједно не доказује излазни пут, зато их комбинујте са захтевом ка ресурсу до којег само тунел може да стигне. Имена интерфејса су дијагностичка помоћ, никада капија на којој би апликациона логика требало да се грана.
За теренску проверу упоредите јавну адресу са и без тунела и преузмите страницу само за интерну употребу. Status позив може да пријави повезаност док provider преговара, зато нека одлучи резултат ресурса, а status третирајте као пратећи доказ.