کتابدار برای مرتب کردن قفسه‌ها به کلید گاوصندوق نیاز ندارد. سرویس لینوکس هم نباید برای یک کار کوچک، تمام اختیار root را بگیرد. امشب capabilityها و محدودسازی systemd را روی یک unit بی‌خطر می‌بینیم.

این جلسه بخشی از دورهٔ لینوکس ۳۰۳ در ۴۰ شب است.

محیط تمرین: Ubuntu 24.04؛ systemd 255 و libcap2-bin؛ حساب student از آزمایشگاه؛ sudo.

جایگاه در دوره: هدف‌های 332.1 آزمون 303-300.

root را به اختیارهای مشخص تقسیم کن#

Linux capabilities بعضی اختیارهای ممتاز را جدا می‌کنند؛ مثلاً CAP_NET_BIND_SERVICE به bind کردن پورت ممتاز مربوط است. «غیر root» همیشه به معنی «بدون اختیار ممتاز» نیست: setuid و file capabilities را هم باید ببینی. effective، permitted، inheritable و bounding set نقش‌های یکسانی ندارند.

getcap /usr/bin/ping
capsh --print

ممکن است ping در توزیع تو capability نداشته باشد و از سازوکار دیگر استفاده کند؛ خروج خالی را خطا تلقی نکن. setcap را روی ابزارهای اصلی سیستم تمرین نکن؛ در صورت نیاز فقط کپی مخصوص آزمایشگاه را تغییر بده و قبل و بعد را ثبت کن.

واحدی که چیز زیادی نمی‌خواهد#

فایل /etc/systemd/system/lpic303-demo.service:

[Unit]
Description=LPIC303 sandbox demo
[Service]
ExecStart=/usr/bin/sleep infinity
User=student
NoNewPrivileges=yes
CapabilityBoundingSet=
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
RestrictAddressFamilies=AF_UNIX
[Install]
WantedBy=multi-user.target

sleep فقط زنده می‌ماند؛ به شبکه و فایل خصوصی نیازی ندارد. NoNewPrivileges جلوی به‌دست آوردن اختیار تازه از اجرای فایل را می‌گیرد. bounding set خالی capabilityها را محدود می‌کند؛ ProtectSystem و ProtectHome دسترسی به مسیرها را کاهش می‌دهند. این گزینه‌ها جای منطق صحیح برنامه را نمی‌گیرند.

sudo systemd-analyze verify /etc/systemd/system/lpic303-demo.service
sudo systemctl daemon-reload
sudo systemctl start lpic303-demo
systemctl show lpic303-demo -p User -p MainPID -p NoNewPrivileges -p CapabilityBoundingSet
systemd-analyze security lpic303-demo.service

انتظار داریم unit فعال و propertyها مطابق فایل باشند. امتیاز security یک راهنمای بررسی تنظیمات است، نه گواهی نفوذناپذیری. برای دیدن مرز واقعی، PID را از MainPID بردار و با sudo nsenter -t PID -m -- ls /home فضای mount سرویس را بررسی کن؛ PID عدد واقعی است. خواندن یا نوشتن لازم برنامهٔ واقعی باید در همان context آزموده شود.

سیاست بیش از حد سخت هم شکست است#

اگر سرویس واقعی نیاز به شبکه داشته باشد، AF_UNIX تنها آن را خراب می‌کند. SystemCallFilter فراخوانی‌های سیستم را محدود می‌کند؛ فهرست مناسب باید با رفتار برنامه آزموده شود، نه از سرویس دیگری کپی شود. برای دادهٔ نوشتنی، StateDirectory یا مسیر محدودشدهٔ مشخص می‌تواند از بازکردن تمام فایل‌سیستم بهتر باشد.

تمرین و پایان#

یکی از کنترل‌ها را موقتاً حذف کن و property و امتیاز را مقایسه کن؛ سپس بازگردان. برای پایان sudo systemctl stop lpic303-demo را اجرا کن؛ این unit را در تمرین enable نکردیم.

مرجع دقیق هر گزینه: systemd.exec ؛ مرجع سازوکار capabilityها: capabilities(7) در پروژهٔ Linux man-pages .