/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-ով, արդյոք տեղադրման ընտրանքները մաքուր են, արդյոք պրոցեսի համատեքստը կրում է կարողությունը, և արդյոք ձախողման ժամանակադրոշմում կա քաղաքականության մերժում: Խափանումը, որը վերապրում է բոլոր հինգին, սարքի խնդիր չէ, ինչ էլ որ նշի հաղորդագրությունը: