VPN chroot-ში Android-ზე: რატომ მუშაობს გვირაბი და რატომ უგულებელყოფენ მას აპები
chroot ცვლის ბილიკების გარჩევას, არა ბირთვს, ქსელის სახელთა სივრცეს ან Android-ის VPN რეგისტრაციას. აქედან ორი შედეგი გამომდინარეობს და ორივე ადამიანებს აკვირვებს.
თქვენ ტელეფონზე chroot-ის ქვეშ Linux დისტრიბუციას ამუშავებთ, შიგნით VPN კლიენტს აყენებთ და shell აცხადებს, რომ გვირაბი დასრულებულია. შემდეგ ბრაუზერზე გადადიხართ და ტრაფიკი მობილური მონაცემებით გადის, თითქოს არაფერი მომხდარა. ან პირიქით: ტელეფონის ყველა აპი კავშირს კარგავს, რადგან კლიენტმა ნაგულისხმევი მარშრუტი დაამატა იმ სახელთა სივრცეში, რომელსაც Android რეალურად იყენებს. ეს ორი სიმპტომი ერთი და იმავე ნაკლული ნაწილიდან მოდის და არც ერთი არ არის VPN კლიენტის შეცდომა.
Shell ამბობს დაკავშირებულია, აპები არ ეთანხმებიან
პირველი შედეგი ჩვეულებრივია. chroot-იდან გახსნილ მომხმარებლის სივრცის გვირაბს შეუძლია ხელის ჩამორთმევა დაასრულოს, სტატისტიკა დაბეჭდოს და გადაიტანოს ის ტრაფიკი, რომელსაც იგივე shell აწარმოებს, მაშინ როცა Android-ის აპები კვლავ ტელეფონის ნაგულისხმევ ქსელს იყენებენ. არაფერი არ კვეთს მათ, რადგან არაფერმა არ უთხრა Android-ს, რომ VPN არსებობს.
მეორე შედეგი საშიშია. თუ chroot Android-ის ქსელის სახელთა სივრცეს იზიარებს, რაც ნაგულისხმევია, საკმარისი უფლებების მქონე პროცესს შეუძლია დაამატოს მარშრუტები და TUN ინტერფეისი, რომლებიც მთელ ტელეფონზე მოქმედებს. მაშინ გვირაბი ყველა აპისთვის მუშაობს, მათ შორის იმ აპებისთვის, რომელთა მარშრუტიზაციასაც არ აპირებდით, და ტელეფონის კავშირი ახლა დამოკიდებულია დემონზე, რომელსაც არ აქვს სიცოცხლის ციკლის მართვა, კავშირის მაჩვენებელი და მუდამ ჩართული პოლიტიკა.
ორიდან რომელი მიიღეთ, ერთი ბრძანებით დგინდება. შეადარეთ ip route chroot-ის შიგნით იმავე ბრძანებას გარეთ Android-ის shell-იდან. იდენტური გამოსავალი ნიშნავს, რომ chroot ჰოსტის სახელთა სივრცეშია: ნებისმიერი ქსელური ცვლილება მთელ ტელეფონს ეხება. განსხვავებული გამოსავალი ნიშნავს, რომ გამშვებმა მისთვის სახელთა სივრცე შექმნა და მისი გვირაბი აგებულებით უხილავია Android-ისთვის.
რა შეცვალა chroot-მა და რა არა
| Object | Effect of a chroot |
|---|---|
| Pathname resolution | Changed: lookups start at the new root |
| Kernel and drivers | Unchanged: the phone's kernel, its TUN driver, its limits |
| Network namespace | Unchanged unless the launcher creates one |
| Android VPN registration | Unchanged: no app consented, no VPN is selected |
chroot სისტემური გამოძახება ერთ რამეს აკეთებს: ცვლის დირექტორიას, რომელიც ბილიკების გარჩევისთვის გამოიყენება. man გვერდი ცალსახად ამბობს, რომ ეს უსაფრთხოების საზღვარი არ არის და არაფერს ამბობს ინტერფეისებზე, მარშრუტებზე ან VPN მდგომარეობაზე. ყველაფერი, რასაც ხალხი Linux კონტეინერისგან ელის — კერძო ქსელის სტეკი, გაფილტრული ფაილური სისტემა, რესურსების ლიმიტები — სხვა მექანიზმებიდან მოდის, რომლებიც გამშვებმა შეიძლება გამოიყენა ან არა.
ამიტომ მტკიცებები, რომ chroot VPN-ს იზოლირებს, ჩვეულებრივ არასწორ კითხვას პასუხობს. მნიშვნელოვანი კითხვაა, რომელ სახელთა სივრცეში მუშაობს პროცესი და რომელ SELinux დომენშია შეზღუდული, და ორივე იმის თვისებაა, როგორ გაეშვა ის, და არა სიტყვა chroot-ის.
TUN-ს სამი რამ სჭირდება და მოწყობილობის კვანძი მხოლოდ ერთია
ტრადიციულ მომხმარებლის სივრცის გვირაბს სჭირდება TUN მოწყობილობა, რომლის გახსნაც შეუძლია, ბირთვის მხარდაჭერა ამ მოწყობილობისთვის და ნებართვა ინტერფეისისა და მარშრუტების კონფიგურაციისთვის. ეს ცალკეული მოთხოვნებია და /dev-ის ქვეშ ბილიკის სახელის შექმნა თავისთავად არც ერთს არ აკმაყოფილებს:
ls -l /dev/net/tun
ip tuntap add dev tun0 mode tun
Android-ზე TUN მხარდაჭერა ჩვეულებრივ ბირთვშია ჩაშენებული, რადგან პლატფორმის საკუთარი VPN სერვისი იყენებს მას, მაგრამ ეს არ ნიშნავს, რომ თქვენს პროცესს მისი გამოყენება შეუძლია. ინტერფეისის კონფიგურაციას ქსელის ადმინისტრირების უნარი სჭირდება და SELinux წყვეტს, შეუძლია თუ არა პროცესს მოწყობილობის კვანძამდე მისვლა. უარი გაუგებარი მიზეზის გარეშე ნებართვის შეცდომას ჰგავს და პასუხი აუდიტის კვალშია:
dmesg | grep avc
logcat -d | grep "avc: denied"
root ამას არ წყვეტს. SELinux uid 0-ით მომუშავე პროცესებს ისევე ზღუდავს, როგორც სხვებს, ამიტომ root shell-იდან გაშვებულ chroot-ს მაინც შეიძლება უარი ეთქვას მოწყობილობაზე, რომელსაც ხედავს. ძველი ინსტალატორის გასამართად აღსრულების გამორთვა მთელი ტელეფონის გადაწყვეტილებაა გვირაბისგან ბევრად შორს შედეგებით და ეს მოძველებული ბინარის შესწორება არ არის.
რატომ უგულებელყოფენ Android-ის აპები თქვენს გვირაბს
Android-ის მხარდაჭერილი მოდელია VPN აპი, რომელიც პლატფორმის VPN სერვისში რეგისტრირდება, მომხმარებელს ერთხელ სთხოვს თანხმობას და საკუთარი გვირაბისთვის ფაილის აღმწერს იღებს. შემდეგ პლატფორმა ტრაფიკს ამ აღმწერში მიმართავს და ახორციელებს მომხმარებლის ან ადმინისტრატორის მიერ არჩეულ აპების არეალს, ამიტომ ერთი და იგივე მექანიზმი შეიძლება იყოს თითო აპზე, თითო პროფილზე და გაერთიანდეს მუდამ ჩართულ და VPN-ის გარეშე დაბლოკვის პარამეტრებთან. Android-ის VPN განვითარების სახელმძღვანელო აღწერს ამ ხელის ჩამორთმევას და მთავარია, რომ ეს რეგისტრაციაა და არა მარშრუტიზაციის ხრიკი.
chroot-ის შიგნით დემონი არასოდეს რეგისტრირდება. არ არის თანხმობის დიალოგი, გასაღების ხატულა სტატუსის ზოლში, აპების ჩართვის ან გამორიცხვის სია და მონაწილეობა მუდამ ჩართულ პოლიტიკაში. ამიტომ აპები კვლავ ნაგულისხმევ ქსელს იყენებენ და გვირაბი მხოლოდ იმას გადაიტანს, რასაც თავად shell აგზავნის.
საპირისპირო მიმართულებაც არ ეხმარება. მარშრუტების ჰოსტის სახელთა სივრცეში ჩაგდება ყველაფერს იჭერს, მათ შორის ტრაფიკს, რომელსაც პლატფორმა ლოკალურად დატოვებას ელოდა, და ამას აკეთებს აპების მიხედვით კონტროლისა და მომხმარებლისთვის ნახვის ან გაუქმების გარეშე. არ არსებობს შუალედური პარამეტრი, სადაც chroot-ის დემონი მხოლოდ ერთი აპისთვის წარმართავს ტრაფიკს.
ბინარული თავსებადობა ცალკე კედელია
მაშინაც კი, როცა ქსელური მხარე საინტერესოა, შესრულებად ფაილს თავისი მოთხოვნები აქვს: პროცესორის არქიტექტურა, დინამიკური ჩამტვირთავი, C ბიბლიოთეკა და ბირთვის ის შესაძლებლობები, რომლებსაც ელის. Android იყენებს bionic-ს და არა glibc-ს, და სამაგიდო დისტრიბუციისთვის აწყობილ ძველ ბინარს შეიძლება დასჭირდეს ბიბლიოთეკები, რომლებიც მოწყობილობაზე აღარ არის.
ბიბლიოთეკის ფაილის სახელის უფრო ახალ ვერსიაზე მიბმა ABI თავსებადობას არ ქმნის და ათი წლის პაკეტიდან დაარქივებული კრიპტოგრაფიული ბიბლიოთეკა მხარდაჭერილი კომპონენტი არ არის. თუ გეგმა ამაზეა დამოკიდებული, გეგმა ტელეფონზე ქსელური უფლებებით მხარდაუჭერელი კოდის გაშვებაა.
დაამტკიცეთ Android-ის კონტექსტში და შემდეგ გაასუფთავეთ
გამოსცადეთ ის, რაც ნამდვილად მნიშვნელოვანია თქვენთვის, იმ მხრიდან, რომელიც მნიშვნელოვანია: გახსენით კონკრეტული აპი, მიაღწიეთ კონკრეტულ კერძო დანიშნულებას, დაადასტურეთ რომელი გადამწყვეტი უპასუხა, შემდეგ გათიშეთ გვირაბი და დაადასტურეთ დოკუმენტირებული ქცევა. chroot-ის შიგნით ტერმინალიდან მიღებული შედეგი მხოლოდ ამ ტერმინალის შესრულების კონტექსტის მტკიცებულებაა და მეტი არაფერი.
თუ ექსპერიმენტის დროს ჰოსტის მარშრუტები შეცვალეთ, დააბრუნეთ და ჩაწერეთ, რა შეცვალეთ. შემდეგ შეამოწმეთ, აქვს თუ არა ტელეფონს მუდამ ჩართული VPN, რადგან წესის დატოვებული ძველი ექსპერიმენტი თვეების შემდეგ პლატფორმის ხარვეზად შეიძლება მოჩანდეს.
დისტანციური წვდომის რეალური საჭიროებისთვის გამოიყენეთ სერვისის მხარდაჭერილი კლიენტი ან დამტკიცებული კარიბჭის დიზაინი. კითხვა, რომლის დასმაც ღირს, არ არის, შეიძლება თუ არა root ინსტალატორის ამუშავება, არამედ ის, გადაიტანს თუ არა მხარდაჭერილი იმპლემენტაცია თქვენთვის საჭირო აპებს თქვენ მიერ განზრახული საზღვრის გადაღმა, მოწყობილობაზე უპატრონო პრივილეგირებული ცვლილებების დატოვების გარეშე.