/dev/net/tun ontbreek terwyl tun gelaai is: herstel die toestelknooppunt
'n Gelaaide tun-module bewys nie dat die toestelknooppunt bestaan nie. Skei die drywer van die knooppunt, bou dit in volgorde op en verifieer dit met 'n koppelvlak.
OpenVPN stop met 'n errno 2-foutmelding oor /dev/net/tun terwyl lsmod die tun-module geredelik lys. Albei feite is gelyktydig waar. Die module lewer 'n drywer, en die pad wat die kliënt oopmaak, is 'n toestelknooppunt wat iets anders moet skep. Om dit as een objek te behandel, is die rede waarom die ooglopende herstel van die module se herlaai heeltemal niks verander nie.
Twee objekte, twee verskillende eienaars
'n Kernmodule en 'n toestelknooppunt is onafhanklike objekte met onafhanklike lewensiklusse. Die laai van die module registreer 'n drywer, en op 'n stelsel met devtmpfs vra die kern dat die ooreenstemmende knooppunt geskep word. Op 'n stelsel sonder devtmpfs skep niks enigiets nie, en die drywer sit daar sonder enige pad wat na hom wys. Die module kan gelaai, gesond en terselfdertyd heeltemal onbereikbaar deur die lêerstelsel wees.
Dit is waarom die foutteks en die modulelys nie mekaar weerspreek nie. Die kliënt maak 'n pad oop, die pad bestaan nie, en die kern gee ENOENT terug voordat die tun-drywer ooit geraadpleeg word. Die herlaai van die module kan nie 'n ontbrekende pad herstel nie, en die skep van die pad kan nie 'n ontbrekende drywer herstel nie.
lsmod | grep -w tun
stat -c "%F %t:%T" /dev/net/tun
grep " /dev " /proc/mounts
devtmpfs teenoor 'n eksplisiete mknod
Twee meganismes skep gewoonlik daardie knooppunt, en as jy weet watter een verantwoordelik behoort te wees, weet jy wat om te herstel. devtmpfs laat die kern toestelknooppunte in 'n gekoppelde instansie skep, en udev pas eienaarskap en toestemmings bo-op hulle toe. 'n Eksplisiete mknod is die handmatige pad vir beelde en naamruimtes waar nie een van dié by die selflaai loop nie.
Vergelyk uitkomste eerder as bedoelings. As devtmpfs by /dev gekoppel is en die knooppunt steeds ontbreek, is die drywer nie die een wat jy aanneem nie, of iets het die knooppunt ná selflaai verwyder. As /dev 'n gewone gids in 'n uitgepakte rootfs is, bestaan daar geen outomatiese meganisme nie en moet wie die beeld bou, die knooppunt skep.
stat -c "%F major=%t minor=%T" /dev/net/tun
# expect: character special file major=a minor=c8
Waar nie een van die meganismes loop nie, moet die knooppunt met die hand gemaak word, en die volgorde maak saak. Skep eers die ouergids, want mknod kan nie een uitdink nie, dan die karaktertoestel, dan 'n modus wat dit alleen vir root skryfbaar laat. Herlaai die module voordat jy die knooppunt skep, en verwyder eers 'n bestaande pad nadat ls getoon het dat dit 'n gids eerder as 'n toestel is.
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
Die tipe wat deur stat gerapporteer word, is die vinnigste onderskeier, en 'n gids by daardie pad is die algemeenste verrassing in minimale beelde. 'n Goedbedoelde mkdir in 'n Dockerfile laat presies dit oor, en geen hoeveelheid modulelaai vervang 'n gids met 'n karaktertoestel nie. Major 10 met minor 200 is die geregistreerde paar vir tun, in heksadesimaal uitgedruk as a en c8.
Vier spore, vier oorsake
Vier oorsake verklaar byna elke geval, en elkeen laat 'n ander spoor in die logs. Begin by die selflaai-omgewing. Skyflose beelde, ingebedde borde en initramfs-fases koppel dikwels nie devtmpfs of 'n udev-beheerde /devnie, so geen proses skryf ooit die knooppunt nie. Lees dan die koppelopsies op wat /devook al huisves, want nodev laat die pad toe om te bestaan terwyl dit weier om dit oop te maak, en 'n bind-koppeling wat van 'n geharde gasheer geneem is, dra die vlag sonder om dit aan te kondig. 'n Lees-alleen-koppeling misluk vroeër en harder: mknod gee daar EROFS terug, terwyl EPERM beteken die proses het nie die vermoë nie eerder as dat die lêerstelsel homself beskerm. Laastens, 'n houerruntime met sy eie /dev tmpfs benodig die knooppunt wat in sy eie naamruimte ingespan word, en sy toestel-cgroup moet die major- en minor-paar toelaat.
Kontroleer die beleidslaag voordat jy weer toestemmings verander. SELinux en AppArmor kan 'n oopmaak weier wat elke lêerattribuut toelaat, en daardie weiering verskyn in die auditlog eerder as in die kliëntuitset. 'n Toestemmingsverandering wat nooit in 'n weiering verskyn nie, is tyd wat heeltemal aan die verkeerde laag bestee word.
sudo journalctl -k -n 20 --no-pager
sudo ausearch -m AVC -ts recent | tail -5
Bewys dit met 'n koppelvlak, nie met 'n lys nie
'n Suksesvolle lys bewys dat 'n pad bestaan en niks meer nie. Maak 'n gesonde tun-knooppunt oop vir lees, en die oproep kom terug met 'n fout, want die toestel het geen leessemantiek nie en is nie 'n gewone lêer nie. Daardie fout is die suksessein hier, en om dit te herken keer dat jy dit as 'n fout agtervolg.
head -c 1 /dev/net/tun
head: error reading '/dev/net/tun': File descriptor in bad state
Die beslissende toets skep 'n koppelvlak, want dit oefen die drywer, die knooppunt en jou voorregte in 'n enkele stap uit. As die byvoeging slaag en die skakel verskyn, werk al drie. Wanneer dit misluk, skei die errno die oorsake: ENOENT beteken daar is geen bruikbare knooppunt nie, EPERM wys na vermoë, koppelvlae of beleid, en EBUSY beteken 'n ander proses besit reeds die koppelvlak.
sudo ip tuntap add dev tun7 mode tun
ip -brief link show tun7
sudo ip tuntap del dev tun7 mode tun
Voer daardie toets uit in die konteks wat werklik misluk, want 'n dienseenheid, 'n houer of 'n geskeduleerde taak kan 'n ander vermoëstelling dra as jou aanmelddop. 'n Toets wat in die verkeerde konteks slaag, bewys niks oor die mislukkende een nie.
Wanneer die toestel nie die probleem is nie
As die koppelvlaktoets slaag en die kliënt steeds misluk, is die oorblywende probleem die profiel, die dienskonteks of die roete, en die toestel is reg. Dit is die oomblik om op te hou om toestelknooppunte te redigeer, want verdere veranderinge voeg net afstand van 'n werkende stelsel by.
Voer elke keer dieselfde vyf kontroles uit eerder as om 'n nuwe een uit te dink: is die module gelaai sonder 'n mededingende module, is die pad 'n karaktertoestel met die regte major en minor, is die koppelopsies skoon, dra die proseskonteks die vermoë, en is daar 'n beleidsweiering op die tydstempel van die mislukking. 'n Fout wat al vyf oorleef, is nie 'n toestelprobleem nie, wat die boodskap ook al noem.