رفتن به محتوا
IROSG.
مقاله‌ها

Podman Rootless؛ کانتینر بدون Root دقیقاً چه مرزی می‌سازد؟

Rootless Podman را با user namespace، storage، port binding و محدودیت‌های واقعی آن بفهمیم؛ بدون اینکه آن را معادل sandbox کامل بدانیم.

Podman Rootless؛ کانتینر بدون Root دقیقاً چه مرزی می‌سازد؟

تصویر کلی

Podman می‌تواند بدون daemon مرکزی و در حالت rootless اجرا شود؛ نگاشت UID/GID و user namespace بخش مهم این مدل است.

برای فهم این موضوع بهتر است اجزا را به‌عنوان یک مسیر ببینیم، نه مجموعه‌ای از گزینه‌های مستقل. در Production معمولاً مشکل زمانی شکل می‌گیرد که تنظیم روی دیسک، وضعیت Runtime و فرض تیم درباره رفتار سیستم با هم یکی نیستند. به همین دلیل مشاهده وضعیت مؤثر، Log و Metric باید کنار Configuration بررسی شود.

اجزای اصلی و مرز مسئولیت

در rootless mode، storage، networking و دسترسی به deviceها نسبت به rootful محدودیت‌های متفاوتی دارند و configuration کاربر اهمیت دارد.

در طراحی عملی، برای هر جزء یک سؤال روشن بنویسید: چه ورودی می‌گیرد، چه خروجی تولید می‌کند، چه Stateای نگه می‌دارد و در خرابی چه کسی مسئول Recovery است. این مدل ساده کمک می‌کند خطاهای شبکه، هویت، ذخیره‌سازی یا Replication به‌اشتباه به جزء دیگری نسبت داده نشوند.

خطاهای رایج

Rootless سطح privilege را کم می‌کند اما isolation مطلق نیست؛ kernel، mount، capability و policy میزبان همچنان مرز امنیتی واقعی هستند.

خطای دیگر، فعال‌کردن قابلیت پیشرفته بدون تعریف معیار موفقیت است. قبل از تغییر، Baseline بگیرید؛ بعد از تغییر همان Signalها را مقایسه کنید. اگر سیستم توزیع‌شده است، Failure Modeهای قطع شبکه، Restart، Lag، Timeout و از دست‌رفتن Dependency را نیز آزمایش کنید.

چک‌لیست عملی

  • نسخه و Configuration مؤثر را ثبت کنید، نه فقط فایل مورد انتظار را.
  • مسیر داده و کنترل را جدا رسم کنید.
  • Health، Latency، Error Rate و ظرفیت را قبل و بعد از تغییر مقایسه کنید.
  • برای تغییرات Stateful، Backup/Restore یا Rollback واقعی را آزمایش کنید.
  • دسترسی مدیریتی را حداقل کنید و Log تصمیم‌ها را نگه دارید.
  • مستندات همان نسخه محصول را مرجع نهایی قرار دهید.

تمرین IROSG

یک محیط کوچک آزمایشی بسازید و فقط یک Failure را تزریق کنید؛ مثلاً قطع Upstream، حذف یک Replica، خطای DNS یا تغییر Route. قبل از آزمایش بنویسید انتظار دارید کدام Metric و Log تغییر کند. بعد نتیجه واقعی را با انتظار مقایسه کنید. این تمرین معمولاً سریع‌تر از حفظ‌کردن Optionها، مدل ذهنی سیستم را اصلاح می‌کند.

مرجع

این راهنما بر پایه مستندات رسمی Podman نوشته شده و مثال‌های عملی تحریریه برای آموزش دفاعی و عملیاتی هستند.

Root داخل کانتینر چه معنایی دارد؟

در اجرای rootless، کاربر عادی میزبان کانتینر را ایجاد می‌کند و user namespace رابطه شناسه‌های داخل و بیرون را تغییر می‌دهد. بنابراین شناسه صفر داخل کانتینر الزاماً همان اختیار root میزبان را ندارد. با این حال فرایند همچنان می‌تواند به چیزهایی دسترسی داشته باشد که کاربر میزبان و تنظیمات اجرا در اختیارش گذاشته‌اند. اگر پوشه اسناد کاربر را برای نوشتن mount کنید، rootless بودن مانع تغییر همان اسناد مجازشده نمی‌شود. مرز امنیت از ترکیب namespace، مجوزها و ورودی‌های واگذارشده ساخته می‌شود.

برای مشاهده عملی، یک پوشه آزمایشی بدون داده مهم بسازید و مالک فایل را داخل و بیرون کانتینر مقایسه کنید. نگاشت UID و GID را با ابزارهای مربوط بخوانید و نتیجه را ثبت کنید. نام کاربر در دو محیط ممکن است متفاوت باشد؛ عدد و نگاشت اهمیت دارد. تغییر کورکورانه مالکیت همه فایل‌ها برای رفع خطا می‌تواند دسترسی برنامه‌های دیگر را خراب کند. ابتدا بفهمید برنامه داخل کانتینر با کدام شناسه اجرا می‌شود و آن شناسه بیرون چگونه دیده می‌شود.

محدوده شناسه‌های فرعی

ورودی‌های subuid و subgid امکان نگاشت مجموعه‌ای از شناسه‌ها را فراهم می‌کنند. تخصیص آن‌ها باید با سیاست سیستم هماهنگ و بدون هم‌پوشانی نامناسب باشد. این فایل‌ها را از یک راهنمای عمومی بدون بررسی روی میزبان چندکاربره کپی نکنید. بعد از تغییر، رفتار محیط موجود و روش اعمال تغییر را مطابق نسخه نصب‌شده بررسی کنید. کانتینر قدیمی و اجرای تازه ممکن است وضعیت یکسانی نداشته باشند تا چرخه لازم کامل شود.

در عیب‌یابی خطای مالکیت هنگام دریافت ایمیج، احتمال محدودیت نگاشت را از مشکل رجیستری جدا کنید. ممکن است دانلود موفق باشد ولی استخراج لایه با تغییر مالکیت شکست بخورد. پیام خطا و مرحله اجرا را بخوانید. دادن دسترسی root به فرمان می‌تواند یک مخزن و محیط جدا بسازد و مسئله را پنهان کند. اجرای Podman با کاربر عادی و اجرای آن با root به طور پیش‌فرض موجودی مشترک کانتینرها نیستند؛ این تفاوت را در دستورالعمل تیم روشن کنید.

فایل‌سیستم و فضای ذخیره

محل نگه‌داری ایمیج‌ها و داده rootless معمولاً به کاربر وابسته است. ظرفیت home، نوع فایل‌سیستم و تنظیم storage روی رفتار اثر دارند. اگر home روی فایل‌سیستم شبکه‌ای قرار دارد، سازگاری آن با user namespace و روش storage را از مستندات بررسی کنید. خطای این لایه با افزایش حافظه کانتینر حل نمی‌شود. مسیر داده پایدار برنامه را نیز از محل لایه‌های قابل بازسازی ایمیج جدا طراحی کنید.

برای پشتیبان‌گیری، بدانید کدام داده در volume یا bind mount است و کدام فقط در لایه نوشتنی کانتینر مانده است. حذف و ایجاد دوباره کانتینر نباید داده ضروری را بی‌دلیل از بین ببرد. در آزمایش، یک رکورد ساختگی ایجاد کنید، کانتینر را طبق روش معمول بازسازی کنید و وجود داده را بررسی کنید. اگر برنامه پایگاه داده است، سازگاری پشتیبان نیازمند روش خود آن برنامه است؛ کپی پوشه در حال نوشتن لزوماً نسخه قابل بازیابی نمی‌سازد.

شبکه rootless و انتظار درست

شبکه در اجرای بدون root می‌تواند از سازوکارهای کاربری استفاده کند و جزئیات آن با نسخه و تنظیمات متفاوت است. بنابراین رفتار نشانی مبدأ، دسترسی به میزبان و انتشار پورت را از آزمایش واقعی بفهمید. یک سرویس داخلی کانتینر را نخست از همان کانتینر، سپس از میزبان و بعد از یک کلاینت مجاز بیرونی بررسی کنید. این ترتیب مشخص می‌کند listener برنامه، نگاشت پورت یا فایروال کدام‌یک مانع است.

انتشار پورت را با رابط مورد نیاز محدود کنید. اگر سرویس فقط برای استفاده محلی است، گوش‌دادن روی همه رابط‌ها دامنه دسترسی را بی‌دلیل افزایش می‌دهد. محدودیت پورت‌های پایین نیز به تنظیمات سیستم وابسته است و نباید با اجرای ناگهانی همه کانتینر به عنوان root دور زده شود. راهکار را با نیاز واقعی سرویس و سیاست میزبان انتخاب کنید. پس از تغییر، از یک محل بیرونی مجاز بررسی کنید چه چیزی واقعاً در دسترس است؛ خروجی فرمان اجرا همه مسیر شبکه را ثابت نمی‌کند.

capability، seccomp و کنترل اجباری

rootless یک لایه است و جای کاهش capabilityها، فیلتر فراخوانی سیستمی و کنترل‌هایی مانند SELinux یا AppArmor را نمی‌گیرد. برنامه‌ای که به ابزار خاص نیاز ندارد نباید همه اختیارات ممکن را دریافت کند. گزینه‌های گسترده‌ای مثل اجرای privileged را راه‌حل پیش‌فرض خطای سازگاری نکنید. ابتدا عملیات دقیق ناموفق را پیدا کنید و کوچک‌ترین نیاز قابل توضیح را بررسی کنید. هر افزایش اختیار باید به یک آزمون کاربردی مرتبط باشد.

اگر bind mount روی میزبان دارای SELinux استفاده می‌شود، برچسب‌گذاری نیز می‌تواند در دسترسی نقش داشته باشد. تغییر مالکیت Unix بدون بررسی label ممکن است هیچ اثری نداشته باشد. در مقابل تغییر گسترده label روی پوشه مشترک می‌تواند سرویس دیگری را مختل کند. یک پوشه آزمایشی اختصاصی بسازید و اثر گزینه‌های مستند را همان‌جا ببینید. سپس فقط روش متناسب با اشتراک یا اختصاصی بودن داده را به محیط اصلی منتقل کنید.

اجرای پایدار با مدیر سرویس

فرمانی که در نشست تعاملی سالم اجرا می‌شود، لزوماً پس از خروج کاربر یا راه‌اندازی دوباره میزبان همان رفتار را ندارد. برای سرویس پایدار از روش مدیریت مستند مانند واحدهای کاربری systemd و Quadlet متناسب با نسخه استفاده کنید. وابستگی به شبکه، مسیر داده و زمان آماده‌شدن را روشن کنید. نگه‌داری فرایند در ترمینال یا اسکریپت نامشخص، وضعیت restart و ثبت خطا را دشوار می‌کند.

در آزمون پذیرش، خروج از نشست و راه‌اندازی دوباره محیط آزمایشی را وارد کنید. بررسی کنید سرویس با همان کاربر، همان تنظیمات و همان داده بالا می‌آید. اگر نیاز به فعال بودن مدیر کاربری بدون نشست وجود دارد، آن را آگاهانه با سیاست میزبان هماهنگ کنید. log باید در مقصدی باشد که تیم عملیات واقعاً می‌تواند بخواند. تفاوت محیط shell و محیط مدیر سرویس، مانند متغیرها و مسیر فایل، از علت‌های رایج اجرای متفاوت است.

ایمیج، secret و زنجیره تأمین

بدون root اجرا شدن، معتبر بودن ایمیج را ثابت نمی‌کند. منبع ایمیج، digest و سیاست اعتماد باید مشخص باشند. نام کوتاه مبهم می‌تواند به رجیستری ناخواسته حل شود؛ برای سرویس مهم از مرجع روشن استفاده کنید. secret را در لایه ایمیج یا فرمانی که در تاریخچه باقی می‌ماند نگذارید. روش تزریق باید با نیاز برنامه و قابلیت نسخه هماهنگ باشد و در log نیز مقدار حساس آشکار نشود.

به‌روزرسانی خودکار یا دستی ایمیج باید با آزمون سلامت و امکان بازگشت همراه باشد. وجود tag ثابت تضمین نمی‌کند محتوا ثابت مانده است. هنگام تغییر، digest قبلی و جدید را ثبت کنید و داده پایدار را از نسخه اجرایی جدا نگه دارید. اگر نسخه جدید ساختار داده را تغییر می‌دهد، بازگشت فقط با اجرای ایمیج قبلی ممکن است کافی نباشد. این موضوع مسئله برنامه است و rootless بودن آن را حل نمی‌کند.

تشخیص خطا با کمترین تغییر

پیام خروج Podman را از پیام خروج برنامه داخل کانتینر جدا بخوانید. خطای ساخت محیط، پیدا نشدن فرمان و شکست منطق برنامه معناهای متفاوت دارند. ابتدا inspect، log و وضعیت فرایند را با زمان رخداد تطبیق دهید. یک کانتینر آزمایشی ساده با همان volume یا شبکه می‌تواند کمک کند عامل زیرساخت از برنامه جدا شود. در پایان، اصلاح باید توضیح دهد کدام نگاشت، مسیر یا مجوز تغییر کرده و چرا همان تغییر کافی بوده است.

سوکت مدیریت را مانند اختیار کاربر ببینید

دسترسی به سوکت یا API مدیریت Podman می‌تواند امکان ایجاد کانتینر و mount کردن داده‌های در دسترس همان کاربر را بدهد. بنابراین نباید آن را صرفاً یک فایل ارتباطی بی‌خطر دانست. اگر ابزار ساخت به این سوکت نیاز دارد، مرز اعتماد آن ابزار را بررسی کنید و سوکت را در اختیار برنامه‌های نامرتبط قرار ندهید. rootless دامنه اختیار را نسبت به root میزبان محدود می‌کند، ولی داده و حساب کاربری صاحب سرویس همچنان ارزشمند است. آزمون دسترسی باید نشان دهد فقط مصرف‌کنندگان مورد نظر می‌توانند عملیات مدیریتی انجام دهند و سرویس از شبکه عمومی قابل کنترل نیست.

TRACEABLE KNOWLEDGE

منابع و مطالعهٔ بیشتر

01
Podman — مستندات رسمیhttps://docs.podman.io/en/latest/markdown/podman.1.html
02
منبع تصویر رسمیhttps://podman.io/

آخرین بررسی تحریریه:

IROSG / EDITORIAL

خبرها و معرفی مشاهیر با نگارش مستقل و ذکر منبع تهیه شده‌اند. اعتبار و مجوز تصاویر در بخش منابع همین صفحه نگه‌داری می‌شود تا متن زیر عکس‌ها شلوغ نشود. داده‌های مرجع CVE با اعتباردهی به منابع اصلی ارائه می‌شوند.

سیاست تألیف و حقوق تصاویر ↗

ادامهٔ کشف.

مقاله‌ها ↗