Hook uni root sifatida qo‘lda ishga tushirganingizda ishlaydi va qaytaradi Operation not permitted xizmat uni ishga tushirgan paytda. Fayl o‘sha ishga tushirishlar orasida o‘zgarmadi; muhit o‘zgardi. systemd jarayonga kichikroq dunyo beradi: kamroq imkoniyatlar, boshqa /dev, faqat o‘qish uchun fayl tizimi yo‘llari va vazifalar chegarasi. Muvaffaqiyatsizlikni bitta aniq operatsiyani rad etgan chegara sifatida o‘qing, buzilgan skript sifatida emas.

Rad etilgan operatsiyadan boshlang

Unit muvaffaqiyatsiz bo‘ldi degan log satri sizga deyarli hech narsa aytmaydi. Foydali satr rad etilgan chaqiruvni nomlaydi: ochib bo‘lmagan qurilma tuguni, yozib bo‘lmagan katalog, yaratib bo‘lmagan namespace. Bitta yo‘riqnomaga tegishdan oldin o‘sha chaqiruvni toping, chunki har biri boshqa cheklovga mos keladi. So‘ng paket yuborgan fayl o‘rniga, drop-in bilan birga, haqiqatda ishlagan unitni o‘qing.

Quyidagi so‘rov fragment yo‘lini, drop-in kataloglarini va qurilma yoki fayl tizimi rad etilishi uchun muhim xususiyatlarni chop etadi. Qaysi chegara tegishli ekanini hal qilishdan oldin ularning barchasini o‘qing:

systemctl show "[email protected]" -p FragmentPath -p DropInPaths -p PrivateDevices -p DevicePolicy -p DeviceAllow -p ProtectHome -p ProtectSystem -p TasksMax
journalctl -u "[email protected]" -b --no-pager | grep -iE 'operation not permitted|permission denied|cannot open|failed'

O‘sha blokda hech narsa yozmaydi. Rad etilgan chaqiruv jurnalda bo‘lmasa, yo‘riqnomalarni taxmin qilish o‘rniga bir ishga tushirish uchun mijozning batafsilligini oshiring. Ishlab turgan jarayon unit ishga tushganini isbotlaydi, hook kerakli imtiyozlar bilan ishlaganini emas.

Namespacega TUN qurilmasi hech qachon ishlatmaydigan mount huquqlari kerak

Bitta hook ichida bir xil ko‘rinadigan ikki operatsiyaning ruxsat profillari boshqacha. Ochish /dev/net/tun va interfeys yaratish tarmoq administratsiyasi va o‘sha tugunga kirishni talab qiladi. Nomlangan tarmoq namespace yaratish ham mount bilan bog‘liq ishni talab qiladi, chunki namespace vositasi yangi /sys ko‘rinishni mount qiladi va holat katalogini joyiga bog‘laydi. yuqori oqim mijoz uniti mount administratsiyasini ataylab o‘z cheklov to‘plamidan tashqarida qoldiradi, shuning uchun namespace qadami rad etiladi, tunnelning o‘zi ishlagan bo‘lardi.

Shuning uchun qurilma tugunini berish skriptni qutqarmaydi. Qurilma ruxsati bitta savolga javob beradi, bu jarayon bu tugunni ocha oladimi, namespace savoli esa boshqa. Biror narsani kengaytirishdan oldin muvaffaqiyatsiz chaqiruvni uning imkoniyatiga moslang.

Sizning shellingizdagi test cheklanmagan root ega bo‘lgan har qanday imkoniyatni meros oladi, unit esa cheklov to‘plami saqlab qolgan narsani meros oladi. Bu ikki ishga tushirish turli tajribalar ikkilik fayl bir xil bo‘lsa ham.

Qurilmalar, himoyalangan yo‘llar va vazifa chegaralari

Rad etilgan operatsiya ma’lum bo‘lgach, uch guruh yo‘riqnoma ko‘pchilik nosozliklarni tushuntiradi. Qurilma kirishini PrivateDevices boshqaradi, u /dev ni minimal psevdo-qurilmalar to‘plami bilan almashtiradi, va DevicePolicy bilan DeviceAllow, ular cgroup nimaga ruxsat berishini hal qiladi. /dev/net/tun bu minimal to‘plamning qismi emas, shuning uchun PrivateDevices=yes ga ega unit uni ocha olmaydi, qurilma siyosati nima desa ham.

Fayl tizimi himoyasi ikkinchi savolga javob beradi. ProtectHome=yes /home, /root va /run/user ni yetib bo‘lmaydigan qilib qo‘yadi, va ProtectSystem=full /usr, /boot va /etc ni faqat o‘qish uchun qiladi. Shuning uchun o‘z konfiguratsiya fayli yonida yozadigan hook sizning shellingizda ishlaydi va unit ostida muvaffaqiyatsiz bo‘ladi, yo‘q imkoniyat bilan bir xil ruxsat shaklida. Yoziladigan kirishni siyosat ruxsat bergan yo‘lga ko‘chiring, yoki tor ReadWritePaths= yozuv qo‘shing.

Resurs cheklovlari uchinchi guruh va eng kam ko‘rinadiganidir. TasksMax= unit yaratishi mumkin bo‘lgan vazifalar sonini cheklaydi, fayl deskriptori chegarasi esa soketlar va tutqichlar uchun xuddi shunday ishlaydi. Chegaradan oshib o‘sgan joylashtirish ruxsat xatosi o‘rniga resurs xatosi bilan muvaffaqiyatsiz bo‘ladi, shuning uchun aniq xabar hali ham muhim.

Namespace qadamini hookdan tashqariga chiqaring

Mijoz ega bo‘lmasligi kerak bo‘lgan imtiyozni talab qiladigan tayyorgarlik o‘z unitiga tegishli. Mijozdan oldin ishlaydigan, natijasini saqlaydigan va ulanishdan oldin tartiblangan oneshot namespace qadamiga kerakli narsani beradi, bu huquqlarni tunnel jarayoniga topshirmasdan. Keyin mijoz o‘sha unitga murojaat qiladi, skriptni o‘zining up hookidan chaqirish o‘rniga.

Quyidagi shablon boshlang‘ich shakl, o‘qilmasdan qo‘llaniladigan narsa emas. U tayyorgarlikni imtiyoz yashaydigan joyda saqlaydi va tunnel unitini tegilmagan holda qoldiradi:

# /etc/systemd/system/[email protected]
[Unit]
Description=Namespace preparation for %i
Before=openvpn-client@%i.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/netns-up.sh %i
CapabilityBoundingSet=CAP_NET_ADMIN CAP_SYS_ADMIN
[Install]
WantedBy=multi-user.target

Tartibni paketlangan unitni tahrirlash o‘rniga drop-in bilan qo‘shing, shunda yangilanish sizning o‘zgarishingizni jimgina tashlab yubora olmaydi. Katalog nusxa nomiga bog‘langan, shuning uchun ikkinchi profil o‘z faylini talab qiladi:

sudo mkdir -p /etc/systemd/system/[email protected]
sudo tee /etc/systemd/system/[email protected]/10-namespace.conf >/dev/null <<'CONF'
[Unit]
[email protected]
[email protected]
CONF
sudo systemctl daemon-reload

O‘zgarishdan keyin xuddi shu chaqiruvni takrorlang

Tuzatish faqat xuddi shu chaqiruv boshqa natija berganida tasdiqlanadi. Ikkala unitni qayta ishga tushiring, muvaffaqiyatsiz bo‘lgan operatsiyani bajaring va uning natijasini o‘zgarishdan oldin saqlagan jurnal satringiz bilan solishtiring. Hook boshqa hech qachon ishlamaydigan holatda ishga tushadigan unit tuzatish emas.

Quyidagi ketma-ketlik taqqoslashni halol saqlaydi, chunki u unit rangini emas, rad etilgan chaqiruvni tekshiradi. Uning chiqishini o‘zgarishdan oldin ushlagan jurnal satri yoniga saqlang:

sudo systemctl restart "[email protected]" "[email protected]"
systemctl status "[email protected]" --no-pager
journalctl -u "[email protected]" -b --no-pager | grep -c 'Operation not permitted'
ip -brief addr show tun0

Oxirgi satrni o‘qish o‘rniga rad etishlarni sanang, chunki hook muvaffaqiyatsiz bo‘lishi, qayta urinishi va muvaffaqiyat qozonishi mumkin, chegara siljiganini faqat son ko‘rsatadi. Drop-inda siz bo‘shatgan yo‘riqnoma va sababni nomlaydigan izoh qoldiring, chunki keyingi yangilanish konfiguratsiyangizni paketlangan standart bilan solishtiradi. Har bir himoya o‘chirilgandan keyingina ishga tushadigan unit tuzatilmagan.

O'xshash maqolalar