Ինչ կարող է ստեղծել NEVPNManager-ը iOS-ում (և ինչ՝ ոչ)
iOS-ի VPN API-ն երեք պրոտոկոլային դասերից կառուցում է հավելվածին պատկանող մեկ կոնֆիգուրացիա։ L2TP-ն, PPTP-ն և ստորագրված պրոֆիլները այդ մակերևույթի մաս չեն։
Երբ iOS հավելվածի ներսում VPN էկրան ես կառուցում, առաջին անակնկալն այն է, որ Կարգավորումներ հավելվածի պրոտոկոլների ցանկը API-ի ցանկը չէ։ Network Extension շրջանակը թույլ է տալիս քո հավելվածին ստեղծել մեկ անձնական VPN կոնֆիգուրացիա՝ պատկանող այդ հավելվածին, և այն ընդունում է միայն մի քանի պրոտոկոլային օբյեկտ։ Մնացած ամեն ինչ, ինչ մարդիկ սպասում են՝ L2TP-ից մինչև ներբեռնված պրոֆիլ, գտնվում է այդ մակերևույթից դուրս կամ Apple-ի համար մասնավոր է։ Հետևող ձախողումները սովորաբար բագեր չեն, դա API-ն է մերժում աշխատանք, որը երբեք չի ստացել։
Առասպել. API-ն Կարգավորումների խմբագիր է
Կարծում են, թե քանի որ iOS-ը կարող է կարգավորել IKEv1, IKEv2, L2TP և IPsec պրոֆիլներ, հավելվածը կարող է դրանցից ցանկացածը ստեղծել ծրագրային եղանակով։ Չի կարող։ Շրջանակը զանգահարող հավելվածին տրամադրում է ճիշտ մեկ կոնֆիգուրացիոն տեղ, և այդ տեղը ընդունում է հանրային պրոտոկոլային դասերի փոքր հավաքածու։ Մնացած ամեն ինչ, ինչ մարդիկ սպասում են՝ L2TP-ից մինչև ներբեռնված պրոֆիլ, գտնվում է այդ մակերևույթից դուրս կամ Apple-ի համար մասնավոր է։
Հետևող ձախողումները սովորաբար բագեր չեն։ Դա API-ն է մերժում աշխատանք, որը երբեք չի ստացել, և լուծումն այն է՝ էկրանը ձևավորել այն բանի շուրջ, ինչը պատկանում է API-ին։
Երեք պրոտոկոլային օբյեկտ և նրանք, որոնք գոյություն չունեն
Քո տարբերակներն են IKEv1-ը NEVPNProtocolIPSec-ի միջոցով, IKEv2-ը NEVPNProtocolIKEv2-ի միջոցով, և NETunnelProviderProtocol-ը, եթե առաքում ես սեփական փաթեթային թունելի ընդլայնում։ NEVPNManager-ի տեղեկատուն թվարկում է ընդունված պրոտոկոլային օբյեկտները։ L2TP-ն և PPTP-ն երբեք չեն հայտնվում այդ ցանկում, որովհետև Apple-ը դրանց համար դասեր չի հրապարակել։ Դրանցից որևէ մեկը փորձելը ավարտվում է պահպանման պահին սխալով կամ ավելի վատ՝ կոնֆիգուրացիայով, որն համակարգը լուռ հրաժարվում է օգտագործել։
Աշխատասեղանի կոդը հետևում է այլ կանոնների։ macOS-ում SCNetworkInterfaceCreateWithInterface-ը շարում է ինտերֆեյսի տիպ, օրինակ L2TP՝ IPv4-ի վրա, և կցում է այն ցանցային ծառայությանը, իսկ networksetup -connectpppoeservice-ը մեկնարկում է արդյունքը։ Պահանջվում են ադմինիստրատորի իրավունքներ և օժանդակ գործիք, քանի որ ընդհանուր գաղտնիքն ու գաղտնաբառը գնում են համակարգի բանալիների շղթա։ Պատճենիր այդ ձևավորումը iOS-ի վրա և ոչինչ չի կոմպիլվի։
Փոխանցիր բանալիների շղթայի հղում, ոչ թե գաղտնաբառը
IKE դասերից ոչ մեկը գաղտնաբառը որպես տեքստ չի ընդունում։ Երկու հատկություն՝ passwordReference-ը և sharedSecretReference-ը, ցանկանում են մշտական բանալիների շղթայի հղում, որը ստանում ես SecItemCopyMatching-ից՝ խնդրելով kSecReturnPersistentRef։ Տարրի տվյալները փոխանցելը կամ դաշտում տող մտցնելը առաջացնում է պահպանման ձախողում կամ դատարկ հավատարմագրերով կապ։ Հղումը նույնքան դիմացկուն է, որքան դրա հետևում գտնվող բանալիների շղթայի տարրը, դրա համար տարրը պետք է գոյություն ունենա մինչև կոնֆիգուրացիայի հավաքումը։ Ստեղծիր այն պահպանման նույն տրանզակցիայում և կվերացնես դասակարգման բագերի մի ամբողջ դաս։
Վկայագրային նույնականացումն այլ ուղի է գնում՝ identityData գումարած identityDataPassword PKCS#12 բլոբի համար։ Այդ բլոբը հավելվածի փաթեթի ներսում առաքելը օրինակելի կոդից փոխանցված սովորություն է, ոչ թե թողարկման որոշում, որովհետև գաղտնաբառը ճամփորդում է դրա հետ, և հավելվածի յուրաքանչյուր պատճեն կրում է նույն ինքնությունը։
Իրավունքը և հասանելիությունը պայմանավորում են ամեն ինչ
Կառավարիչը կարող է ընդհանրապես գոյություն չունենալ, և պատճառը տրամադրումն է։ Քո հավելվածի նույնացուցիչին անհրաժեշտ է Network Extension հնարավորությունը՝ անձնական VPN-ի իրավունքի հետ միասին, և build-ը ստորագրող պրոֆիլը պետք է կրի երկուսն էլ։
Բաց թող դա, և ընդհանուր օրինակը վերադարձնում է nil, կամ պահպանումը ձախողվում է սխալով, որը երբեք չի հիշատակում իրավունքը։ Հասանելիությունը երկրորդ դարպասն է։ Թիրախավորիր iOS 8-ից հին որևէ բան, և սիմվոլը բացակայում է կատարման պահին, ուստի ձախողումը խափանում է կամ nil կառավարիչ, այլ ոչ թե առանց կոնֆիգուրացիայի կառավարիչ։ Ստուգիր կատարման միջավայրը և իրավունքը նախքան օբյեկտների գրաֆիկը վրիպազերծելը։
Բեռնիր, փոխիր, պահպանիր, ապա հետևիր պահանջարկի հերթականությանը
Կենսացիկլը դիտարկիր որպես բեռնում, փոփոխություն, պահպանում և երբեք չշրջանցիր բեռնումը։ Քանի դեռ loadFromPreferences-ը չի ավարտվել, կառավարիչը ոչինչ չի պահում, և պրոտոկոլային օբյեկտը հնարավոր չէ կարդալ կամ փոխարինել։
Երկրորդ պահպանումը փոխարինում է կոնֆիգուրացիան՝ փոխարենը մեկ ուրիշ ավելացնելու, ուստի կիսատ պահպանումը կարող է վնասել աշխատող պրոֆիլը։ Պահանջարկի կանոնները կազմում են դասավորված զանգված, և այդ կարգը քաղաքականությունն է։ Դիր ցանկացած տեղից միանալու կանոնը անջատման կանոնից առաջ, և ձեռքով անջատումից հետո անմիջապես հաջորդում է վերամիացում, ինչը թերության տպավորություն է թողնում, բայց հետևում է փաստաթղթավորված գնահատմանը։
Անջատման կանոնը տեղափոխիր առաջ, երբ օգտվողի գործողությունը պետք է հաղթի։ Այն, ինչ մնում է հավելվածի վերահսկողությունից դուրս, նույնքան կարևոր է։ Երթուղիները գալիս են թունելից կամ սերվերի քաղաքականությունից, ոչ թե քո սահմանած նախապատվությունից, և փաթեթային թունելի մատակարարը հաղորդում է դրանց մեկնարկելիս։ Հավելվածը չի կարող թվարկել կամ խմբագրել այլ հավելվածների կամ կոնֆիգուրացիոն պրոֆիլների կողմից տեղադրված պրոֆիլները, ուստի սարքի բոլոր VPN-ները ցուցադրող էկրան մի խոստացիր։