Docker یا Podman بدون root؛ شباهت فرمان‌ها تفاوت امنیت را پنهان می‌کند

|نویسنده: تیم تحریریه QUASA|6 دقیقه مطالعه| 1
Docker یا Podman بدون root؛ شباهت فرمان‌ها تفاوت امنیت را پنهان می‌کند

برای انتقال بارکاری از Docker به Podman در حالت بدون root، از همان تصویر و پیکربندی در یک حساب آزمایشی شروع کنید و پیش از جابه‌جایی سرویس، دسترسی به فایل‌ها، شبکه و اجرای CI را بسنجید. شباهت فرمان‌ها مرز امنیتی یکسانی ایجاد نمی‌کند: طبق راهنمای rootless Docker، هم daemon و هم کانتینرها در فضای نام کاربر و بدون دسترسی root اجرا می‌شوند؛ daemon همچنان در مسیر اجرای Docker حضور دارد.

در مقابل، مستندات Podman آن را ابزاری بدون daemon مرکزی برای فرمان‌های محلی توصیف می‌کند که در حالت rootless فضای نام کاربر می‌سازد و داده‌های کانتینری را برای هر کاربر جدا نگه می‌دارد. بنابراین پرسش اصلی پیش از مهاجرت این است که بارکاری فعلی به کدام رفتار موتور، نگاشت شناسه، مسیر شبکه یا محل ذخیره‌سازی وابسته است؛ پاسخ را باید با اجرای همان بارکاری به دست آورد.

محیط آزمایشی را از سرویس اصلی جدا کنید

ابتدا وضعیت Docker فعلی را ثبت کنید. اجرای فرمان بدون sudo به‌تنهایی نشان نمی‌دهد daemon نیز rootless است؛ خروجی docker info، context فعال، گزینه‌های امنیتی سرور و مسیر socket را کنار هم ببینید. سپس تصویر و نسخهٔ آن، متغیرهای محیطی، پورت‌ها، شبکه‌ها، volumeها، bind mountها و فرمان‌های ساخت و اجرا در CI را یادداشت کنید. این مشخصات مبنای آزمون یکسان در دو محیط‌اند.

برای Podman حساب کاربری جداگانه‌ای بسازید که مجوز نوشتن روی دادهٔ تولید نداشته باشد. بازه‌های اختصاص‌یافته به آن را در /etc/subuid و /etc/subgid و دسترسی لازم برای ایجاد فضای نام کاربر بررسی کنید. همان تصویر و تنظیمات برنامه را با کپی داده یا دادهٔ آزمایشی اجرا کنید؛ اتصال مستقیم و قابل‌نوشتن دادهٔ اصلی، تشخیص اثر آزمون از تغییرات سرویس واقعی را دشوار می‌کند.

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

نگاشت UID و GID را روی کپی داده بسنجید

مسیر دادهٔ متصل به کانتینر Podman که دسترسی آن به نگاشت UID و GID روی میزبان لینوکسی وابسته است

کانتینری که بدون خطا شروع می‌شود، لزوماً می‌تواند فایل‌های برنامه را بخواند یا تغییر دهد. در اجرای rootless، شناسه‌های داخل کانتینر به شناسه‌های میزبان نگاشته می‌شوند و نتیجه برای bind mount به کاربر داخل تصویر، مالک فایل میزبان و شیوهٔ نگاشت وابسته است. برای هر مسیر داده، شناسهٔ مورد انتظار برنامه را با مالک و گروه فایل‌های میزبان مقایسه کنید.

آزمون را به خواندن یک فایل محدود نکنید: ساخت فایل تازه، تغییر نام، نوشتن در پوشهٔ موجود، بازکردن دوبارهٔ فایل و دسترسی پس از راه‌اندازی مجدد را با کپی داده امتحان کنید. برنامه‌ای که با کاربر غیر root داخل تصویر اجرا می‌شود ممکن است برای خواندن مجوز داشته باشد، اما در همان مسیر نتواند فایل تازه بسازد. مالک artifactهایی را که از کانتینر به میزبان برمی‌گردند نیز بررسی کنید؛ این موضوع در CI به اندازهٔ دادهٔ سرویس اهمیت دارد.

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

ذخیره‌سازی و شبکه را با بارکاری خود اندازه بگیرید

مسیر شبکهٔ کانتینر Podman بدون root از طریق pasta در برابر مسیر شبکهٔ میزبان با جداسازی کمتر

راهنمای عملکرد Podman اثر runtime، فایل‌سیستم میزبان، تصویر و گزینه‌های اجرا را بر نتیجه توضیح می‌دهد؛ میان overlayfs بومی، fuse-overlayfs و vfs تمایز می‌گذارد و برای آزمون درایور، حساب جداگانه را پیشنهاد می‌کند. همین راهنما می‌گوید ترافیک شبکهٔ rootless معمولاً از pasta می‌گذرد و این مسیر هزینهٔ عملکردی دارد؛ استفاده از شبکهٔ میزبان نیز فضای نام شبکه را حذف می‌کند و دسترسی به سرویس‌های محلی میزبان را افزایش می‌دهد.

در حساب آزمایشی، درایور ذخیره‌سازی فعال و محل نگهداری تصویرها را ثبت کنید. اگر پوشهٔ خانگی روی NFS یا فایل‌سیستم توزیع‌شده است، محل ذخیره‌سازی rootless Podman به بررسی ویژه نیاز دارد، زیرا چنین فایل‌سیستم‌هایی برای این کار پشتیبانی نمی‌شوند. زمان دریافت تصویر، ساخت کانتینر، شروع برنامه و خواندن و نوشتن داده را جدا اندازه بگیرید؛ کندی مرحلهٔ ساخت، الزاماً به معنی کندی پردازش درخواست‌ها نیست.

هشدار: فرمان podman system reset کانتینرها و تصویرهای حساب اجراکننده را پاک می‌کند. برای تغییر و مقایسهٔ درایور آن را روی حساب تولید اجرا نکنید. حساب مستقل اجازه می‌دهد تنظیمات ذخیره‌سازی را بدون دست‌زدن به مجموعهٔ کانتینرها و تصویرهای سرویس اصلی بیازمایید.

شبکه را نیز با همان الگوی مصرف بسنجید: اتصال مشتری از بیرون میزبان، ارتباط برنامه با پایگاه داده، نام‌گشایی و پورت‌های منتشرشده را بررسی کنید. اگر پاسخ‌گویی با pasta برای بارکاری شما کافی نیست، تفاوت را با درخواست‌های نماینده و در شرایط یکسان اندازه بگیرید. انتخاب شبکهٔ میزبان صرفاً برای کوتاه‌کردن مسیر ترافیک، مرز جداسازی شبکه را تغییر می‌دهد و باید به‌عنوان تصمیم امنیتی سنجیده شود.

Compose و CI را جدا از فرمان‌های تعاملی آزمایش کنید

موفقیت یک اجرای podman run به معنی سازگاری کامل فایل Compose نیست. فرمان podman compose کار را به یک ارائه‌دهندهٔ خارجی Compose می‌سپارد؛ پس نام و نسخهٔ ارائه‌دهندهٔ نصب‌شده را ثبت کنید. پیکربندی موجود را در حساب آزمایشی بالا بیاورید و شبکهٔ سرویس‌ها، volumeها، پورت‌ها، بررسی سلامت و آماده‌شدن وابستگی‌ها را با اجرای فعلی مقایسه کنید.

در CI، مسیر اتصال هر job به موتور کانتینر را مشخص کنید. فرمان محلی Podman به daemon مرکزی نیاز ندارد، اما ابزاری که از طریق Docker API کار می‌کند ممکن است به سرویس و socket سازگار Podman احتیاج داشته باشد. بررسی کنید job با کدام حساب اجرا می‌شود، چه کسی به socket دسترسی دارد و cache تصویرها و فایل‌های خروجی زیر مالکیت کدام کاربر می‌مانند.

همان pipeline را در runner آزمایشی چند بار با ورودی یکسان اجرا کنید. علاوه بر وضعیت موفقیت job، محتوای artifact، مالکیت فایل، زمان ساخت و رفتار پاک‌سازی پس از پایان کار را مقایسه کنید. اگر چند job از یک حساب یا محل ذخیره‌سازی مشترک استفاده می‌کنند، اثر این اشتراک را در طراحی آزمون لحاظ کنید.

جابه‌جایی را به معیار بازگشت گره بزنید

انتقال زمانی آماده است که برنامه با شناسه‌های مورد انتظار به داده دسترسی داشته باشد، پورت‌ها و ارتباطات لازم کار کنند، Compose و CI خروجی درست بسازند و زمان پاسخ یا ساخت در محدودهٔ پذیرفته‌شدهٔ همان سامانه بماند. این محدوده را پیش از تغییر ترافیک تعیین کنید تا نتیجهٔ آزمایش به برداشت از یک اجرای موفق وابسته نباشد.

پیکربندی قبلی Docker و نسخهٔ پشتیبان قابل‌بازیابی را نگه دارید و هنگام جابه‌جایی، نوشتن هم‌زمان دو موتور روی یک مسیر داده را متوقف کنید. اگر معیارها برآورده نشدند، سرویس آزمایشی را متوقف و ترافیک را به مسیر قبلی برگردانید. به این ترتیب، تفاوت معماری و عملکرد با بارکاری واقعی سنجیده می‌شود، در حالی که دادهٔ تولید برای آزمون دست‌کاری نشده است.

بیشتر بخوانید:

اشتراک‌گذاری:

عضویت در خبرنامه

تازه‌ترین اخبار Web3، هوش مصنوعی و رمزارز را مستقیم در صندوق ایمیل خود دریافت کنید.

0