რატომ ვერ ამატებს თქვენი Android აპი სისტემურ VPN პროფილს
VpnService ქმნის გვირაბს, რომელიც თქვენს აპს ეკუთვნის; მას არ შეუძლია ტელეფონის PPTP, L2TP ან IPsec ჩანაწერების დამატება ან რედაქტირება. გაიარეთ საზღვარი და აირჩიეთ სწორი გზა.
თქვენ ეხებით VPN-ის სტრიქონს პარამეტრებში, ხედავთ პროფილს, რომელიც სხვამ დააყენა, და იწყებთ იმ გამოძახების ძებნას, რომელიც მას ამატებს. ასეთი გამოძახება არ არსებობს. აპს შეუძლია გახსნას საკუთარი გვირაბი VpnService-ის მეშვეობით, მაგრამ იმ სიის ჩანაწერები პლატფორმას და იმ კლიენტს ეკუთვნის, რომელმაც ისინი შექმნა. ზუსტად იმის ცოდნა, სად გადის საზღვარი, დაგიზოგავთ კვირას ფარული კლასების დევნაში.
დაიწყეთ იმით, რასაც პარამეტრების ეკრანი აჩვენებს
VPN-ის სია არის პროფილების რეესტრი, რომლებიც დააყენა სისტემამ ან მწარმოებლის კლიენტმა: PPTP, L2TP/IPsec, IKEv2 და ნებისმიერი სტრიქონი, რომელიც OEM აპმა ან MDM-მა შეიყვანა. თითოეულ სტრიქონს აქვს სერვერის მისამართი, სერთიფიკატები და პროტოკოლის იმპლემენტაცია, რომელიც თქვენი პროცესის გარეთ ცხოვრობს. როცა მომხმარებელი იქ კავშირზე აჭერს, გვირაბს პლატფორმის კლიენტი წევს, და არა თქვენი კოდი. ამიტომ გადაურჩება სტრიქონი გადატვირთვას და ამიტომ თქვენი აპის წაშლა მას არასდროს არ ხსნის.
მომხმარებლის მხრიდან სია API-ის ზედაპირს ჰგავს, ადგილს, სადაც VPN-ის დამატება ერთი განზრახვის მანძილზე უნდა იყოს. ასე არ არის. ერთადერთი საჯარო შესასვლელი წერტილები, რომლებიც მას ეხებიან, ნავიგაციის განზრახვებია, და ყველაფერი, რაც მასში წერს, პლატფორმას ან პრივილეგირებულ კომპონენტს ეკუთვნის.
პრაქტიკული შედეგი: თუ მხარდაჭერის ტექსტი ეუბნება მომხმარებლებს, დაამატონ პროფილი პარამეტრებში, თქვენი აპი საერთოდ არ არის ამ ნაკადის ნაწილი.
რას გაძლევთ VpnService სინამდვილეში
VpnService და VpnService.Builder აღწერენ ერთ გვირაბს, რომელიც თქვენს აპს ეკუთვნის. თქვენ ამატებთ მისამართებს, მარშრუტებს, DNS სერვერებს და MTU-ს, ზღუდავთ ტრაფიკს addAllowedApplication() ან addDisallowedApplication() მეშვეობით, და შემდეგ establish() აბრუნებს ParcelFileDescriptor-ს TUN ინტერფეისისთვის. ამ მომენტიდან აპი კითხულობს IP პაკეტებს და წერს პასუხებს, რაც ნიშნავს, რომ პროტოკოლი თქვენია დასანერგად ან ჩასაშენებლად: OpenVPN, WireGuard, საკუთარი ტრანსპორტი.
ამ თანმიმდევრობაში არაფერი ლაპარაკობს PPTP-ზე, L2TP/IPsec-ზე ან IKEv2-ზე. Builder-ს არ აქვს გადამრთველი, რომელიც იტყვის გამოიყენე სისტემის L2TP კლიენტი, და არ არსებობს უკუგამოძახება, რომელიც საშუალებას მოგცემთ მართოთ პროფილი, რომელიც უკვე პლატფორმას ეკუთვნის. ეს არის ნამდვილი საზღვარი და ეს დიზაინის საზღვარია და არა ნებართვების ხარვეზი.
ამიტომ აპი სავსებით შეიძლება იყოს VPN კლიენტი Android-ზე. უბრალოდ ვერ იქნება ტელეფონთან მომავალი კლიენტების მმართველი.
თანხმობის დიალოგი მორთულობა არ არის
რადგან თქვენი გვირაბი შეიძლება სხვა აპების ტრაფიკს დაიჭიროს, სისტემა მოითხოვს, რომ მომხმარებელმა ის ცალსახად დაამტკიცოს. prepare() აბრუნებს Intent-ს, რომელიც უნდა გაუშვათ, დამტკიცება თქვენს პაკეტს უკავშირდება, და სანამ გვირაბი აქტიურია, სტატუსის ზოლი მუდმივ ინდიკატორს აჩვენებს. მეორე VPN-ის აწევა გამორთავს პირველს, რადგან Android ერთდროულად ერთ აქტიურ VPN-ს უშვებს.
ერთი აქტიურის ეს წესი ხალხს ტესტირებაში აბრკოლებს. თქვენ აწევთ გვირაბს, სანამ კორპორატიული კლიენტი დაკავშირებულია, და ასკვნით, რომ თქვენი კოდი გატეხილია, მაშინ როცა პლატფორმამ უბრალოდ სხვა კლიენტიდან გადაინაცვლა. დამტკიცებები მოგვიანებით შეიძლება გაუქმდეს, და prepare()-მა შეიძლება დააბრუნოს null მოწყობილობებზე, სადაც თანხმობის აქტივობა აკლია, ამიტომ establish()-მა მაინც უნდა დაამუშაოს მარცხი.
ფარული API-ები და პარამეტრების განზრახვები
ძველი პასუხები მიუთითებენ com.android.internal კლასებზე და AIDL ინტერფეისებზე, რომლებსაც ჩაშენებული კლიენტი იყენებს. ისინი SDK-ში არ არიან, გამოშვებებს შორის შეტყობინების გარეშე იცვლებიან, და აპების მაღაზიები ამ წვდომას რისკად მიიჩნევენ. მოწყობილობის root-ვა მათ სტაბილურობასაც არ მისცემს, რადგან root და ფარულ API-ზე წვდომა დაუკავშირებელი პრობლემებია.
მხარდაჭერილი ნავიგაციის დამხმარე არის Settings.ACTION_VPN_SETTINGS, რომლის მნიშვნელობაა android.net.vpn.SETTINGS. გადაწყვიტეთ ის გაშვებამდე, რადგან ზოგი OEM-ის ნაგებობა ამ აქტივობას არ აწვდის, და გადადით წერილობით ნაბიჯებზე, როცა გადაწყვეტა ვერ მოხერხდება. ის მომხმარებელს ეკრანზე მიჰყავს და არაფერს აკონფიგურირებს.
მოწყობილობის მფლობელისა და MDM-ის გზები არის ის გამონაკლისი, რასაც ხალხი ჩვეულებრივ გულისხმობს. DevicePolicyManager-ს შეუძლია მუდამ ჩართული VPN პაკეტის დანიშვნა, და მართული კონფიგურაციები შეიძლება წინასწარ ჩატვირთავდნენ პარამეტრებს კლიენტისთვის, რომელიც მათ მხარს უჭერს, მაგრამ ეს მაინც არ არის საჯარო SDK, რომელიც PPTP პროფილს წერს.
გაიარეთ გადაწყვეტილება მომხმარებლის მხრიდან
თუ თქვენმა პროდუქტმა ტრაფიკი უნდა გადაიტანოს, დაგეგმეთ VpnService და ნამდვილი პროტოკოლური დასტა, და დრო გამოყავით თანხმობის ნაკადსა და ერთი VPN-ის წესს. თუ მიზანია არსებულ კორპორატიულ პროფილთან დაკავშირება, თქვენი საქმე ხელმძღვანელობაა: ღრმა ბმული პარამეტრების ეკრანზე, ველების დოკუმენტირება, და მიეცით პლატფორმის კლიენტს გვირაბის გაკეთება. თუ აპს მხოლოდ კერძო საბოლოო წერტილამდე მისვლა სჭირდება, მას საკუთარი გვირაბი საერთოდ არ სჭირდება.
ჩაწერეთ ეს გადაწყვეტილება კოდის დაწერამდე, რადგან სამ გზას პირველი სპრინტის შემდეგ თითქმის არაფერი აქვს საერთო.
ბოლო შემოწმება დაწყებამდე: მოთხოვნა ამბობს, რომ ჩვენი აპი უკავშირდება თუ მოწყობილობა უკავშირდება? პირველი VpnService-ია, მეორე კი პროფილი, რომელსაც ვერ შექმნით. ამ წინადადების სწორად ჩამოყალიბება ნებისმიერ რეფაქტორინგზე იაფია.