/dev/net/tun აკლია, თუმცა tun ჩატვირთულია: შეაკეთეთ მოწყობილობის კვანძი
ჩატვირთული tun მოდული არ ამტკიცებს, რომ მოწყობილობის კვანძი არსებობს. გამოყავით დრაივერი კვანძისგან, აღადგინეთ ის რიგითობით და შეამოწმეთ ინტერფეისით.
OpenVPN ჩერდება errno 2 ჩივილით /dev/net/tun -ის შესახებ, მაშინ როცა lsmod მშვიდად ჩამოთვლის tun მოდულს. ორივე ფაქტი ერთდროულად ჭეშმარიტია. მოდული აძლევს დრაივერს, ხოლო გზა, რომელსაც კლიენტი ხსნის, არის მოწყობილობის კვანძი, რომელიც სხვა რაღაცამ უნდა შექმნას. მათი ერთ ობიექტად მიჩნევა სწორედ იმის მიზეზია, რომ მოდულის გადატვირთვის აშკარა შეკეთება საერთოდ არაფერს ცვლის.
ორი ობიექტი, ორი განსხვავებული მფლობელი
ბირთვის მოდული და მოწყობილობის კვანძი დამოუკიდებელი ობიექტები არიან დამოუკიდებელი სასიცოცხლო ციკლებით. მოდულის ჩატვირთვა არეგისტრირებს დრაივერს, და devtmpfs-იან სისტემაში ბირთვი ითხოვს შესაბამისი კვანძის შექმნას. devtmpfs-ის გარეშე სისტემაში არაფერი არაფერს ქმნის, და დრაივერი იქ ზის მისკენ მიმავალი არცერთი გზის გარეშე. მოდული შეიძლება იყოს ჩატვირთული, ჯანმრთელი და ფაილური სისტემით სრულიად მიუწვდომელი იმავე მომენტში.
ამიტომ შეცდომის ტექსტი და მოდულების სია ერთმანეთს არ ეწინააღმდეგება. კლიენტი ხსნის გზას, გზა არ არსებობს, და ბირთვი აბრუნებს ENOENT-ს სანამ tun დრაივერს საერთოდ ჰკითხავენ. მოდულის გადატვირთვა ვერ შეაკეთებს დაკარგულ გზას, და გზის შექმნა ვერ შეაკეთებს დაკარგულ დრაივერს.
lsmod | grep -w tun
stat -c "%F %t:%T" /dev/net/tun
grep " /dev " /proc/mounts
devtmpfs აშკარა mknod-ის წინააღმდეგ
ჩვეულებრივ ამ კვანძს ორი მექანიზმი ქმნის, და იმის ცოდნა, რომელი უნდა იყოს პასუხისმგებელი, გეუბნებათ რა უნდა შეაკეთოთ. devtmpfs აძლევს ბირთვს საშუალებას შექმნას მოწყობილობის კვანძები ჩამონტაჟებულ ეგზემპლარში, ხოლო udev მათზე ადებს მესაკუთრეობას და ნებართვებს. აშკარა mknod არის ხელით გზა იმ იმიჯებისა და სახელთა სივრცეებისთვის, სადაც არცერთი მათგანი არ მუშაობს ჩატვირთვისას.
შეადარეთ შედეგები და არა განზრახვები. თუ devtmpfs ჩამონტაჟებულია /dev -ზე და კვანძი მაინც აკლია, დრაივერი არ არის ის, რასაც ვარაუდობთ, ან რაღაცამ კვანძი ჩატვირთვის შემდეგ წაშალა. თუ /dev ჩვეულებრივი დირექტორია გახსნილ rootfs-ში, ავტომატური მექანიზმი არ არსებობს და ვინც იმიჯს აწყობს, მან უნდა შექმნას კვანძი.
stat -c "%F major=%t minor=%T" /dev/net/tun
# expect: character special file major=a minor=c8
სადაც არცერთი მექანიზმი არ მუშაობს, კვანძი ხელით უნდა გაკეთდეს, და რიგითობა მნიშვნელოვანია. ჯერ შექმენით მშობელი დირექტორია, რადგან mknod ვერ მოიგონებს მას, შემდეგ სიმბოლური მოწყობილობა, შემდეგ რეჟიმი, რომელიც მხოლოდ root-ისთვის დატოვებს ჩასაწერად. გადატვირთეთ მოდული კვანძის შექმნამდე, და წაშალეთ არსებული გზა მხოლოდ მას შემდეგ, რაც ls აჩვენებს, რომ ეს დირექტორიაა და არა მოწყობილობა.
sudo modprobe tun
sudo mkdir -p /dev/net
sudo mknod /dev/net/tun c 10 200
sudo chmod 600 /dev/net/tun
ls -l /dev/net/tun
ყველაზე სწრაფი განმასხვავებელი stat -ის მიერ მოხსენებული ტიპია, და ამ გზაზე დირექტორიის არსებობა ყველაზე გავრცელებული მოულოდნელობაა მინიმალურ იმიჯებში. კეთილგანწყობილი mkdir Dockerfile-ში ზუსტად ამას ტოვებს, და მოდულების ჩატვირთვის არცერთი რაოდენობა არ ცვლის დირექტორიას სიმბოლური მოწყობილობით. Major 10 minor 200-თან ერთად tun-ის რეგისტრირებული წყვილია, გამოსახული თექვსმეტობითში როგორც a და c8.
ოთხი კვალი, ოთხი მიზეზი
ოთხი მიზეზი ხსნის თითქმის ყველა შემთხვევას, და თითოეული განსხვავებულ კვალს ტოვებს ჟურნალებში. დაიწყეთ ჩატვირთვის გარემოთი. დისკის გარეშე იმიჯები, ჩაშენებული დაფები და initramfs-ის ეტაპები ხშირად არ ამონტაჟებენ არც devtmpfs-ს და არც udev-ის მიერ მართულ /dev, ამიტომ არცერთი პროცესი არასდროს წერს კვანძს. შემდეგ წაიკითხეთ ჩამონტაჟების პარამეტრები იმაზე, რაც მასპინძლობს /dev-ს, რადგან nodev გზის არსებობას უშვებს, მაგრამ უარს ამბობს მის გახსნაზე, და გამაგრებული ჰოსტიდან აღებული bind ჩამონტაჟება ამ დროშას თავის გამოცხადების გარეშე ატარებს. მხოლოდ-კითხვის ჩამონტაჟება უფრო ადრე და უფრო ხმამაღლა ფეილდება: mknod იქ EROFS-ს აბრუნებს, ხოლო EPERM ნიშნავს, რომ პროცესს უკლია უნარი და არა ის, რომ ფაილური სისტემა თავს იცავს. ბოლოს, საკუთარი /dev tmpfs-ის მქონე კონტეინერის runtime-ს სჭირდება კვანძის შეყვანა მისსავე სახელთა სივრცეში, და მისმა მოწყობილობის cgroup-მა უნდა დაუშვას major და minor წყვილი.
სანამ კვლავ შეცვლით ნებართვებს, შეამოწმეთ პოლიტიკის ფენა. SELinux და AppArmor შეიძლება უარყონ გახსნა, რომელსაც ფაილის ყველა ატრიბუტი უშვებს, და ეს უარყოფა აუდიტის ჟურნალში ჩნდება და არა კლიენტის გამოსავალში. ნებართვის ცვლილება, რომელიც არასდროს ჩნდება უარყოფაში, სრულიად არასწორ ფენაზე დახარჯული დროა.
sudo journalctl -k -n 20 --no-pager
sudo ausearch -m AVC -ts recent | tail -5
დაამტკიცეთ ინტერფეისით, არა სიით
წარმატებული სია ამტკიცებს, რომ გზა არსებობს და მეტს არაფერს. გახსენით ჯანმრთელი tun კვანძი წასაკითხად და გამოძახება შეცდომით ბრუნდება, რადგან მოწყობილობას არ აქვს კითხვის სემანტიკა და არ არის ჩვეულებრივი ფაილი. სწორედ ეს შეცდომაა აქ წარმატების სიგნალი, და მისი ამოცნობა გიშლით ხელს მას გაუმართაობად დაედევნოთ.
head -c 1 /dev/net/tun
head: error reading '/dev/net/tun': File descriptor in bad state
გადამწყვეტი ტესტი ინტერფეისს ქმნის, რადგან ერთ ნაბიჯში ამოწმებს დრაივერს, კვანძს და თქვენს პრივილეგიებს. თუ დამატება წარმატებულია და ბმული ჩნდება, სამივე მუშაობს. როცა ფეილდება, errno ჰყოფს მიზეზებს: ENOENT ნიშნავს, რომ გამოსადეგი კვანძი არ არის, EPERM მიუთითებს უნარზე, ჩამონტაჟების დროშებზე ან პოლიტიკაზე, ხოლო EBUSY ნიშნავს, რომ ინტერფეისს უკვე სხვა პროცესი ფლობს.
sudo ip tuntap add dev tun7 mode tun
ip -brief link show tun7
sudo ip tuntap del dev tun7 mode tun
გაუშვით ეს ტესტი იმ კონტექსტში, რომელიც ნამდვილად ფეილდება, რადგან სერვისის ერთეულს, კონტეინერს ან დაგეგმილ სამუშაოს შეიძლება ჰქონდეს თქვენი შესვლის shell-ისგან განსხვავებული უნარების ნაკრები. ტესტი, რომელიც არასწორ კონტექსტში გადის, არაფერს ამტკიცებს ფეილდებადის შესახებ.
როცა მოწყობილობა პრობლემა არ არის
თუ ინტერფეისის ტესტი წარმატებულია და კლიენტი მაინც ფეილდება, დარჩენილი პრობლემა პროფილია, სერვისის კონტექსტი ან მარშრუტი, და მოწყობილობა რიგზეა. ეს არის მომენტი, როცა უნდა შეწყვიტოთ მოწყობილობის კვანძების რედაქტირება, რადგან შემდგომი ცვლილებები მხოლოდ აშორებს მომუშავე სისტემას.
ყოველ ჯერზე გაუშვით იგივე ხუთი შემოწმება და არ მოიგონოთ ახალი: ჩატვირთულია თუ არა მოდული მეტოქე მოდულის გარეშე, არის თუ არა გზა სიმბოლური მოწყობილობა სწორი major-ით და minor-ით, სუფთაა თუ არა ჩამონტაჟების პარამეტრები, ატარებს თუ არა პროცესის კონტექსტი უნარს, და არის თუ არა პოლიტიკის უარყოფა ფეილის დროის ნიშნულზე. გაუმართაობა, რომელიც ხუთივეს გადაურჩება, მოწყობილობის პრობლემა არ არის, რაც არ უნდა ახსენოს შეტყობინებამ.