/dev/net/tun गायब है जबकि tun लोड है: डिवाइस नोड ठीक करें
लोड किया गया tun मॉड्यूल यह सिद्ध नहीं करता कि डिवाइस नोड मौजूद है। ड्राइवर को नोड से अलग करें, क्रम में इसे फिर से बनाएँ और किसी इंटरफ़ेस से सत्यापित करें।
OpenVPN errno 2 शिकायत के साथ रुक जाता है, जो /dev/net/tun के बारे में है, जबकि lsmod tun मॉड्यूल को सहजता से सूचीबद्ध करता है। दोनों तथ्य एक ही समय सत्य हैं। मॉड्यूल एक ड्राइवर देता है, और क्लाइंट जो पथ खोलता है वह एक डिवाइस नोड है जिसे किसी और को बनाना होता है। दोनों को एक ही वस्तु मानना ही वह कारण है कि मॉड्यूल को फिर से लोड करने का स्पष्ट उपाय कुछ भी नहीं बदलता।
दो वस्तुएँ, दो अलग मालिक
कर्नेल मॉड्यूल और डिवाइस नोड स्वतंत्र जीवन-चक्र वाली स्वतंत्र वस्तुएँ हैं। मॉड्यूल लोड करने से एक ड्राइवर पंजीकृत होता है, और devtmpfs वाले सिस्टम में कर्नेल संबंधित नोड बनाने के लिए कहता है। devtmpfs के बिना किसी सिस्टम में कुछ भी कुछ नहीं बनाता, और ड्राइवर वहाँ बिना किसी ऐसे पथ के बैठा रहता है जो उसकी ओर इशारा करे। मॉड्यूल एक ही पल में लोडेड, स्वस्थ और फ़ाइल सिस्टम के ज़रिए पूरी तरह अगम्य हो सकता है।
इसीलिए त्रुटि पाठ और मॉड्यूल सूची एक-दूसरे का खंडन नहीं करते। क्लाइंट एक पथ खोलता है, पथ मौजूद नहीं है, और कर्नेल tun ड्राइवर से पूछे जाने से पहले ही ENOENT लौटा देता है। मॉड्यूल फिर से लोड करना गुम पथ को ठीक नहीं कर सकता, और पथ बनाना गुम ड्राइवर को ठीक नहीं कर सकता।
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 वाले कंटेनर रनटाइम को नोड अपने ही नेमस्पेस में इंजेक्ट करना पड़ता है, और उसके डिवाइस 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
उस परीक्षण को उसी संदर्भ में चलाएँ जो वास्तव में विफल होता है, क्योंकि कोई सेवा इकाई, कंटेनर या निर्धारित कार्य आपके लॉगिन शेल से अलग क्षमता-समुच्चय रख सकता है। गलत संदर्भ में पास होने वाला परीक्षण विफल होने वाले के बारे में कुछ सिद्ध नहीं करता।
जब डिवाइस समस्या न हो
यदि इंटरफ़ेस परीक्षण सफल हो और क्लाइंट फिर भी विफल हो, तो बची हुई समस्या प्रोफ़ाइल, सेवा संदर्भ या मार्ग है, और डिवाइस ठीक है। यही वह क्षण है जब डिवाइस नोड संपादित करना बंद करना चाहिए, क्योंकि आगे के बदलाव काम कर रहे सिस्टम से दूरी ही बढ़ाते हैं।
हर बार नया गढ़ने के बजाय वही पाँच जाँच चलाएँ: क्या मॉड्यूल किसी प्रतिद्वंद्वी मॉड्यूल के बिना लोड है, क्या पथ सही major और minor वाला कैरेक्टर डिवाइस है, क्या माउंट विकल्प साफ़ हैं, क्या प्रक्रिया संदर्भ में क्षमता है, और क्या विफलता के टाइमस्टैम्प पर कोई नीति अस्वीकृति है। पाँचों को पार कर जाने वाली खराबी डिवाइस की समस्या नहीं है, संदेश चाहे जो कहे।