წაიკითხეთ Android DNS სწორად: ქსელის მიხედვით, არა resolv.conf-ში
თქვენი Android აპი წყვეტს ქსელის მიხედვით resolver-ის მეშვეობით, არა ახლახან წაკითხული resolv.conf-ის მეშვეობით. ჯერ შეამოწმეთ LinkProperties, socket-ის მიბმები და Private DNS.
მოწყობილობაზე shell-ს იღებთ, კითხულობთ /etc/resolv.conf-ს ან ძველ net.dns1 მნიშვნელობას ამოთხრით და ერთ მისამართს იღებთ. თქვენს წინ არსებული აპი სულ სხვა რამის მეშვეობით წყვეტს. მიმდინარე Android გამოშვებაში resolver ქსელის მიხედვითაა: სისტემა ყოველი Network-ისთვის პოლიტიკას ინახავს და მას მოთხოვნის გამომგზავნ socket-ზე იყენებს. ფაილი და ძველი თვისება ნაშთებია და არც ერთი მათგანი არ აღწერს გზას, რომელიც თქვენმა მოთხოვნამ სინამდვილეში გაიარა.
ეს უფსკრული split-tunnel და Private DNS დანერგვისას ჩნდება, სადაც ერთ ტელეფონზე ორ აპს კანონიერად შეუძლია განსხვავებული პასუხები დაინახოს. ეს სახელმძღვანელო არასწორი ან არარსებული ამოხსნიდან იწყება და უკან მიდის კონფიგურაციისკენ, რომელსაც ის ეკუთვნის.
Resolver ქსელს ეკუთვნის, არა მოწყობილობას
სახელების ამოხსნა Android 9-სა და უფრო ახალში გადის სისტემურ resolver-ზე, რომელიც ეყრდნობა Network-ს, რომელზეც socket არის მიბმული. ყოველ ქსელს აქვს საკუთარი LinkProperties, და ეს თვისებები შეიცავს DNS სერვერების სიას, ძიების დომენებს და Private DNS მდგომარეობას მხოლოდ იმ ქსელისთვის. ამ მოდელში არაფერი შეესაბამება ერთ მთელ მოწყობილობაზე გავრცელებულ სიას, რომელსაც ფაილიდან წაიკითხავდით.
VPN გაყოფას აშკარას ხდის. როცა გვირაბი ამოდის, VPN აპი აწვდის DNS სერვერებს, რომლებიც VPN-ის საკუთარ ქსელზე არიან რეგისტრირებული, ამიტომ მის გავლით მარშრუტირებული აპები ამ სერვერებზე წყვეტენ, ხოლო გამორიცხულ აპებს ქვეშ არსებული ქსელის გამოყენება გრძელდებათ. ერთი მოწყობილობა, ორი პასუხის გზა, წინააღმდეგობის გარეშე.
წაიკითხეთ სურათი დაზარალებული აპის შიგნიდან
ჰკითხეთ თავად აპს. მეთოდი, რომელსაც აქვს Context და ჩვეულებრივი android.permission.ACCESS_NETWORK_STATE ნებართვა, სისტემურ თვისებებზე შეხების გარეშე წაიკითხავს სურათს:
val cm = getSystemService(ConnectivityManager::class.java) ?: return
val network = cm.activeNetwork
val links = network?.let { cm.getLinkProperties(it) }
val dnsServers = links?.dnsServers
val privateDnsActive = links?.isPrivateDnsActive
val privateDnsName = links?.privateDnsServerNameactiveNetwork თქვენი პროცესის ნაგულისხმევი ქსელია, არა მოწყობილობის ერთადერთი ქსელი, და შეიძლება იყოს null, როცა გამომძახებელს გამოსადეგი ნაგულისხმევი არ აქვს. დაბლოკილი ნაგულისხმევი VPN ჩვეულებრივი მიზეზია. isPrivateDnsActive გეუბნებათ, გადის თუ არა ამ ქსელზე მოთხოვნები TLS-ით სახელდებულ resolver-ზე, რაც ცვლის იმას, თუ რას გაჩვენებთ მარტივი UDP 53 შემოწმება. API-ის ზედაპირი დოკუმენტირებულია LinkProperties-ის ქვეშ, და მასში ყოველი მნიშვნელობა კონფიგურაციის სურათია, არა იმის მტკიცებულება, რომ კონკრეტულმა მოთხოვნამ კონკრეტულ სერვერს მიაღწია.
როცა ნაგულისხმევი ქსელი არ არის ის, რომელიც სამუშაოს ასრულებს
სურათი მხოლოდ ნაგულისხმევ ქსელზე პასუხობს. აპს შეუძლია თავისი პროცესი ან ერთი socket სხვა ქსელზე მიაბას, და მაშინ ამოხსნა ამ არჩევანს მიჰყვება, სანამ თქვენი დიაგნოსტიკა კვლავ ნაგულისხმევს აცხადებს. ბრაუზერი, რომელიც საკუთარ DNS-over-HTTPS resolver-ს მოაქვს, საერთოდ არ კითხულობს სისტემურ სიას, ამიტომ მისი პასუხები მოწყობილობის დანარჩენზე არაფერს ამბობს. სამუშაო პროფილის აპი ცალკე მომხმარებლის ქვეშ მუშაობს საკუთარი პოლიტიკით. სანამ სერვერებს დაადანაშაულებთ, შეამოწმეთ მიბმა.
VPN ინტეგრაცია მეორე ნახევარია. dhcp-option DNS ხაზის მიღება OpenVPN პროფილში და ამ მისამართის Android VPN ქსელზე რეგისტრაცია ორი ცალკე ნაბიჯია, და სერვერამდე დაკარგული მარშრუტი ისე ჩუმად ვარდება, როგორც არასწორი მისამართი. განვითარების მანქანიდან adb shell dumpsys connectivity იგივე კავშირის თვისებებს ბეჭდავს ქსელის მიხედვით, როცა build ამას იძლევა, რაც კოდის დაწერის გარეშე ადასტურებს სიას.
შეადარეთ კონფიგურაცია ერთ ამოხსნას, რომლის გაკეთებაც ნებადართულია
აირჩიეთ სახელი, რომელიც კერძო სახელთა სივრცეში უნდა ამოიხსნას, და ერთი საჯარო სახელი, და ორივე შედეგი სურათის გვერდით ჩაწერეთ: ქსელი, კონფიგურირებული სერვერები, Private DNS მდგომარეობა და შეცდომის ზუსტი ტექსტი. სახელდებულ სერვერზე პირდაპირი მოთხოვნა ამტკიცებს, რომ ეს სერვერი გპასუხებთ; ის არ ამტკიცებს, რომ ჩვეულებრივმა აპის ამოხსნამ ის აირჩია. ქეშში არსებული პასუხი ახალი ტესტი არ არის, ამიტომ ქეში გაასუფთავეთ ან გამოიყენეთ სახელი, რომელიც დღეს არავის უკითხავს.
თუ resolver მხოლოდ გარკვეული წვდომის ქსელის კლიენტებს ემსახურება, ის, რასაც VPN-იდან გასვლის შემდეგ ხედავს, შედეგს გადაწყვეტს, და ეს პოლიტიკის საკითხია მისთვის, ვინც მას მართავს, არა იმის მტკიცებულება, რომ ოპერატორები UDP 53-ს ბლოკავენ. სადაც Private DNS აქტიურია, არაკვალიფიციური ჰოსტის სახელი დიზაინით შეიძლება უარყოფილ იქნას, სანამ იგივე სერვერი საჯარო სახელებს ჩვეულებრივ პასუხობს. თვისებების წაკითხვა გეუბნებათ, რომელი რეჟიმი მოქმედებს, ამიტომ პაკეტების ფილტრებზე გამოცნობას წყვეტთ.
შეაკეთეთ ფენა, რომელსაც ეკუთვნის შეუსაბამობა
იმუშავეთ ზევით ნაცვლად გლობალური მდგომარეობის რედაქტირებისა. თუ აპი არასწორ ქსელზეა მიბმული, შეაკეთეთ მიბმა. თუ პროფილი არასწორ DNS ოფციას აწვდის, შეაკეთეთ პროფილი. თუ Private DNS მკაცრია ქსელზე, რომლის resolver-ს თქვენი კერძო ზონის მომსახურება არ შეუძლია, ეს მოწყობილობის მართვის გადაწყვეტილებაა და არა ფუნქციის ყველგან გამორთვის მიზეზი.
საჯარო resolver-ების DHCP კაუჭში ან სისტემურ თვისებაში ჩაჭრა არის შესწორება, რომელიც გამუდმებით იწვევს ინციდენტებს: კერძო სახელები წყვეტს ამოხსნას, ცვლილება VPN სესიას გადაურჩება, და მოწყობილობაზე შემდეგი ადამიანი უპატრონო მოძველებულ მისამართს პოულობს. შეინახეთ ცვლილება VPN-ის, აპის ან მართვის ფენის შიგნით, რომელსაც შეუსაბამობა ეკუთვნის, და შემდეგ ხელახლა წაიკითხეთ სურათი, რომ დაადასტუროთ, რომ სერვერების სია ნამდვილად შეიცვალა.
ბოლოს გსურთ ერთი აპის მოთხოვნა, მიბმული ერთ ქსელზე, resolver-ების სიაზე და Private DNS მდგომარეობაზე. როცა ამ ჯაჭვის ჩვენება შეგიძლიათ, ფაილში ნაცნობი მისამართი აღარაფრის მტკიცებულება აღარ არის.