تصویر کلی
Linux capabilities بخشی از privilegeهای root را به capabilityهای مجزا مثل CAP_NET_ADMIN یا CAP_SYS_ADMIN تقسیم میکنند.
برای فهم این موضوع بهتر است اجزا را بهعنوان یک مسیر ببینیم، نه مجموعهای از گزینههای مستقل. در Production معمولاً مشکل زمانی شکل میگیرد که تنظیم روی دیسک، وضعیت Runtime و فرض تیم درباره رفتار سیستم با هم یکی نیستند. به همین دلیل مشاهده وضعیت مؤثر، Log و Metric باید کنار Configuration بررسی شود.
اجزای اصلی و مرز مسئولیت
Process چند set مختلف capability دارد و execve، file capability و bounding set روی نتیجه نهایی اثر میگذارند.
در طراحی عملی، برای هر جزء یک سؤال روشن بنویسید: چه ورودی میگیرد، چه خروجی تولید میکند، چه Stateای نگه میدارد و در خرابی چه کسی مسئول Recovery است. این مدل ساده کمک میکند خطاهای شبکه، هویت، ذخیرهسازی یا Replication بهاشتباه به جزء دیگری نسبت داده نشوند.
خطاهای رایج
دادن capability کمتر از root مفید است ولی capabilityهای بسیار قدرتمند میتوانند سطح حمله بزرگی بسازند؛ least privilege باید با syscall و namespace هم دیده شود.
خطای دیگر، فعالکردن قابلیت پیشرفته بدون تعریف معیار موفقیت است. قبل از تغییر، 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ها، مدل ذهنی سیستم را اصلاح میکند.
مرجع
این راهنما بر پایه مستندات رسمی Linux man-pages نوشته شده و مثالهای عملی تحریریه برای آموزش دفاعی و عملیاتی هستند.
نیاز واقعی برنامه را به عملیات تبدیل کنیم
وقتی برنامه با خطای مجوز متوقف میشود، اجرای دوباره آن با root سریعترین راه تشخیص دقیق نیست. ابتدا مشخص کنید کدام عملیات رد شده است: باز کردن یک فایل، ایجاد سوکت خاص، تغییر تنظیم شبکه یا دسترسی به یک دستگاه؟ بعضی خطاها با مالکیت فایل و گروه حل میشوند و اصلاً به capability نیاز ندارند. بعضی نیز ناشی از محدودیت دیگری مانند سیاست امنیتی یا فضای نام هستند. افزودن مجموعه بزرگی از قابلیتها ممکن است نشانه را پنهان کند، بدون اینکه نیاز اصلی برنامه روشن شود.
مثال آموزشی مناسب، یک سرویس کوچک است که فقط باید روی درگاه مشخص گوش دهد. پیش از تغییر قابلیتها، تنظیمات مؤثر سیستم و روش اجرای سرویس را بررسی کنید؛ رفتار درگاههای پایین میتواند با تنظیمات محیط فرق کند. اگر نیاز به امتیاز ویژه وجود دارد، آن را به همان عملیات محدود کنید و پس از آغاز کار ببینید آیا برنامه هنوز به آن نیاز دارد یا خیر. طراحی برنامهای که امتیاز را فقط در مرحله لازم استفاده میکند، با برنامهای که همیشه مجموعه وسیعی از قدرت را نگه میدارد تفاوت مهمی دارد.
مجموعههای قابلیت، یک فهرست واحد نیستند
فرایند چند مجموعه capability دارد که در تصمیم مجوز و انتقال اختیار نقشهای متفاوتی دارند. مجموعه مؤثر برای بررسی امتیاز جاری مهم است، اما مجموعه مجاز و محدودکننده نیز بر آنچه قابل فعال شدن یا انتقال است اثر میگذارند. بنابراین دیدن یک نام در خروجی ابزار به تنهایی کافی نیست؛ باید معلوم باشد آن نام در کدام مجموعه است. هنگام بررسی یک سرویس، وضعیت همان فرایند واقعی را مشاهده کنید، نه فقط تنظیماتی را که انتظار دارید مدیر سرویس اعمال کرده باشد.
اجرای برنامه تازه نیز میتواند وضعیت قابلیتها را تغییر دهد. فایل اجرایی، هویت کاربر، تنظیمات سرویس و قواعد انتقال در این نتیجه دخیلاند. اگر یک پوسته یا اسکریپت واسط میان مدیر سرویس و برنامه قرار دارد، زنجیره اجرا را بررسی کنید. ممکن است قابلیتی که در یک مرحله دیده میشود در مرحله بعد وجود نداشته باشد. به همین دلیل آزمایش باید عملیات واقعی برنامه نهایی را بسنجد. موفقیت یک ابزار تشخیصی در همان ماشین، لزوماً به معنی داشتن اختیار یکسان توسط سرویس هدف نیست.
قابلیت روی فایل و خطر اختیار غیرمنتظره
میتوان به فایل اجرایی قابلیت نسبت داد، اما این تصمیم روی همه اجراهای مرتبط با آن فایل اثر میگذارد. پیش از چنین تغییری، مالکیت فایل و امکان جایگزینی آن را بررسی کنید. اگر کاربر غیرمجاز بتواند باینری را عوض کند یا مسیر اجرای دیگری ایجاد کند، مرز اعتماد ضعیف میشود. همچنین نصب مجدد بسته یا کپی فایل ممکن است ویژگیهای مورد انتظار را تغییر دهد. پیکربندی باید در فرایند مدیریت سیستم ثبت شود تا پس از ارتقا به یک وضعیت تصادفی وابسته نباشد.
برای آزمایش، یک باینری کوچک و اختصاصی در محیط جدا انتخاب کنید، وضعیت فایل را قبل و بعد ثبت کنید و عملیات مجاز را بررسی کنید. سپس همان فایل را از مسیر فرایند واقعی سرویس اجرا کنید. رفتار فایلسیستم، گزینههای اتصال و سیاستهای امنیتی ممکن است در نتیجه مؤثر باشند. این آزمایش نباید به اعطای قابلیت به پوسته عمومی یا مفسری که کد دلخواه اجرا میکند تبدیل شود؛ چنین انتخابی دامنه اختیار را بسیار فراتر از عملیات کوچک مورد نظر میبرد و بررسی امنیتی را دشوار میکند.
چرا CAP_SYS_ADMIN یک پاسخ عمومی نیست؟
بعضی capabilityها حوزه بسیار گستردهای از عملیات را پوشش میدهند. افزودن CAP_SYS_ADMIN برای رفع خطای نامعلوم میتواند سطح اختیار بزرگی ایجاد کند و ارزش محدودسازی را کاهش دهد. اگر یک راهنما این قابلیت را پیشنهاد میکند، بررسی کنید دقیقاً برای چه عملیات و چه نسخهای لازم بوده است. شاید برنامه جدیدتر نیاز محدودتری داشته باشد یا راهاندازی در معماری دیگری انجام شود. نام «قابلیت» نباید این تصور را بسازد که همه گزینهها کوچک و کمخطرند؛ دامنه واقعی هر مورد باید مطالعه شود.
همچنین CAP_NET_ADMIN با دسترسی صرف به یک اتصال معمول شبکه برابر نیست. برنامهای که فقط به یک API بیرونی درخواست میفرستد معمولاً نباید به بهانه «نیاز به شبکه» اختیار اداره تنظیمات شبکه بگیرد. نیاز را به فعل دقیق تبدیل کنید: اتصال، شنود، تغییر مسیر یا مدیریت رابط؟ این تفکیک در کانتینرها اهمیت بیشتری دارد، چون یک تنظیم کپیشده میتواند در صدها نمونه تکرار شود. بازبینی باید از کار مورد نیاز شروع شود و هر قابلیت اضافه دلیل قابل آزمون داشته باشد.
فضای نام، محدودیت سیستمفراخوانی و هویت
Capability تنها لایه کنترل نیست. فضای نام میتواند حوزه مشاهده و اثر را جدا کند و محدودیت سیستمفراخوانی میتواند بعضی عملیات را مستقل رد کند. سیاستهایی مانند SELinux یا AppArmor نیز نقش دارند. اگر عملی با وجود capability رد میشود، نتیجه نگیرید که باید مجموعه بیشتری اضافه کنید. گزارشهای مربوط و نوع خطا را بخوانید. در یک محیط چندلایه، ممکن است کنترل دیگری عمداً همان عمل را بسته باشد و افزودن امتیاز بیشتر هم آن را تغییر ندهد.
شناسه کاربر داخل کانتینر نیز باید در ارتباط با فضای نام کاربر و میزبان تفسیر شود. root داخل یک محیط ایزوله الزاماً همان قدرت root میزبان را ندارد، اما این جمله مجوز بیدقتی نیست. تنظیمات mount، دستگاهها، قابلیتها و مسیرهای اشتراکی میتوانند دامنه اثر را تغییر دهند. برای ارزیابی یک کانتینر، کل پیکربندی امنیتی را کنار هم ببینید. یک برچسب ساده مانند «غیر root» یا «دارای user namespace» به تنهایی درباره تمام مسیرهای دسترسی پاسخ نمیدهد.
طراحی آزمون مثبت و منفی
اگر برنامه برای انجام یک عملیات مشخص قابلیت دریافت کرده است، آزمون مثبت باید همان عملیات را با فرایند واقعی تأیید کند. آزمون منفی باید نشان دهد عملیات نامرتبط همچنان رد میشود. برای مثال، دسترسی لازم برای یک سرویس شبکه نباید به خواندن فایل محرمانه متعلق به سرویس دیگر تعبیر شود. خروجی آزمون را با هویت، مجموعه قابلیتها و پیکربندی اجرا ثبت کنید. بدون این زمینه، نتیجه پس از تغییر مدیر سرویس یا تصویر کانتینر قابل مقایسه نخواهد بود.
در مسیر سختسازی، از حذف همه قابلیتهای غیرضروری شروع کنید و تنها نیاز اثباتشده را اضافه کنید. اگر برنامه شکست خورد، یک عملیات را بررسی کنید و تغییر کوچک بدهید. افزودن چند قابلیت همزمان تشخیص نقش هرکدام را دشوار میکند. پس از موفقیت، آزمون شروع مجدد و انتشار نسخه تازه را انجام دهید. بعضی نیازها تنها در مرحله آغاز، چرخش فایل یا اتصال دوباره به دستگاه ظاهر میشوند؛ آزمایش چند ثانیه نخست برنامه تصویر کامل چرخه عمر را نشان نمیدهد.
مستندسازی اختیار برای نگهداری آینده
کنار هر capability نام برنامه، عملیات نیازمند آن و آزمون اثباتکننده را ثبت کنید. اگر مالک برنامه تغییر کرد، این یادداشت مانع حفظ بیدلیل اختیار قدیمی میشود. در بازبینی ارتقا، دوباره بررسی کنید آیا همان نیاز باقی است. ممکن است برنامه اکنون بتواند روی درگاه دیگر اجرا شود یا عملیات حساس به جزء کوچکتری منتقل شده باشد. حذف امتیاز در چنین شرایطی نتیجه تغییر معماری است، نه فقط پاک کردن یک گزینه از فایل تنظیمات.
برای حادثه نیز اطلاعات قابلیتها مفیدند. اگر فرایند رفتار غیرمنتظره دارد، دانستن اختیار مؤثر آن به برآورد دامنه اثر کمک میکند. با این حال، وضعیت فعلی ممکن است با زمان رخداد متفاوت باشد، پس نسخه پیکربندی و زمان شروع فرایند را حفظ کنید. هدف این است که بتوان توضیح داد برنامه در آن لحظه چه قدرتی داشته است. یک فهرست کلی از قابلیتهای بسته نرمافزاری بدون پیوند به نمونه اجراشده، برای چنین تحلیلی کافی نیست.