/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 менен белги түзмөгү бекен, орнотуу параметрлери тазабы, процесс контексти жөндөмдү алып жүрөбү, жана ийгиликсиздик убагында саясат четке кагуусу барбы. Бешөөнөн тең аман өткөн бузулуу — түзмөк көйгөйү эмес, билдирүү эмнени айтса да.