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

სამი გადაწყვეტილება ფიქსირებული რიგით

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

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

StageSelectorWhat it cannot decide
Policy ruleuid range, mark, incoming interfaceWhich route exists inside the table
Route lookupDestination prefix, longest matchWhether the packet is allowed out
Netfilter hookChain position, match conditionsWhich table was selected

ნიშნები შეფუთული ველია, და არა თქვენი საკუთარი იარლიყი

Android რამდენიმე ფაქტს ერთსა და იმავე ნიშნის მნიშვნელობაში აფუთავს: რომელი ქსელი აირჩიეს, აპლიკაციამ ცალსახად აირჩია თუ არა ქსელი, დაცულია თუ არა socket VPN-ისგან და ნებართვებთან დაკავშირებული ბიტები. AOSP-ის fwmark სათაური განსაზღვრავს ამ განლაგებას მიმდინარე ხისთვის, და განლაგება პლატფორმის შიდა დეტალია, რომელიც გამოშვებებს შორის იცვლება.

ამიტომ Android-ზე საშიშია მთლიანი ნიშნის მნიშვნელობის ჩაწერა iptables -j MARK --set-mark -ით. ის იარლიყს არ ამატებს; ის ცვლის ქსელის იმ არჩევანს, რომელიც სისტემამ უკვე გააკეთა. შემდეგ პაკეტი სხვა წესებს ემთხვევა, რაც შეიძლება გამოიყურებოდეს ისე, თითქოს VPN-მა მუშაობა დაიწყო, ან თითქოს უკავშირო აპლიკაციამ კავშირი დაკარგა — იმის მიხედვით, რომელი ბიტები გადაიწერა.

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

ip rule show
ip route show table all | head -40
ip route get 10.20.4.11

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

ვის ეკუთვნის წესები და ცხრილები

Android-ის ქსელური სერვისი, netd, ქმნის წესებს და თითო ქსელის ცხრილებს. AOSP RouteController არის ადგილი, სადაც ეს წესები აწყობენ VPN-ებისთვის, ფიზიკური ქსელებისთვის და uid დიაპაზონებისთვის, და მისი სასიცოცხლო ციკლი ქსელურ მოვლენებზეა მიბმული და არა კონფიგურაციის ფაილზე.

ორი შედეგი გამომდინარეობს. პირველი, ერთ მოწყობილობაზე ნაპოვნი პრიორიტეტები და ცხრილის ნომრები build-ის შიდა დეტალებია და არა ინტერფეისი: ერთნაირად მოჩვენებული ნომრები Android-ის სხვა ვერსიაზე შეიძლება სრულიად სხვა რამეს ნიშნავდეს. მეორე, მდგომარეობა ხელახლა აგება ქსელების შეცვლისას, ამიტომ დღეს root shell-იდან ჩასმული წესი შეიძლება გაქრეს შემდეგი Wi-Fi გადასვლის შემდეგ.

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

კაუჭების რიგის კითხვებს უნივერსალური პასუხი არ აქვს

კითხვას, მუშაობს თუ არა iptables VPN-ის მარშრუტიზაციამდე, პასუხი არ აქვს პაკეტის გზის დასახელების გარეშე. ლოკალურად შექმნილი პაკეტი გადის output კაუჭზე, სადაც ნიშნის ცვლილება იწვევს ხელახალი მარშრუტიზაციის შემოწმებას — მეორე ძებნა და არა პირველის უკუქცევითი რედაქტირება. tether-ით დაკავშირებული კლიენტიდან მოსული პაკეტი გადის prerouting გზაზე და ნაცვლად ამისა გადაეცემა, და ჯაჭვები, რომლებიც მას ხედავენ, სხვაა.

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

ეს ის ეტაპიცაა, სადაც პოლიტიკის მარშრუტიზაციის შეცდომა ძნელად შესამჩნევი ხდება. არსებულ, მაგრამ დანიშნულების გარეშე ცხრილში მარშრუტიზაცია იძლევა ქსელი მიუწვდომელია, რაც firewall-ის ჩაგდებას ჰგავს, ხოლო firewall-ის ჩაგდება იძლევა დროის ამოწურვას, რაც მარშრუტიზაციის შავ ხვრელს ჰგავს.

დიაგნოზი სისტემის შიგნით, ან თავი დაანებეთ

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

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

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

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