معرفی
این راهنما بر پایه مستندات رسمی پروژه نوشته شده و هدف آن ساختن یک مدل ذهنی دقیق برای طراحی، عملیات و عیبیابی است.
نکته 1
directiveهایی مثل ProtectSystem، PrivateTmp، NoNewPrivileges و RestrictAddressFamilies مرز process را محدود میکنند.
نکته 2
هر service به مجموعه متفاوتی از filesystem، network و capability نیاز دارد؛ profile یکسان برای همه مناسب نیست.
نکته 3
systemd-analyze security میتواند نقطه شروع review باشد ولی جای تست functional را نمیگیرد.
برداشت عملیاتی IROSG
قبل از هر تغییر Production، نسخه، وابستگی، سطح دسترسی، rollback و observability را بررسی کنید. منبع رسمی همین صفحه مرجع اصلی جزئیات است.
محدودسازی را از نیاز واقعی سرویس شروع کنید
یک سرویس وب ساده ممکن است فقط به خواندن فایلهای برنامه، نوشتن داده در یک پوشه و اتصال به یک پایگاه داده نیاز داشته باشد. سرویس پشتیبانگیری نیاز متفاوتی دارد و شاید باید چند مسیر را بخواند و روی مقصد دیگری بنویسد. اگر یک مجموعه گزینه را برای هر دو بدون بررسی کپی کنید، یا سرویس میشکند یا دسترسی اضافی باقی میماند. پیش از تنظیم sandbox، فهرست فایلها، مسیرهای نوشتن، خانوادههای شبکه و عملیات خاص مورد نیاز را تهیه کنید. این فهرست مبنای تصمیم است.
برای شناخت نیازها، اجرای عادی کافی نیست. راهاندازی اولیه، چرخش لاگ، بارگذاری گواهی تازه، ساخت فایل موقت و بازیابی پس از خطا نیز ممکن است مسیرهای دیگری استفاده کنند. یک سرویس که در اولین درخواست کار میکند، ممکن است شب هنگام اجرای کار دورهای شکست بخورد. بنابراین دوره آزمایش باید شامل این رویدادها باشد. اگر برنامه مستندات مسیر داده دارد، آن را با مشاهده محیط واقعی مقایسه کنید و تفاوتها را ثبت کنید.
حساب اجرا نخستین مرز است
اجرای سرویس با حساب اختصاصی غیرریشه، دامنه دسترسی معمول آن را محدود میکند. این حساب نباید بیدلیل مالک فایل اجرایی یا تنظیماتی باشد که مدیر باید کنترل کند. اگر برنامه بتواند کد خودش را بازنویسی کند، یک خطای برنامه میتواند به ماندگاری تغییر ناخواسته منجر شود. در طراحی مسیرها، فایل اجرایی، تنظیمات و داده متغیر را جدا نگه دارید. فقط مسیرهای لازم برای داده برنامه باید قابل نوشتن باشند. این تفکیک با گزینههای sandbox همکاری میکند و جایگزین آنها نیست.
گروههای تکمیلی حساب را نیز بررسی کنید. عضویت در یک گروه مدیریتی یا دسترسی به سوکت حساس میتواند اختیاری فراتر از چیزی بدهد که نام کاربر نشان میدهد. برای آزمون، عملیات ضروری را با همان هویت اجرا انجام دهید و دسترسیهای غیرضروری را نیز امتحان کنید. تست از پوسته ریشه نتیجه معتبری درباره سرویس محدود نمیدهد. اگر برای عیبیابی از حساب قویتر استفاده میکنید، تفاوت محیط را صریح در گزارش بنویسید.
ProtectSystem و مسیرهای نوشتن
ProtectSystem برای محدود کردن نوشتن در بخشهایی از فایلسیستم در محیط سرویس به کار میرود و حالتهای مختلف آن دامنه متفاوت دارند. انتخاب حالت باید با مستندات نسخه نصبشده تطبیق داده شود. اگر برنامه پس از فعال شدن خطای نوشتن میدهد، نخست مسیر دقیق را پیدا کنید. باز کردن کل فایلسیستم برای حل یک فایل موقت کوچک، هدف محدودسازی را از بین میبرد. معمولاً باید مسیر داده برنامه روشن و استثنا فقط برای همان نیاز تعریف شود.
در تمرین، برنامهای بسازید که یک فایل ساختگی را در پوشه داده خود بنویسد و تلاش دیگری برای نوشتن در مسیر غیرمجاز داشته باشد. عملیات اول باید موفق و دومی باید ناموفق باشد. فقط بالا آمدن سرویس را بررسی نکنید. همچنین مالکیت و مجوز مسیر مجاز باید درست باشد؛ قابل نوشتن شدن mount در sandbox به خودی خود همه مجوزهای معمول فایل را دور نمیزند. این دو لایه را جدا مشاهده کنید تا خطای مجوز با محدودیت mount اشتباه نشود.
PrivateTmp و وابستگیهای پنهان
PrivateTmp نمای جداگانهای از مسیرهای موقت برای سرویس فراهم میکند. این ویژگی میتواند تداخل و دسترسی ناخواسته میان سرویسها را کاهش دهد، اما برنامههایی که از فایل موقت مشترک برای ارتباط استفاده میکنند ممکن است رفتار متفاوتی بگیرند. اگر دو سرویس قرار است دادهای را به اشتراک بگذارند، یک مسیر صریح با مالکیت و چرخه عمر روشن معمولاً از اتکا به فایل تصادفی در tmp قابل فهمتر است. پیش از فعال کردن، این وابستگیها را پیدا کنید.
برای آزمایش، یک فایل موقت با نام مشخص از داخل سرویس ایجاد کنید و مشاهده آن را از محیط دیگر مقایسه کنید. سپس پاکسازی و راهاندازی دوباره را بسنجید. دادهای که باید پس از restart باقی بماند نباید صرفاً در مسیر موقت نگهداری شود. اگر برنامه از فایل موقت برای cache استفاده میکند، از دست رفتن آن باید قابل تحمل باشد. این تمرین کمک میکند داده پایدار، داده قابل بازسازی و فایل گذرا در طراحی برنامه از هم جدا شوند.
NoNewPrivileges و مرز افزایش اختیار
NoNewPrivileges محدودیتی بر بهدست آوردن اختیار تازه از مسیرهای مشخص اجرای برنامه ایجاد میکند. این گزینه را با حذف همه اختیارهای موجود اشتباه نگیرید؛ اگر فرایند از ابتدا دسترسی گسترده داشته باشد، باید آن دسترسی جدا بررسی شود. همچنین برنامههایی که به اجرای کمکی با افزایش اختیار وابستهاند ممکن است نیاز به بازطراحی یا استثنای مستند داشته باشند. نخست بفهمید برنامه چرا آن عملیات را انجام میدهد و آیا میتوان بخش حساس را از سرویس اصلی جدا کرد.
در سناریوی آموزشی، یک سرویس معمولی بدون نیاز به ابزارهای دارای امتیاز ویژه انتخاب کنید. پس از فعال کردن محدودیت، مسیرهای عادی و عملیات مدیریتی مورد انتظار را بسنجید. اگر چیزی شکست خورد، پیام خطا و برنامه کمکی را ثبت کنید. خاموش کردن گزینه بدون شناخت وابستگی فقط وضعیت قبلی را برمیگرداند و دانشی ایجاد نمیکند. هدف این است که مرز اختیار برنامه روشن شود و هر نیاز استثنایی دلیل مشخص داشته باشد.
Capability و خانوادههای آدرس
Capabilityها برخی اختیارهای ویژه هسته را به بخشهای کوچکتر تقسیم میکنند. فهرست مجاز باید از عملیات واقعی سرویس استخراج شود. اضافه کردن مجموعهای بزرگ به دلیل یک خطای مبهم، محدودسازی را بیاثر میکند. برای نمونه، نیاز به درگاه خاص، تغییر تنظیمات شبکه و دسترسی خام به دستگاه سه نیاز متفاوتاند. قبل از افزودن اختیار، بررسی کنید آیا معماری سرویس یا روش ارائه درگاه میتواند نیاز به آن را کاهش دهد. کمترین اختیار باید نتیجه تحلیل باشد، نه فقط یک شعار در فایل تنظیمات.
RestrictAddressFamilies به خانوادههای سوکت مربوط است و با فهرست مجاز مقصدهای شبکه یکی نیست. اجازه یک خانواده به معنی اجازه فقط یک سرور نیست و محدود کردن آن نیز جای فایروال یا سیاست شبکه را نمیگیرد. برنامه ممکن است برای ارتباط محلی به سوکت یونیکس نیاز داشته باشد حتی اگر وظیفه اصلیاش وب باشد. در آزمایش، DNS، اتصال پایگاه داده و ارتباط محلی را جدا بسنجید. حذف یک خانواده بدون شناخت وابستگی میتواند خطاهایی ایجاد کند که ظاهراً به نامحلکنی یا کتابخانه مربوطاند.
محدودیتهای نسخه و محیط اجرا
همه گزینهها در همه نسخهها یا محیطها رفتار یکسان ندارند. برخی قابلیتها به پشتیبانی هسته، نوع سرویس یا امکان ساخت فضای نام وابستهاند. مستندات آنلاین آخرین نسخه را با نسخه نصبشده اشتباه نگیرید. وضعیت unit و پیامهای مدیر سرویس را بررسی کنید تا گزینه ناشناخته یا اعمالنشده نادیده نماند. محیط کاربری و محیط سیستمی نیز ممکن است محدودیت متفاوت داشته باشند. نتیجه آزمایش روی ماشین کامل را به کانتینر یا سرویس کاربری بدون بررسی تعمیم ندهید.
ابزار systemd-analyze security برای مرور تنظیمات مفید است، اما امتیاز آن حکم قطعی امنیت برنامه نیست. یک سرویس میتواند امتیاز بهتر بگیرد ولی کار اصلیاش را انجام ندهد، یا به دلیل نیاز مشروع امتیاز متفاوتی داشته باشد. از گزارش برای پیدا کردن سؤالهای باز استفاده کنید: چرا این مسیر قابل نوشتن است، چرا این capability لازم است و چه جایگزینی وجود دارد؟ سپس پاسخ را با آزمون و معماری برنامه بسنجید. هدف گرفتن یک عدد زیبا به قیمت از کار افتادن خدمت نیست.
انتشار تغییر با آزمون مثبت و منفی
تغییرها را در یک drop-in قابل شناسایی نگه دارید و نسخه قبلی را داشته باشید. ابتدا روی نمونه آزمایشی اجرا کنید و هر گروه محدودیت را جدا اضافه کنید. پس از هر مرحله، وضعیت سرویس، پاسخ برنامه و لاگ خطا را ببینید. اگر چندین محدودیت را همزمان فعال کنید، یافتن علت شکست دشوارتر میشود. در عین حال آزمون منفی لازم است تا نشان دهد محدودیت واقعاً اعمال شده است؛ صرف نبود خطا در برنامه هیچ چیز درباره بسته بودن مسیر غیرضروری ثابت نمیکند.
یک مجموعه پذیرش مناسب میتواند شامل شروع سرویس، نوشتن داده مجاز، رد نوشتن در مسیر ممنوع، اتصال مجاز و اجرای کار دورهای باشد. پس از restart و پس از بهروزرسانی برنامه نیز آن را تکرار کنید. نسخه جدید برنامه ممکن است مسیر تازهای برای cache یا فایل موقت بخواهد. این نیاز باید بازبینی شود، نه اینکه به صورت خودکار همه محدودیتها حذف شوند. ثبت دلیل استثنا در کنار تنظیم، تصمیم آینده را آسانتر میکند.
مرز دفاع و نگهداری بلندمدت
Sandboxing اثر بعضی خطاها یا سوءاستفادهها را محدود میکند، اما جای وصله برنامه، اعتبارسنجی ورودی و مدیریت راز را نمیگیرد. اگر سرویس مجاز است پایگاه داده را بخواند، محدودیت فایلسیستم به تنهایی مانع سوءاستفاده از همان دسترسی نمیشود. رازهای برنامه باید با دامنه مناسب و چرخه تعویض روشن مدیریت شوند. همچنین محدودیت منابع مانند حافظه و پردازنده موضوع مکملی است که باید بر اساس نیاز خدمت تنظیم شود. مرزهای مختلف با هم دفاع ایجاد میکنند و هیچ گزینه منفردی همه مسئله را حل نمیکند.
در مرور دورهای، استثناهای قدیمی را با نسخه فعلی برنامه مقایسه کنید. ممکن است مسیری که قبلاً لازم بوده دیگر استفاده نشود. حذف کنترلشده آن همراه با آزمون، سطح دسترسی را کوچکتر میکند. نتیجه هر تغییر را به زبان عملیاتی ثبت کنید: چه عملی مجاز ماند، چه عملی بسته شد و کدام آزمون شاهد آن است. چنین مستندی برای تیم نگهداری از فهرست طولانی directiveها مفیدتر است و به همکار بعدی امکان میدهد تصمیم را با دلیل ادامه دهد.