OpenVPN stoppet mei in errno 2-klacht oer /dev/net/tun wylst lsmod de tun-module noflik opneamt. Beide feiten binne tagelyk wier. De module leveret in stjoerder, en it paad dat de klient iepenet is in apparaatknooppunt dat eat oars meitsje moat. Beide as ien objekt behannelje is de reden wêrom't de foar de hân lizzende reparaasje fan it op 'e nij laden fan 'e module hielendal neat feroaret.

Twa objekten, twa ferskillende eigners

In kernelmodule en in apparaatknooppunt binne ûnôfhinklike objekten mei ûnôfhinklike libbenssyklusen. It laden fan 'e module registrearret in stjoerder, en op in systeem mei devtmpfs freget de kernel om it byhearrende knooppunt oan te meitsjen. Op in systeem sûnder devtmpfs makket neat eat, en de stjoerder sit dêr sûnder in paad dat nei him wiist. De module kin tagelyk laden, sûn en folslein ûnberikber fia it bestânsysteem wêze.

Dêrom tsjinsprekke de flatertekst en de modulelist elkoar net. De klient iepenet in paad, it paad bestiet net, en de kernel jout ENOENT werom foar't de tun-stjoerder ea frege wurdt. It op 'e nij laden fan 'e module kin in ûntbrekkend paad net reparearje, en it meitsjen fan it paad kin in ûntbrekkende stjoerder net reparearje.

lsmod | grep -w tun
stat -c "%F %t:%T" /dev/net/tun
grep " /dev " /proc/mounts

devtmpfs tsjin in eksplisite mknod

Normaal meitsje twa meganismen dat knooppunt, en witte hokker ferantwurdlik wêze moat fertelt jo wat te reparearjen. devtmpfs lit de kernel apparaatknooppunten meitsje yn in oanhongen eksimplaar, en udev leit eigendom en rjochten derop. In eksplisite mknod is it hânmjittige paad foar bylden en nammeruimten dêr't gjin fan beide by it opstarten rint.

Fergelykje útkomsten ynstee fan bedoelingen. As devtmpfs oan /dev hongen is en it knooppunt noch altyd ûntbrekt, is de stjoerder net dejinge dy't jo oannimme, of eat hat it knooppunt nei it opstarten fuorthelle. As /dev in gewoane map is yn in útpakt rootfs, bestiet der gjin automatysk meganisme en wa't it byld bout moat it knooppunt meitsje.

stat -c "%F major=%t minor=%T" /dev/net/tun
# expect: character special file major=a minor=c8

Dêr't gjin fan beide meganismen rint, moat it knooppunt mei de hân makke wurde, en de folchoarder is wichtich. Meitsje earst de âlderlike map, want mknod kin der gjin betinke, dan it tekentekenapparaat, dan in modus dy't it allinnich foar root beskriuwber lit. Laad de module op 'e nij foar't jo it knooppunt meitsje, en ferwiderje in besteand paad pas neidat ls sjen litten hat dat it in map is en gjin apparaat.

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

It type dat stat rapportearret is de fluchste ûnderskieder, en in map op dat paad is de meast foarkommende ferrassing yn minimale bylden. In goed bedoelde mkdir yn in Dockerfile lit krekt dat efter, en gjin hoemannichte moduleladen ferfangt in map troch in tekentekenapparaat. Major 10 mei minor 200 is it registrearre pear foar tun, yn heksdesimaal útdrukt as a en c8.

Fjouwer spoaren, fjouwer oarsaken

Fjouwer oarsaken ferklearje hast elk gefal, en elk lit in oar spoar yn 'e logboeken efter. Begjin by de opstartomjouwing. Skyfleanleaze bylden, ynboude boerden en initramfs-fazen montearje faak noch devtmpfs noch in troch udev beheard /dev, sadat gjin proses ea it knooppunt skriuwt. Lês dan de montaazje-opsjes fan wat /devhûsfestet, want nodev lit it paad bestean wylst it wegeret it te iepenjen, en in bind-montaazje fan in hurde host draacht de flagge sûnder him oan te kundigjen. In allinnich-lêzen-montaazje falt earder en lûder: mknod jout dêr EROFS werom, wylst EPERM betsjut dat it proses de kapasiteit mist en net dat it bestânsysteem himsels beskermet. Ta beslút, in kontenerruntime mei syn eigen /dev tmpfs hat it knooppunt yn syn eigen nammeruimte ynjektearre nedich, en syn apparaat-cgroup moat it major- en minor-pear tastean.

Kontrolearje de beliedslaach foar't jo wer rjochten feroarje. SELinux en AppArmor kinne in iepening wegerje dy't elk bestânsattribút tastiet, en dy wegering ferskynt yn it auditlogboek ynstee fan yn 'e klientútfier. In rjochtsferoaring dy't nea yn in wegering ferskynt is tiid dy't folslein oan 'e ferkearde laach bestege is.

sudo journalctl -k -n 20 --no-pager
sudo ausearch -m AVC -ts recent | tail -5

Bewiis it mei in ynterface, net mei in list

In slagge list bewiist dat in paad bestiet en net mear. Iepenje in sûne tun-knooppunt foar lêzen en de oprop komt werom mei in flater, want it apparaat hat gjin lêssemantyk en is gjin gewoan bestân. Dy flater is hjir it súksessinjaal, en it werkenningen derfan hâldt jo tsjin it as in stoarning te efterfolgjen.

head -c 1 /dev/net/tun
head: error reading '/dev/net/tun': File descriptor in bad state

De beslissende test makket in ynterface, want it beoefenet de stjoerder, it knooppunt en jo privileezjes yn ien stap. As it tafoegjen slagget en de keppeling ferskynt, wurkje alle trije. As it mislearret, skiedt errno de oarsaken: ENOENT betsjut dat der gjin brûkbere knooppunt is, EPERM wiist op kapasiteit, montaazjeflaggen of belied, en EBUSY betsjut dat in oar proses de ynterface al hat.

sudo ip tuntap add dev tun7 mode tun
ip -brief link show tun7
sudo ip tuntap del dev tun7 mode tun

Fier dy test út yn 'e kontekst dy't wier mislearret, want in tsjinstienheid, in kontener of in plande taak kin in oare kapasiteitsset drage as jo oanmeldskulp. In test dy't yn 'e ferkearde kontekst slagget, bewiist neat oer de mislearjende.

As it apparaat net it probleem is

As de ynterfacetest slagget en de klient noch mislearret, is it oerbleaune probleem it profyl, de tsjinstkontekst of de rûte, en it apparaat is goed. Dat is it momint om op te hâlden mei it bewurkjen fan apparaatknooppunten, want fierdere feroarings foegje allinnich ôfstân ta oan in wurkjend systeem.

Fier elke kear deselde fiif kontrôles út ynstee fan in nije te betinken: is de module laden sûnder in konkurrearjende module, is it paad in tekentekenapparaat mei de juste major en minor, binne de montaazje-opsjes skjin, draacht de proseskontekst de kapasiteit, en is der in beliedswegering op it tiidstempel fan 'e mislearring. In stoarning dy't alle fiif oerlibbet is gjin apparaatprobleem, wat it berjocht ek neamt.

Relatearre artikelen