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

სამი ობიექტი სახელად resolv.conf

resolved-ის მქონე ჰოსტზე /etc/resolv.conf ჩვეულებრივ სიმბოლური ბმულია /run/systemd/resolve/stub-resolv.conf-ზე. ეს სამიზნე შეიცავს ლოკალური stub-მსმენელის მისამართს, 127.0.0.53-ს, და resolved-ის მიერ გამოთვლილ ძიების დომენებს. ეს მდგომარეობის ხედვაა და არა თავად მდგომარეობა.

მდგომარეობა resolved-ის თითოეული კავშირის კონფიგურაციაში ცხოვრობს, ამიტომ resolvectl status შეიძლება ფაილს არ დაეთანხმოს და მაინც მართალი იყოს. თითოეული კავშირი თავის სერვერებსა და თავის მარშრუტიზაციის დომენებს ატარებს, ხოლო stub ამ მონაცემებს მოთხოვნის მოსვლისას ეკითხება. systemd-resolved-ის სახელმძღვანელო აღწერს გენერირებულ ფაილებსა და თითოეული კავშირის მოდელს; ხედვისა და მდგომარეობის გამიჯვნა სწორედ ის ნაწილია, რომლის დამახსოვრებაც ღირს. სიმბოლური ბმულის სამიზნის შეცვლა ცვლის იმას, რასაც ტრადიციული კლიენტები კითხულობენ და არა იმას, რაც ამომხსნელმა იცის.

მესამე ობიექტი, /run/systemd/resolve/resolv.conf, ყველა კავშირს ერთ სერვერთა სიაში აბრტყელებს. ამ ფაილზე მიმართული პროგრამა მოთხოვნებს პირდაპირ ჩამოთვლილ სერვერებზე აგზავნის და stub-ს გვერდს უვლის, ამიტომ თითოეული კავშირის პოლიტიკა მას აღარ ეხება. ამის გამო ერთსა და იმავე მანქანაზე ორმა პროგრამამ შეიძლება ერთსა და იმავე სახელს სხვადასხვანაირად უპასუხოს და არც ერთი არ იყოს გატეხილი.

თვალი ადევნეთ ერთ ძიებას NSS-ის გავლით

glibc კითხულობს /etc/nsswitch.conf-ს, რომ გადაწყვიტოს ვინ პასუხობს სახელს. hosts-ის სტრიქონი, რომელიც შეიცავს resolve-ს, კითხვას nss-resolve-ისკენ მიმართავს, რომელიც D-Bus-ის მეშვეობით resolved-ს ეკითხება და თითოეული კავშირის პასუხს იღებს. მხოლოდ files dns-ის მქონე სტრიქონი მოთხოვნას იმ მისამართზე აგზავნის, რომელიც /etc/resolv.conf-ს აქვს.

ეს ერთი სტრიქონი ხსნის ბრაუზერსა და dig-ს შორის უმეტეს უთანხმოებას. dig resolv.conf-ს პირდაპირ კითხულობს და NSS-ს არასდროს ეხება, ამიტომ ამოწმებს stub-ს ან ზედა სერვერს და არა გზას, რომელსაც აპლიკაცია იყენებს. getent hosts internal.example NSS-ის გავლით მიდის და მისი პასუხის dig-ის პასუხთან შედარება პირველი სასარგებლო გაზომვაა.

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

შეამოწმეთ, ვის ეკუთვნის ფაილი და საით მიუთითებს

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

stat -c '%N' /etc/resolv.conf
resolvectl status --no-pager
grep '^hosts' /etc/nsswitch.conf
ls -l /run/systemd/resolve/

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

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

შეაკეთეთ ბმულის მფლობელთან

VPN-კავშირმა თავისი სერვერები და დომენები საკუთარ კავშირზე უნდა დაარეგისტრიროს, შემდეგ კი გათიშვისას უკან წაიღოს. NetworkManager-ის resolved-ინტეგრაცია და კლიენტის საკუთარი დამხმარე ორივე ასე მუშაობს; სკრიპტი, რომელიც მხოლოდ resolv.conf-ს გადაწერს, ასე არ იქცევა.

უკვე არსებულ კავშირზე მექანიზმს გაშვების დროის პარამეტრები აჩვენებს. resolvectl dns tun0 10.40.0.53 სერვერს მიაბამს, ხოლო resolvectl domain tun0 '~corp.example' მარშრუტიზაციის დომენს მიაბამს. ტილდა ტვირთის მზიდი სიმბოლოა: ის ამ სუფიქსის მოთხოვნებს ამ კავშირზე ზღუდავს და დანარჩენს ხელუხლებლად ტოვებს, ხოლო იგივე მნიშვნელობა ტილდის გარეშე ძიების დომენად იქცევა და გაყოფა ორთქლდება. ეს მისამართები ლაბორატორიული მაგალითებია და არა მუდმივი კონფიგურაცია. დაადასტურეთ resolvectl query host.corp.example-ით და წაიკითხეთ, რომელმა კავშირმა უპასუხა.

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

როგორ გამოიყურება მუშა მდგომარეობა

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

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

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