როცა ემულატორი ვერ აღწევს build-სერვერს, რომელსაც ჰოსტის ბრაუზერი ჩვეულებრივ ხსნის, სასარგებლო კითხვა არ არის, მუშაობს თუ არა VPN. კითხვაა, ორი მექანიზმიდან რომელი აკლია guest-ს. ვირტუალური მოწყობილობა საკუთარ ქსელურ stack-ს ატარებს ემულატორის NAT-ის უკან, და მისი resolver-ების სია boot-ის დროს აღებული ასლია, ამიტომ მოგვიანებით აწეული გვირაბი ცვლის ჰოსტის გზას, მაგრამ არ ცვლის იმას, რასაც guest კითხულობს. ამ ორი შრის გაგება ხსნის ამ პრობლემის თითქმის ყველა ვარიანტს.

Guest არის ცალკე stack ფიქსირებული NAT-ის უკან

QEMU-ს user-mode ქსელი guest-ს ათავსებს 10.0.2.15-ზე, gateway-ით 10.0.2.2-ზე, და DNS სერვისს 10.0.2.3-დან 10.0.2.6-მდე. Guest-ის გამავალი ტრაფიკი ჰოსტის kernel-ის მიერ არ forward-დება; ის გარდაიქმნება ჰოსტის მხარეს socket-ებად, ერთი თითო guest-კავშირზე, და ეს socket-ები გამოდიან ჰოსტის მისამართების სივრციდან. ამიტომ guest-კავშირი მემკვიდრეობით იღებს ჰოსტის routing-ის გადაწყვეტილებას შექმნის მომენტში, და ამიტომ guest-ის route ცხრილში არ არის ჩანაწერი, რომელიც თქვენს გვირაბს მიუთითებს.

იგივე მექანიზმი guest-ს სასარგებლო გასასვლელს აძლევს. 10.0.2.2 ჰოსტის loopback ინტერფეისის alias-ია, ამიტომ ლეპტოპის 127.0.0.1-ზე მოსმენადი სერვისი guest-იდან ხელმისაწვდომია ამ მისამართზე. ყველაფერი, რასაც client მხოლოდ loopback-ზე აქვეყნებს, ამ გზით მისაწვდომია, და ეს არის ქვემოთ აღწერილი proxy კონფიგურაციის საფუძველი.

რისი გაკეთებაც guest-ს არ შეუძლია, არის ჰოსტის ქსელის დაკვირვება ისე, თითქოს ის მისი namespace-ია. არ არის bridge, არ არის საერთო route ცხრილი და არ არის მემკვიდრეობით მიღებული resolver; არის მხოლოდ NAT სერვისი, რომელიც მის packet-ებს იღებს, და ის snapshot, რომელიც launcher-მა ვირტუალური მოწყობილობის გაშვებისას აიღო.

DNS არის snapshot და არა ცოცხალი სურათი

გაშვებისას ემულატორი კითხულობს ჰოსტის resolver-ების სიას და guest-ს აძლევს ოთხამდე სერვერს, გამოქვეყნებულს 10.0.2.3-დან 10.0.2.6 მისამართებზე. თუ იმ მომენტში გვირაბი ჩამოშვებული იყო, snapshot შეიცავს იმ public resolver-ს, რომელსაც ლეპტოპი იყენებდა, და guest სიცოცხლის ბოლომდე აგრძელებს მის კითხვას. Public სახელები წყდება, შიდა სახელები ვარდება, და ყველა სიმპტომი VPN-ზე მიუთითებს, მაშინ როცა რეალურად მოძველებული მნიშვნელობა არის resolver-ების სია, რომელიც გვირაბის აწევამდე რამდენიმე წუთით ადრე იქნა აღებული.

ამიტომ რიგითობის გასწორება ფოლკლორი არ არის. ჯერ შეაერთეთ გვირაბი, შემდეგ გადატვირთეთ ემულატორი, და ამჯობინეთ cold boot snapshot-ის აღდგენას, რადგან quick-boot იმიჯი შეიძლება დაბრუნდეს ადრე შენახული resolver-ისა და route-ის მდგომარეობით. თუ გსურთ ნახოთ, რას იყენებს guest ახლა, ჰკითხეთ მოწყობილობას და არა ჰოსტს:

adb shell dumpsys connectivity | grep -i -A2 dns
adb shell ping -c 1 build.internal.example

ემულატორი ასევე იღებს გამოკვეთილ resolver-ს გაშვებისას, რაც სასარგებლოა, როცა ზუსტად იცით, რომელი სერვერი უნდა გამოიყენოს guest-მა, და საშიშია, როცა ეს სერვერი public-ია:

emulator -avd Pixel_API_34 -dns-server 203.0.113.53

Public resolver-ს შიდა ზონის ასლი არ აქვს, ამიტომ ერთის მიმაგრება რიგითობის პრობლემას მუდმივ მარცხად აქცევს. თუ profile private DNS-ს უბიძგებს, მიეცით გვირაბს მისი მოწოდების საშუალება და გააკეთეთ guest-ის cold boot მისამართის ხისტად ჩაწერის ნაცვლად.

Routing ჰოსტს მიჰყვება კავშირის შექმნის მომენტში

ვინაიდან guest-კავშირები ჰოსტის socket-ებად იქცევა, routing-ის გადაწყვეტილება მიიღება socket-ის შექმნისას. გვირაბის აწევა მოთხოვნამდე ნიშნავს, რომ მოთხოვნა გამოდის გვირაბით, profile-ის route-ების შესაბამისად. Split-tunnel profile, რომელიც მხოლოდ შერჩეულ prefix-ებს გადააქვს, სიამოვნებით დატოვებს თქვენს private subnet-ს გარეთ, ამიტომ ჰოსტის ხელმისაწვდომობა guest-ის შესახებ ჰიპოთეზაა და არა შედეგი. არსებული guest-კავშირები ინარჩუნებენ იმ გზას, რომლითაც შეიქმნნენ, ამიტომ ხელახლა დაკავშირებული client ყოველთვის არ ასწორებს ემულატორში ჩარჩენილ ჩამოტვირთვას.

გადამოწმება ჰოსტის ინტერფეისზეა და არა guest-ის სტატისტიკაში:

sudo tcpdump -ni tun0 'host 203.0.113.10'

თუ guest-ის მოთხოვნა გვირაბის ინტერფეისზე ჩნდება, routing მუშაობს და პრობლემა მის ზემოთაა. თუ ის ფიზიკურ ინტერფეისზე ჩნდება, profile ამ prefix-ს არ ფარავს, და guest-ის მხარეს ვერანაირი ხელახალი კონფიგურაცია ამას არ შეცვლის.

როცა client მხოლოდ loopback proxy-ს გვთავაზობს

ზოგი კომერციული client საერთოდ არ ქმნის system tunnel-ს. ისინი 127.0.0.1-ზე HTTP ან SOCKS listener-ს აქვეყნებენ და ელოდებიან, რომ აპლიკაციები მას გამოიყენებენ. Guest ვერ ხედავს ამ socket-ს უშუალოდ, მაგრამ ემულატორს შეიძლება ვუთხრათ მისი გამოყენება, ან extended controls-ით (Settings, შემდეგ Proxy, manual mode, host 127.0.0.1 და client-ის დაბეჭდილი port), ან გაშვებისას:

emulator -avd Pixel_API_34 -http-proxy http://127.0.0.1:8080

დააკოპირეთ port client-ის ფანჯრიდან; გამოცნობილი port ჩუმად ვარდება და გატეხილ გვირაბს ჰგავს. გაითვალისწინეთ, რას ფარავს ეს: HTTP proxy-ის პარამეტრს პატივს სცემენ proxy-ს გაცნობიერებული აპლიკაციები, ხოლო ნედლი socket-ები სრულიად უგულებელყოფენ მას. თუ დატვირთვა native binary-ია, რომელიც საკუთარ კავშირებს ხსნის, proxy-ის გზა გვირაბის ეკვივალენტი არ არის და შედარება ცალკე უნდა გაკეთდეს.

დაამტკიცეთ შედეგი guest-ის შიგნიდან

გამოყავით resolution routing-ისგან ერთ სესიაში ორი ტესტით. სახელი, რომელიც ვარდება, მაშინ როცა ციფრული მისამართი პასუხობს, DNS snapshot-ის პრობლემაა, და გამოსავალი რიგითობა ან გამოკვეთილი resolver-ია. ორივეს ვარდნა routing-ზე ან policy-ზე მიუთითებს, და შემდეგი შემოწმებაა, მუშაობს თუ არა აპლიკაცია work profile-ში, საკუთარი ქსელური შეზღუდვებით.

და ბოლოს, იცოდეთ, რომელ guest-ზე ამოწმებთ. ძალიან ძველი ემულატორის იმიჯები გამოდიოდა tun-ის მხარდაჭერის გარეშე, რომელიც guest-ის მხარეს VPN client-ს სჭირდება, ამიტომ იქ ვერც ერთი profile ვერ იმუშავებდა; მიმდინარე იმიჯებში ის შედის. Client, რომელიც მიმდინარე იმიჯზე ვარდება, client-ის ან profile-ის პრობლემაა, და ჰოსტის გვირაბის ხელახლა აწყობა შედეგს არ შეცვლის.

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