/dev/net/tun байхгүй боловч tun ачаалагдсан: төхөөрөмжийн зангилааг засна
Ачаалагдсан tun модуль төхөөрөмжийн зангилаа байгааг батлахгүй. Драйверыг зангилаанаас салгаж, дарааллаар нь дахин бүтээж, интерфэйсээр шалгана.
OpenVPN errno 2 гомдолтойгоор зогсдог, тэр нь /dev/net/tun тухай, харин lsmod tun модулийг тайван жагсаадаг. Хоёр баримт нэгэн зэрэг үнэн. Модуль драйвер өгдөг, клиентийн нээх зам нь өөр зүйлийн үүсгэх ёстой төхөөрөмжийн зангилаа юм. Хоёулыг нэг объект гэж үздэг учраас модулийг дахин ачаалах гэх ойлгомжтой засвар юу ч өөрчлөхгүй байна.
Хоёр объект, хоёр өөр эзэн
Цөмийн модуль ба төхөөрөмжийн зангилаа нь бие даасан амьдралын мөчлөгтэй бие даасан объектууд юм. Модулийг ачаалах нь драйверыг бүртгэдэг бөгөөд devtmpfs-тэй системд цөм холбогдох зангилааг үүсгэхийг хүсдэг. devtmpfsгүй системд юу ч юуг ч үүсгэхгүй, драйвер түүн рүү заасан ямар ч замгүйгээр тэнд сууна. Модуль нэгэн зэрэг ачаалагдсан, эрүүл, файлын системээр дамжуулан огт хүрэх боломжгүй байж болно.
Тиймээс алдааны текст ба модулийн жагсаалт хоорондоо зөрчилдөхгүй. Клиент зам нээдэг, зам байхгүй, цөм tun драйвераас асуухаас өмнө ENOENT буцаана. Модулийг дахин ачаалах нь алга болсон замыг засахгүй, замыг үүсгэх нь алга болсон драйверыг засахгүй.
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 бүхий тэмдэгт төхөөрөмж үү, холболтын сонголт цэвэр үү, процессын орчин чадварыг үүрч байна уу, бүтэлгүйтлийн цаг дээр бодлогын татгалзал байна уу. Тавыг бүгдийг нь даван туулсан гэмтэл нь төхөөрөмжийн асуудал биш, мессеж юу гэж дурдсан ч.