root არ არის ის, რაც Android VPN აპლიკაციას საშუალებას აძლევს გადაიტანოს ტრაფიკი, დაბლოკოს გაჟონვები ან გადაიტანოს გადატვირთვა. ადამიანები ამ ყველაფერს აჯამებენ როგორც „აპლიკაციას აქვს VPN ნებართვა“, რაც მალავს სამ ცალკეულ მექანიზმს: მომხმარებლის მიერ მიცემულ თანხმობას, სისტემის მიერ შექმნილ პაკეტურ ინტერფეისს და პლატფორმის ბლოკირების პოლიტიკას, რომლის განსაზღვრა აპლიკაციის საქმე არ არის. Android VPN დიზაინის განხილვა ნიშნავს იკითხოთ, ამ სამიდან რომელს ეყრდნობა სინამდვილეში რომელიმე მტკიცება, რადგან თითოეულს განსხვავებული მფლობელი და განსხვავებული მარცხის რეჟიმი აქვს.

თანხმობა მოდის სისტემური აქტივობის მეშვეობით

VpnService.prepare() არაფერს აძლევს. ის intent-ს უბრუნებს სისტემის თანხმობის აქტივობას, როცა თანხმობა აკლია, და აპლიკაცია ხსნის ამ დიალოგს, რომ მომხმარებელმა დაამტკიცოს სერვისი. საკუთარი პროცესის გაშვება, მანიფესტში ნებართვის დამატება ან მორგებული „VPN-ის ჩართვის“ ეკრანის ჩვენება არ ქმნის ნებართვას.

ნებართვა შეზღუდულია მოცულობითაც. ის ეკუთვნის პაკეტს მომხმარებლის პროფილში, ამიტომ პირადი ასლი და სამუშაო ასლი ცალკე გადაწყვეტილებებია, და მოწყობილობის მფლობელს შეუძლია მართული პროფილი სხვაგვარად მოამზადოს, ვიდრე პირადი. თუ დიალოგი არასოდეს გამოჩნდა და prepare() აბრუნებს null-ს, თანხმობა უკვე არსებობს ამ პაკეტისთვის ამ პროფილში; ეს არ არის აპლიკაციის სანდოობის მტკიცებულება, მხოლოდ ის, რომ ნებართვა ადგილზეა.

ინტერფეისი არის მოთხოვნა, რომელსაც სისტემა ასრულებს

თანხმობის შემდეგ აპლიკაცია VpnService.Builder-ის საშუალებით აღწერს, რა სურს: მისამართები, მარშრუტები, DNS სერვერები, MTU და, სადაც მხარდაჭერილია, ჩასართავი ან გამოსარიცხი აპლიკაციები. establish() სისტემას სთხოვს შექმნას გვირაბის ინტერფეისი და გაუშვას შესაბამისი ტრაფიკი მასში. მარშრუტიზაციის გადაწყვეტილება სისტემას ეკუთვნის; აპლიკაცია იღებს ფაილის აღწერილობას და შემდეგ პაკეტებთან რაღაც სასარგებლო უნდა გააკეთოს.

What you observeWho actually owns it
VPN consent dialogThe system, triggered by prepare()
Routes, DNS and app listsThe app requests them; the system applies them
One active VPN per profileThe platform; a new service replaces the old one
Always-on and block-without-VPNDevice policy enforced by the platform

ეს ცხრილი არქიტექტურაა ერთ ადგილას. აპლიკაცია პაკეტების დამუშავებაში მონაწილეობს; ინტერფეისი, მარშრუტიზაციის ცხრილი ან გაშვებადი სერვისების რაოდენობა მას არ ეკუთვნის.

გვირაბის socket-მა უნდა გაფართხალოს საკუთარი გვირაბიდან

კავშირი, რომელიც შიფრავს ტრაფიკს, თავად socket-ია. თუ ის ისევ იმ ინტერფეისში გადამისამართდება, რომელიც აპლიკაციამ ახლახან შექმნა, გვირაბი დამოკიდებულია გვირაბზე და ჩერდება. VpnService.protect() ამ socket-ს აკავშირებს ქვედა ქსელთან, რომ თავი აარიდოს აღებას, და ამიტომ სწორი კლიენტი პირველ ხელის ჩამორთმევამდე იცავს თავის გარე socket-ს.

adb shell dumpsys connectivity | grep -i -A5 vpn
adb shell settings get global always_on_vpn_app
adb shell settings get global always_on_vpn_lockdown

ეს ბრძანებები აჩვენებს დაყენებულ VPN ქსელს, ყოველთვის ჩართულ პაკეტს და კითხულობს, დაყენებულია თუ არა ჩაკეტვა. ესენი მხოლოდ წაკითხვადი დაკვირვებებია: თუ მნიშვნელობები არ ემთხვევა იმას, რასაც დიზაინი ამტკიცებს, მტკიცება აპლიკაციის ინტერფეისს ეხება და არა სისტემის მდგომარეობას.

ბლოკირება შეიძლება პლატფორმას ეკუთვნოდეს

Android ადოკუმენტებს პოლიტიკას, რომელიც ბლოკავს კავშირებს, რომლებიც არ იყენებენ VPN-ს. ეს აღსრულება პლატფორმის კონტრაქტია, და არა აპლიკაცია, რომელიც ციკლში იმეორებს კავშირის ცდებს. გადამრთველი მოწყობილობის VPN პარამეტრებშია სახელწოდებით „VPN-ის გარეშე კავშირების ბლოკირება“, და მართულ მოწყობილობაზე მფლობელს შეუძლია ჩართოს ის მთელი პროფილისთვის. განსხვავებას მნიშვნელობა აქვს მარკეტინგული მტკიცების შეფასებისას: კლიენტს შეუძლია აჩვენოს ბოქლომის ხატულა და აგრესიულად ხელახლა დაუკავშირდეს, სანამ პირდაპირი ტრაფიკი ჯერ კიდევ შესაძლებელია, ან დაფარული აპლიკაციები დარჩეს ოფლაინში, რადგან სისტემა აღასრულებს ჩაკეტვას.

ბოქლომის ხატულას აპლიკაცია ხატავს, ამიტომ ის მხოლოდ იმას ამტკიცებს, რომ აპლიკაცია თვლის, რომ დაკავშირებულია. სხვა აპლიკაცია დაკარგავს თუ არა ქსელურ წვდომას, პლატფორმა წყვეტს, ამიტომ სასარგებლო შემოწმებაა ნახოთ ის აპლიკაცია, რომელიც ვერ ახერხებს მუშაობას, სანამ გვირაბი ჩართულია.

„ყოველთვის ჩართული“ ეტიკეტი აპლიკაციების მაღაზიიდან არც ის ცვლის ამ კონტრაქტს. ყოველთვის ჩართვა და ჩაკეტვა მოწყობილობის პარამეტრებია, ხშირად მფლობელის მიერ გამოყენებული, და მათ ქცევას გამორიცხული აპლიკაციებისთვის პლატფორმა განსაზღვრავს. წაიკითხეთ პარამეტრი და არა ნიშანი.

ოთხი კითხვა დიზაინის განხილვისთვის

პირველი, ვინ მისცა თანხმობა: რომელი პაკეტი, რომელი პროფილი და ეს იყო მომხმარებელი თუ მართული მოწყობილობის პოლიტიკა? მეორე, რა მოითხოვა აპლიკაციამ: რომელი მარშრუტები, რომელი მისამართების ოჯახები, რომელი ჩართული ან გამორიცხული აპლიკაცია? მესამე, რა ხდება, როცა გვირაბი მიუწვდომელია: სისტემა ბლოკავს თუ ტრაფიკი უბრუნდება ქვედა ქსელს? მეოთხე, რას აკეთებს აპლიკაცია მიღებულ პაკეტებთან?

მეოთხე კითხვა არის ის, რომელზეც ნებართვების მოდელი ვერ გიპასუხებთ. თანხმობა და TUN ინტერფეისი ამტკიცებს, რომ აპლიკაცია ტრაფიკს იღებს, და არა იმას, რომ ის შიფრავს, ავთენტიფიცირებს მხარეს ან სუფთად აღდგება. ეს იმპლემენტაციის თვისებებია, და სწორედ იქ ატარებს დროს პატიოსანი განხილვა.

ზედმეტი root მოთხოვნა ლეგიტიმური არ ხდება იმით, რომ შედეგს kill switch-ს უწოდებ, და თანხმობის დიალოგი უსაფრთხოების აუდიტი არ არის. შეინახეთ სამი ნებართვა ცალ-ცალკე და ყოველი მტკიცება შემოწმებადი გახდება.

დაკავშირებული სტატიები