Ակտիվ VPN-ի հայտնաբերում sandbox-ված Mac հավելվածում
Այս հարցի համար հանրային API չկա, և ինտերֆեյսի անվան հնարքը միայն էվրիստիկա է։ Վեց ստուգում՝ որոշելու, թե ինչից պետք է իրականում կախված լինի ձեր հավելվածը։
Ձեզ պետք է մեկ էկրան, որը այլ կերպ վարվի, երբ թունելը միացված է, և չկա զանգ, որը կասի ձեզ այդ մասին։ Սա թողարկման սահմանափակումն է. macOS-ում ոչ մի հանրային ֆրեյմվորկ չի հաղորդում՝ արդյոք կամայական VPN-ը միացված է, իսկ iOS-ում կարգավիճակը պատկանում է այն հավելվածին, որը տեղադրել է կոնֆիգուրացիան։ Ստորև բերված ստուգումները տանում են այդ սահմանից դեպի մի բան, որը կարող եք թողարկել, և դրանցից ցանկացածը կարող է վաղ ավարտել որոնումը։
Ստուգում 1. արդյոք հարցին ընդհանրապես հնարավոր է պատասխանել։
Sandbox-ը լուծում է հարցը ցանկացած API-ից առաջ։ Երրորդ կողմի գործընթացը չի կարող թվարկել մեկ այլ մատակարարի ընդլայնումը և չի կարող կարդալ այդ ընդլայնման կոնֆիգուրացիան, ուստի հարցնելու համար աջակցվող օբյեկտ չկա։
Ցանկացած շրջանցում բախվում է նույն պատին։ Ինտերֆեյսների ցանկերը, scutil --nc list և համակարգի կոնֆիգուրացիայի ուղղակի ընթերցումները կա՛մ պահանջում են թույլտվություններ, որոնք sandbox-ը զսպում է, կա՛մ կախված են վարքագծից, որը Apple-ը երբեք չի խոստացել։ Եթե պլանին պետք է դրանցից մեկը, խնդիրը պլանն է։ Չփաստաթղթավորված մանրամասնության վրա կառուցված ֆունկցիան առաքման ամսաթիվ ունեցող աջակցության տոմս է։
Ստուգում 2. արդյոք ձեր հավելվածն ինքն է կառավարում թունելը։
Եթե այո, դուք ունեք աջակցվող պատասխան ձեր սեփական կոնֆիգուրացիայի համար։ Բեռնեք նախապատվությունները, մշակեք սխալը, ապա կարդացեք կարգավիճակը և բաժանորդագրվեք փոփոխություններին՝ հարցումներ անելու փոխարեն։
vpnManager.loadFromPreferences { error in
// handle a load failure before reading status
}
NotificationCenter.default.addObserver(
forName: .NEVPNStatusDidChange,
object: nil,
queue: nil
) { note in
let status = (note.object as? NEVPNConnection)?.status
}Եղեք ճշգրիտ, թե ինչ է վերադարձնում սա՝ ձեր տեղադրած թունելի վիճակը։ Այլ հաճախորդ օգտագործող օգտատերը կցուցադրվի որպես անջատված, և դա ձեր կոդի սխալ չէ։ Որոշեք, թե այդ երկու հարցերից որն է ձեր ֆունկցիան իրականում տալիս, նախքան պատասխանի վրա կառուցելը։
Ստուգում 3. ի՞նչ կասեր ձեզ էվրիստիկան իրականում։
Լայնորեն պատճենված մոտեցումը համակարգի պրոքսի բառարանից հարցնում է նրա շրջանակված գրառումները և կարդում բանալիները, որոնք պատահաբար ինտերֆեյսների անուններ են։
let settings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as NSDictionary?
let scoped = settings?["__SCOPED__"] as? [String: Any]
let names = scoped?.keys ?? []Բանալին, որը սկսվում է tap, tun, ppp, ipsec կամ utun-ով, ենթադրում է, որ առկա է թունելի շրջանակով ինտերֆեյս։ Ամբողջ անվան համապատասխանեցումը անմիջապես ձախողվում է, որովհետև iOS 12-ը եկել է utun1-ով և utun2-ով, և որոշ պրոֆիլներ հայտնվում են որպես ipsec4, ppp0 կամ utun0։ Փոխարենը համեմատեք նախածանցերը։
Այնուամենայնիվ, անունը ոչ մի սեփականատեր չի նույնականացնում։ Համակարգի ֆունկցիաները և այլ մատակարարների ընդլայնումները նույնպես ստեղծում են utun ինտերֆեյսներ, և մեկը կարող է գոյություն ունենալ՝ չկրելով ձեր թրաֆիկի ոչինչ։ Կարդացեք սա որպես ակնարկ, որ մոտակայքում կա թունելի ձևով ինչ-որ բան, ոչ ավելին։ Կեղծ դրականն այստեղ էժան է, եթե դուք սահմանափակում եք միայն մեկ ֆունկցիա, և թանկ, եթե սահմանափակում եք մուտքի էկրանը։
Ստուգում 4. կարո՞ղ եք փոխարենը ստուգել նպատակակետը։
Եթե հավելվածին պետք է միայն իմանալ՝ արդյոք ներքին ծառայությունը հասանելի է, ստուգեք այդ ծառայությունը։ Կարճ ժամկետով փորձարկումը պատասխանում է այն հարցին, որից ֆունկցիան իրականում կախված է, և այն շարունակում է աշխատել, երբ օգտատերը փոխում է հաճախորդը կամ թունելը փոխում է ձևը։
Հասանելիությունը դիտարկում է ձեր ուղու մասին։ Ինտերֆեյսի անունը եզրակացություն է ձեր ուղուն հարակից ինչ-որ բանի մասին, դրա համար էվրիստիկան վեճեր է ստեղծում սխալների հաշվետվություններում, իսկ փորձարկումը՝ ապացույցներ։ Եթե փորձարկումը ձախողվում է, մինչ օգտատերը պնդում է, որ VPN-ը միացված է, այժմ դուք ունեք կոնկրետ ուղի վրիպազերծման համար՝ անունների լուծում, երթուղի կամ ծառայության թույլտվություն։
Ստուգում 5. կարո՞ղ է հարթակը պարտադրել այն, ինչ ձեզ պետք է։
Երբ պահանջը երաշխիքն է, որ ոչինչ չի փախչի թունելից, պրոֆիլն է դրա տեղը, ոչ թե դետեկտորը։ includeAllNetworks-ը միացնելը iOS 14 կամ ավելի նոր տարբերակում ամբողջական թունելի կոնֆիգուրացիայում փոխում է հարթակի վարքը՝ ձեր հավելվածից եզրակացնել պահանջելու փոխարեն։ Դրոշը փաստաթղթավորված է NEVPNProtocol-ի տեղեկատուում։
Սա այլ տեսակի պատասխան է՝ պարտադրում դիտարկման փոխարեն։ Այն նաև կիրառվում է միայն ձեր վերահսկած պրոֆիլների նկատմամբ, ուստի չի օգնում սպառողական հավելվածին, որը հետևում է ուրիշի թունելին։
Ստուգում 6. դարձրեք ձախողումը անվտանգ և դիտարկելի
Անջատեք միայն այն հնարավորությունը, որին պետք է թունելը, և թողեք հավելվածի մնացած մասը օգտագործելի։ Դետեկտորը, որը թաքցնում է ամբողջ ինտերֆեյսը, երբ վստահ չէ, անջատում է ստեղծում բոլորի համար, ում թունելը օգտագործում է անուն, որը դուք երբեք չեք կանխատեսել։ Փոխարենը վերադարձեք պահպանողական վարքագծին. տեղական ֆունկցիաները շարունակում են աշխատել, և անջատվում է միայն այն հեռավոր զանգը, որին իսկապես պետք է թունելը։ Այդ ընտրությունը արտադրանքի որոշում է, և այն արժանի է գրվելու էվրիստիկայի կողքին։
Գրանցեք այն, ինչ դիտարկել եք՝ ինտերֆեյսների անունները, հարթակի տարբերակը և մեկ փորձարկման արդյունքը։ Դա հաջորդ հաշվետվությունը վեճից վերածում է ստուգման։ Այնուհետև նախապատվություն տվեք աջակցվող հայտարարությանը, որտեղ այն ունեք, քանի որ կառավարվող կոնֆիգուրացիան կարող է միտքը փոխանցել բացահայտ և վերացնել անունները ստուգելու հիմնական պատճառը։
Եթե 1-ից 5 ստուգումները ձեզ թողել են առանց աջակցվող պատասխանի, թողարկեք փորձարկումը և արդյունքը պիտակավորեք ազնվորեն։ Փաստաթղթավորված լավագույն ջանքի ազդանշանը ավելի լավ արտադրանքի որոշում է, քան մասնավոր API-ն, որը կոտրվում է հաջորդ թողարկումում։