سالها داکر را روی سرور خانگیام اجرا میکردم و تقریباً همیشه بیدردسر کار میکرد. بینیازی از نوشتن sudo هم آسودگی کوچکی بود. اما وقتی تمام این پشته را به پادمنِ بیریشه منتقل کردم، ارتقای واقعی آشکار شد؛ بهبود اصلی تازهبودن پادمن نبود، بلکه حذف کنترل دائمیِ ریشه بود. همین یک تغییر، تعریف تازهای از توان بالقوهٔ یک کانتینر آلوده برای اثر گذاشتن بر میزبان به دست داد. اگر در خانه کانتینر اجرا میکنید، این مرز بخش مهمی از چشمانداز امنیتی شماست.
پشتهٔ کانتینری من یک کلید اصلی در سطح ریشه داشت
هیچوقت به sudo نیاز نداشتم؛ و دقیقاً مشکل همین آسودگی بود

بهطور پیشفرض، Dockerd با دسترسی ریشه اجرا میشود و سوکت داکر رابطی زنده برای کنترل همان فرایند ریشه است. مدت زیادی، اینکه میتوانستم فرمانهای داکر را بیآنکه sudo بنویسم اجرا کنم، نوعی پیروزی در سهولت کار میدانستم. با این حال، عضویت در گروه docker که عملاً اختیارهای سطح ریشه را در اختیارتان میگذارد، یکی از خطرهایی است که مستندات خود داکر نیز به آن هشدار میدهند.
هرچند این معماری لایهلایه از تصویرهای سادهای که معمولاً ترسیم میشوند پیچیدهتر است، سوکت داکر همچنان به یک کانتینر راه دسترسی به آن فرایند ریشه میدهد و در عمل تفاوتی ایجاد نمیکند. تا وقتی فرایندی بتواند با سوکت ارتباط بگیرد، بالقوه میتواند اختیارهای همان دیوِ ریشه را به کار گیرد. میتواند کانتینرهای دارای امتیاز بسازد، مسیرهای میزبان را سوار کند یا از راه دیو، عملیاتهایی با اختیار ریشه انجام دهد. این امکان کنترل، روی سرور خانگی من بیاستفاده مانده بود؛ سروری که ابزارهای رسانهای، همگامسازی اسناد، پراکسیهای معکوس و چند پایگاه داده را اجرا میکند.
با این همه، تصمیم من صرفاً جایگزین کردن یک موتور کانتینر با موتوری دیگر نبود، آن هم به این دلیل که یکی بهطرزی جادویی امنتر است. هدفم در عوض حذف سطح کنترل دائمیِ برخوردار از اختیار ریشه بود که به بخشی از روند کارم بدل شده بود. پادمن معماریِ بدون دیو دارد؛ بنابراین هیچ دیو مرکزیِ ریشهای میان فرمانهای من و کانتینرها قرار نمیگیرد.
ریشه درون کانتینر، ریشه روی سرور من نبود
فرمان «id» چه چیزی را دربارهٔ کارهایی که فرایند واقعاً نمیتوانست انجام دهد نشان داد

یک فرایند همچنان میتواند درون کانتینر بیریشه با اختیار ریشه، یعنی UID ۰، کار کند. با این حال، این توان از مرز کانتینر فراتر نمیرود. UID ۰ کانتینر در میزبان به بازهای از UIDهای بیامتیاز نگاشت میشود و فایلهای /etc/subuid و /etc/subgid بازههای شناسهٔ فرعیِ لازم برای این نگاشت را فراهم میکنند. هستهٔ لینوکس این جداسازی را اعمال میکند. اجرای فرمان id درون کانتینر و مشاهدهٔ همان فرایند از میزبان، ناهمخوانیای را آشکار میکند که این مرز را توضیح میدهد: درون کانتینر ریشه هستید، اما روی میزبان UID متعلق به خودتان را دارید.
یعنی هر فرایند آلودهای که خود را ریشه میپندارد، بهمحض بیرون رفتن از کانتینر از جایگاهی ضعیفتر آغاز میکند. آن فرایند هرگز روی میزبان UID ۰ نبوده است و همین موضوع، کارهایی را که پس از خروج از کانتینر میتواند انجام دهد محدود میکند. هنگام راهاندازی با چند دردسر روبهرو شدم و همانها نشان دادند که محدودیتهای امنیتی واقعیاند. بخشی از رفتارهای شبکهای که در کانتینرهای ریشهدار به آن عادت داشتم، بدون آن اختیارها کار نمیکرد. پادمن برای شبکهسازی بیریشه میتواند از ابزارهایی مانند Pasta بهره ببرد تا بدون دادن اختیار ریشه به موتور کانتینر، شبکه را فراهم کند. حالت بیریشه از اختیارهایی که الگوهای سنتی شبکهسازی را ساده میکنند، برخوردار نیست.
هنوز هم میتوانستم آن اختیار را تماموکمال پس بدهم
یک اتصال بایندِ بیاحتیاط، تمام این مرز را از میان میبرد





اجرای بیریشه بهخودیخود از همهٔ پوشههای میزبان که سوار میکنید محافظت نمیکند. پوشههایی که با یک کانتینر به اشتراک میگذارید، همچنان تابع محدودیتهای دسترسی حساب کاربری عادی شما هستند. کانتینر بالقوه میتواند فایلهای میزبان را که حساب کاربریتان از پیش به آنها دسترسی دارد، بخواند یا در آنها بنویسد.
سوار کردن یک پوشهٔ کامل با سوار کردن یک پوشهٔ اختصاصیِ دادههای برنامه تفاوت دارد. پوشهٔ اختصاصیِ دادههای برنامه، دامنهٔ دسترسی کانتینر را محدود میکند؛ اما سوار کردن پوشهای بسیار بزرگتر، به آن امکان میدهد به هر چیزی درون آن اتصال دسترسی پیدا کند که حساب کاربری شما به آن دسترسی دارد.
با این حال، هستهٔ مشترک محدودیت دشوارتری است. نگاشت فضای نام کاربر، جلوی بهرهبرداری از آسیبپذیری هسته یا گریز موفق از فضای نام را نمیگیرد. حالت بیریشه دامنهٔ یک رخنه را پس از وقوع محدود میکند، اما شاید اساساً نتواند جلوی رخ دادن آن را بگیرد.
ارتقای واقعی بیریشهبودن بود، نه پادمن
داکر چندین سال است که حالت بیریشهای عرضه میکند که فرایند پسزمینه و کانتینرها را درون فضای نام کاربر اجرا میکند. این طراحی میکوشد بیآنکه لازم باشد موتور را عوض کنید، دسترسیهای هستهای را کاهش دهد. این تفاوتی واقعی در معماری است، اما دامنهاش از آنچه شاید تصور کنید محدودتر است؛ زیرا همچنان برای هر کاربر یک فرایند پسزمینه اجرا میشود. در سوی دیگر، پادمن هیچ فرایند پسزمینهای اجرا نمیکند. کوادلت به لینوکس امکان میدهد کانتینرها را مانند سرویسهای بومی پسزمینه مدیریت کند و برای راهاندازیهای روزمرهٔ سرور خانگی، بزرگترین مزیت پادمن است. کوادلت مدیریت کانتینرها را به systemd میسپارد تا با همان ابزارهای مدیریت سرویسی که پیشتر در لینوکس به کار میبرم، آغاز شوند، از نو راه بیفتند و گزارش رویداد تولید کنند.
| داکر با دسترسی ریشه | داکر بیریشه | پادمن بیریشه | |
|---|---|---|---|
| فرایند پسزمینهٔ مرکزی با دسترسی ریشه | بله | خیر | خیر |
| کانتینرهای بیریشه | خیر | بله | بله |
| نیازمند فرایند پسزمینه | بله | بله، برای هر کاربر | خیر |
| تغییر اصلی در معماری | — | حذف دسترسیهای ریشهٔ فرایند پسزمینه | حذف دسترسیهای ریشهٔ فرایند پسزمینه و خودِ فرایند |
گذار از حالت ریشهدار به بیریشه، تغییر مهمی بود. این دگرگونی دامنهٔ آسیب را در دستگاههایی که پیوسته روشناند و حجم زیادی از دادههای شخصیام را نگه میدارند کاهش داد و پادمن ابزار تحقق این تغییر بود.
منبع: این مطلب ترجمه و بومیسازی مقالهای از MakeUseOf به قلم Afam Onyimadu است. مشاهده مقاله اصلی