OpenVPN berhenti dengan keluhan errno 2 tentang /dev/net/tun sementara lsmod dengan santai mencantumkan modul tun. Kedua fakta benar pada saat yang sama. Modul menyediakan pengandar, dan jalur yang dibuka klien adalah simpul perangkat yang harus dibuat oleh sesuatu yang lain. Memperlakukan keduanya sebagai satu objek adalah alasan mengapa perbaikan yang jelas — memuat ulang modul — tidak mengubah apa pun.

Dua objek, dua pemilik berbeda

Modul kernel dan simpul perangkat adalah objek independen dengan siklus hidup independen. Memuat modul mendaftarkan pengandar, dan pada sistem dengan devtmpfs kernel meminta simpul yang sesuai dibuat. Pada sistem tanpa devtmpfs tidak ada yang membuat apa pun, dan pengandar duduk di sana tanpa jalur yang menunjuk padanya. Modul dapat termuat, sehat, dan sama sekali tidak terjangkau melalui sistem berkas pada saat yang sama.

Itulah sebabnya teks galat dan daftar modul tidak saling bertentangan. Klien membuka jalur, jalur itu tidak ada, dan kernel mengembalikan ENOENT sebelum pengandar tun pernah ditanyai. Memuat ulang modul tidak dapat memperbaiki jalur yang hilang, dan membuat jalur tidak dapat memperbaiki pengandar yang hilang.

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

devtmpfs versus mknod eksplisit

Biasanya dua mekanisme membuat simpul itu, dan mengetahui mana yang seharusnya bertanggung jawab memberi tahu Anda apa yang harus diperbaiki. devtmpfs membuat kernel menciptakan simpul perangkat dalam instans yang terpasang, dan udev menerapkan kepemilikan serta izin di atasnya. Sebuah mknod eksplisit adalah jalur manual untuk image dan ruang nama tempat keduanya tidak berjalan saat boot.

Bandingkan hasil, bukan niat. Jika devtmpfs terpasang di /dev dan simpulnya masih tidak ada, pengandarnya bukan yang Anda duga, atau sesuatu menghapus simpul itu setelah boot. Jika /dev adalah direktori biasa di dalam rootfs yang diekstrak, tidak ada mekanisme otomatis dan siapa pun yang membangun image harus membuat simpul itu.

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

Di tempat tidak ada mekanisme yang berjalan, simpul harus dibuat dengan tangan, dan urutannya penting. Buat direktori induk lebih dulu, karena mknod tidak dapat mengarangnya, lalu perangkat karakter, lalu mode yang membuatnya hanya dapat ditulis oleh root. Muat ulang modul sebelum Anda membuat simpul, dan hapus jalur yang ada hanya setelah ls menunjukkan bahwa itu direktori, bukan perangkat.

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

Jenis yang dilaporkan oleh stat adalah pembeda tercepat, dan direktori pada jalur itu adalah kejutan paling umum di image minimal. Sebuah mkdir yang berniat baik di Dockerfile meninggalkan persis itu, dan tidak ada jumlah pemuatan modul yang menggantikan direktori dengan perangkat karakter. Major 10 dengan minor 200 adalah pasangan terdaftar untuk tun, dinyatakan dalam heksadesimal sebagai a dan c8.

Empat jejak, empat penyebab

Empat penyebab menjelaskan hampir setiap kasus, dan masing-masing meninggalkan jejak berbeda di log. Mulailah dari lingkungan boot. Image tanpa disk, papan tertanam, dan tahap initramfs sering tidak memasang devtmpfs maupun /devyang dikelola udev, sehingga tidak ada proses yang pernah menulis simpul itu. Lalu baca opsi pemasangan pada apa pun yang menghosting /dev, karena nodev mengizinkan jalur itu ada tetapi menolak membukanya, dan pemasangan bind yang diambil dari host yang dikeraskan membawa bendera itu tanpa mengumumkan dirinya. Pemasangan hanya-baca gagal lebih awal dan lebih lantang: mknod mengembalikan EROFS di sana, sedangkan EPERM berarti prosesnya kekurangan kemampuan, bukan bahwa sistem berkas melindungi dirinya sendiri. Terakhir, runtime kontainer dengan /dev tmpfs miliknya sendiri memerlukan simpul itu disuntikkan ke ruang nama miliknya, dan cgroup perangkatnya harus mengizinkan pasangan major dan minor.

Periksa lapisan kebijakan sebelum mengubah izin lagi. SELinux dan AppArmor dapat menolak pembukaan yang diizinkan oleh setiap atribut berkas, dan penolakan itu muncul di log audit, bukan di keluaran klien. Perubahan izin yang tidak pernah muncul dalam penolakan adalah waktu yang dihabiskan sepenuhnya di lapisan yang salah.

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

Buktikan dengan antarmuka, bukan daftar

Daftar yang berhasil membuktikan bahwa sebuah jalur ada dan tidak lebih. Buka simpul tun yang sehat untuk dibaca dan panggilan kembali dengan galat, karena perangkat itu tidak punya semantik baca dan bukan berkas biasa. Galat itulah sinyal keberhasilan di sini, dan mengenalinya mencegah Anda mengejarnya sebagai kerusakan.

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

Uji yang menentukan membuat antarmuka, karena itu melatih pengandar, simpul, dan hak istimewa Anda dalam satu langkah. Jika penambahan berhasil dan tautan muncul, ketiganya bekerja. Ketika gagal, errno memisahkan penyebabnya: ENOENT berarti tidak ada simpul yang dapat dipakai, EPERM menunjuk pada kemampuan, bendera pemasangan, atau kebijakan, dan EBUSY berarti proses lain sudah memiliki antarmuka itu.

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

Jalankan uji itu dalam konteks yang benar-benar gagal, karena unit layanan, kontainer, atau tugas terjadwal dapat membawa set kemampuan yang berbeda dari shell login Anda. Uji yang lolos dalam konteks yang salah tidak membuktikan apa pun tentang yang gagal.

Ketika perangkat bukan masalahnya

Jika uji antarmuka berhasil dan klien masih gagal, masalah yang tersisa adalah profil, konteks layanan, atau rute, dan perangkatnya baik-baik saja. Itulah saatnya berhenti menyunting simpul perangkat, karena perubahan lebih lanjut hanya menambah jarak dari sistem yang berfungsi.

Jalankan lima pemeriksaan yang sama setiap kali alih-alih mengarang yang baru: apakah modul termuat tanpa modul saingan, apakah jalurnya perangkat karakter dengan major dan minor yang benar, apakah opsi pemasangannya bersih, apakah konteks proses membawa kemampuan itu, dan apakah ada penolakan kebijakan pada stempel waktu kegagalan. Kerusakan yang bertahan dari kelimanya bukan masalah perangkat, apa pun yang disebut pesan itu.

Artikel terkait