/dev/net/tun trūkst, lai gan tun ir ielādēts: salabojiet ierīces mezglu
Ielādēts tun modulis nepierāda, ka ierīces mezgls pastāv. Atdaliet draiveri no mezgla, pārbūvējiet to secībā un pārbaudiet ar saskarni.
OpenVPN apstājas ar errno 2 sūdzību par /dev/net/tun kamēr lsmod mierīgi uzskaita tun moduli. Abi fakti ir patiesi vienlaikus. Modulis nodrošina draiveri, un ceļš, ko klients atver, ir ierīces mezgls, kas kaut kam citam ir jāizveido. Abu uztveršana kā vienu objektu ir iemesls, kāpēc acīmredzamais labojums — moduļa pārlādēšana — nemaina pilnīgi neko.
Divi objekti, divi dažādi īpašnieki
Kodola modulis un ierīces mezgls ir neatkarīgi objekti ar neatkarīgiem dzīves cikliem. Moduļa ielāde reģistrē draiveri, un sistēmā ar devtmpfs kodols pieprasa atbilstošā mezgla izveidi. Sistēmā bez devtmpfs nekas neko neizveido, un draiveris sēž tur bez neviena ceļa, kas uz to norādītu. Modulis vienlaikus var būt ielādēts, vesels un pilnīgi nesasniedzams caur failu sistēmu.
Tāpēc kļūdas teksts un moduļu saraksts nav pretrunā viens ar otru. Klients atver ceļu, ceļa nav, un kodols atgriež ENOENT vēl pirms tun draiverim vispār jautā. Moduļa pārlāde nevar salabot trūkstošu ceļu, un ceļa izveide nevar salabot trūkstošu draiveri.
lsmod | grep -w tun
stat -c "%F %t:%T" /dev/net/tun
grep " /dev " /proc/mounts
devtmpfs pret skaidru mknod
Parasti šo mezglu izveido divi mehānismi, un zināšana, kuram vajadzētu būt atbildīgam, pasaka, ko labot. devtmpfs ļauj kodolam izveidot ierīces mezglus pievienotā instancē, un udev uzliek tiem īpašumtiesības un atļaujas. Skaidrs mknod ir manuālais ceļš attēliem un nosaukumtelpām, kurās neviens no tiem nedarbojas palaišanas laikā.
Salīdziniet rezultātus, nevis nodomus. Ja devtmpfs ir pievienots /dev un mezgla joprojām nav, draiveris nav tas, ko jūs pieņemat, vai kaut kas mezglu noņēma pēc palaišanas. Ja /dev ir parasta direktorija izpakotā rootfs, automātiska mehānisma nav, un tas, kas būvē attēlu, izveido mezglu.
stat -c "%F major=%t minor=%T" /dev/net/tun
# expect: character special file major=a minor=c8
Tur, kur neviens mehānisms nedarbojas, mezgls jāizveido ar roku, un secība ir svarīga. Vispirms izveidojiet vecākdirektoriju, jo mknod to nevar izdomāt, tad rakstzīmju ierīci, tad režīmu, kas to atstāj rakstāmu tikai root. Pārlādējiet moduli pirms mezgla izveides, un dzēsiet esošo ceļu tikai pēc tam, kad ls ir parādījis, ka tas ir direktorija, nevis ierīce.
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
Ātrākais atšķirējs ir tips, ko ziņo stat un direktorija šajā ceļā ir visbiežākā pārsteigums minimālos attēlos. Labi domāts mkdir Dockerfile atstāj tieši to, un neviens moduļu ielādes daudzums neaizstāj direktoriju ar rakstzīmju ierīci. Major 10 ar minor 200 ir reģistrētais tun pāris, izteikts heksadecimāli kā a un c8.
Četras pēdas, četri cēloņi
Četri cēloņi izskaidro gandrīz katru gadījumu, un katrs atstāj atšķirīgu pēdu žurnālos. Sāciet ar palaišanas vidi. Bezdiska attēli, iegultās plates un initramfs posmi bieži nepievieno ne devtmpfs, ne udev pārvaldītu /dev, tāpēc neviens process nekad neieraksta mezglu. Pēc tam izlasiet pievienošanas opcijas tam, kas mitina /dev, jo nodev ļauj ceļam pastāvēt, bet atsakās to atvērt, un bind pievienošana, kas ņemta no rūdīta resursdatora, nes šo karodziņu, sevi neizsludinot. Tikai lasīšanas pievienošana neizdodas agrāk un skaļāk: mknod tur atgriež EROFS, bet EPERM nozīmē, ka procesam trūkst spējas, nevis ka failu sistēma aizsargā sevi. Visbeidzot, konteineru runtime ar savu /dev tmpfs prasa, lai mezgls tiktu ievadīts tā paša nosaukumtelpā, un tā ierīču cgroup ir jāatļauj major un minor pāris.
Pārbaudiet politikas slāni, pirms vēlreiz maināt atļaujas. SELinux un AppArmor var atteikt atvēršanu, ko atļauj katrs faila atribūts, un šis atteikums parādās audita žurnālā, nevis klienta izvadē. Atļauju maiņa, kas nekad neparādās atteikumā, ir laiks, kas pavadīts pilnīgi nepareizā slānī.
sudo journalctl -k -n 20 --no-pager
sudo ausearch -m AVC -ts recent | tail -5
Pierādiet to ar saskarni, nevis sarakstu
Veiksmīgs saraksts pierāda, ka ceļš pastāv un neko vairāk. Atveriet veselu tun mezglu lasīšanai, un izsaukums atgriežas ar kļūdu, jo ierīcei nav lasīšanas semantikas un tā nav parasts fails. Šī kļūda šeit ir veiksmes signāls, un tās atpazīšana neļauj jums to vajāt kā bojājumu.
head -c 1 /dev/net/tun
head: error reading '/dev/net/tun': File descriptor in bad state
Izšķirošais tests izveido saskarni, jo tas vienā solī pārbauda draiveri, mezglu un jūsu privilēģijas. Ja pievienošana izdodas un saite parādās, visi trīs darbojas. Kad tas neizdodas, errno atdala cēloņus: ENOENT nozīmē, ka nav izmantojama mezgla, EPERM norāda uz spēju, pievienošanas karodziņiem vai politiku, un EBUSY nozīmē, ka saskarni jau pārvalda cits process.
sudo ip tuntap add dev tun7 mode tun
ip -brief link show tun7
sudo ip tuntap del dev tun7 mode tun
Palaidiet šo testu tajā kontekstā, kas tiešām neizdodas, jo servisa vienība, konteiners vai ieplānots darbs var nest citu spēju kopu nekā jūsu pieteikšanās shell. Tests, kas iztur nepareizā kontekstā, neko nepierāda par to, kas neizdodas.
Kad ierīce nav problēma
Ja saskarnes tests izdodas un klients joprojām neizdodas, atlikušā problēma ir profils, servisa konteksts vai maršruts, un ierīce ir kārtībā. Tas ir brīdis, kad jāpārtrauc ierīces mezglu rediģēšana, jo turpmākas izmaiņas tikai palielina attālumu no strādājošas sistēmas.
Katru reizi palaidiet tos pašus piecus pārbaudījumus, nevis izdomājiet jaunu: vai modulis ir ielādēts bez konkurējoša moduļa, vai ceļš ir rakstzīmju ierīce ar pareizo major un minor, vai pievienošanas opcijas ir tīras, vai procesa konteksts nes spēju, un vai bojājuma laika zīmogā ir politikas atteikums. Bojājums, kas pārdzīvo visus piecus, nav ierīces problēma, ko vien vēsta ziņojums.