چگونه eBPF به توسعه دهندگان اجازه می دهد تا به طور ایمن قابلیت های کرنل لینوکس را برای مشاهده پذیری، ردیابی و امنیت گسترش دهند؟
eBPF چیست؟
eBPF به توسعه دهندگان اجازه می دهد تا کدهای سفارشی بنویسند که می توانند به صورت پویا در کرنل بارگذاری شوند و نحوه رفتار کرنل را تغییر دهند.
لینوکس به دلیل قابلیت شخصیسازی گسترده و تطبیقپذیری بالا، همواره گزینهای ایدهآل برای کاربران است. این سیستمعامل به کاربران اجازه میدهد تا محیط کاری خود را مطابق با نیازها و ترجیحاتشان تنظیم کنند.
برای درک کامل این مفهوم، ضروری است که ابتدا چند عنصر کلیدی را درک کنیم. بیایید آنها را یکی یکی تجزیه کنیم.
فضای کرنل در مقابل فضای کاربر
کرنل لینوکس هسته اصلی سیستم عامل لینوکس است. مانند یک پل بین سخت افزار (مانند حافظه، پردازنده و دستگاه های رایانه شما) و نرم افزار (برنامه ها و برنامه های شما) عمل می کند. منابع را مدیریت می کند و اطمینان حاصل می کند که وظایف مختلف به طور روان کار می کنند بدون اینکه با یکدیگر تداخل داشته باشند.
برنامه ها در یک لایه بدون امتیاز به نام فضای کاربر اجرا می شوند که اجازه دسترسی مستقیم به سخت افزار را ندارد. در عوض، این برنامهها با استفاده از رابطهی فراخوانی سیستم، درخواستهایی را به کرنل ارسال میکنند تا به نمایندگی از برنامه عمل کند. بیایید مثالی بزنیم که در آن روی یک فایل دوبار کلیک میکنید تا آن را باز کنید.
تعامل: روی فایل کلیک میکنید تا آن را باز کنید. برنامه (مانند یک خواننده فایل pdf) درخواستی (فراخوانی سیستم open()) را برای دسترسی به فایل به کرنل ارسال میکند. بررسی مجوز: کرنل بررسی میکند که آیا شما مجوزهای لازم (خواندن/نوشتن و غیره) برای دسترسی به فایل را دارید یا خیر. ارتباط سخت افزاری: اگر بررسی مجوز موفقیتآمیز باشد، کرنل با هارد دیسک صحبت میکند تا دادههای فایلی را که درخواست کردهاید پیدا و بازیابی کند. بارگذاری داده: کرنل دادههای فایل را در حافظه رایانه (RAM) بارگذاری میکند تا خواننده pdf بتواند به آن دسترسی پیدا کند. برنامه فایل را باز میکند: فایل در خواننده فایل شما باز میشود و میتوانید شروع به خواندن یا ویرایش آن کنید.
فضای کرنل دارای قدرتهای فوقالعاده است
از آنجایی که کرنل با بالاترین امتیازات کار میکند و کنترل کامل بر منابع سیستم دارد، مکان ایدهآلی برای کارهایی مانند:
- مشاهده پذیری سیستم
- ردیابی عملکرد تعاملات سخت افزار و نرم افزار
- عملیات شبکه بسیار قابل تنظیم
- اجرای سیاستهای امنیتی و جلوگیری از اقدامات غیرمجاز (فراخوانیهای سیستم)
با اجرای برنامهها در فضای کرنل، به مشاهدهپذیری در سطح سیستم دسترسی داریم بدون محدودیتهای برنامههای فضای کاربر.
برنامه ها در فضای کرنل
با توجه به موارد استفاده و میزان ادغام برنامه با کرنل، روشهای مختلفی برای اجرای منطق سفارشی در فضای کرنل وجود دارد. برخی از این روش ها در زیر با معرفی بسیار مختصر فهرست شده اند.
۱. ماژول های کرنل (ماژول های قابل بارگذاری کرنل یا LKM ها):
- ماژول کرنل چیست؟ یک ماژول کرنل قطعه ای از کد است که می تواند به صورت پویا در کرنل بارگذاری شود بدون نیاز به اصلاح کل کرنل یا راه اندازی مجدد سیستم. در صورت عدم نیاز می توانید آنها را تخلیه کنید.
- کاربرد : رایج برای افزودن ویژگی هایی مانند درایورهای دستگاه، سیستم های فایل یا منطق سفارشی کرنل.
- مثال: نوشتن ماژولی برای رهگیری فراخوانی های سیستم یا مدیریت درایورهای سخت افزار سفارشی.
- مزایا و معایب:
- قابل بارگذاری و تخلیه بدون نیاز به راه اندازی مجدد سیستم.
- پشتیبانی شده، ایده آل برای درایورهای دستگاه.
- نیاز به دانش کرنل دارد، می تواند باعث خرابی شود، برای سازگاری نسخه نیاز به نگهداری دارد.
۲. اصلاح کد منبع کرنل (افزودن برنامه از طریق کرنل patch):
- منظور از اصلاح چیست؟ تغییر مستقیم سورس کد کرنل برای ادغام منطق شما و ارسال آن به عنوان Patch (درخواست pull) به کرنل.
- کاربرد : اگر به یکپارچگی عمیق با کرنل نیاز دارید یا می خواهید تغییرات شما دائمی و به عنوان بخشی از کرنل رسمی لینوکس توزیع شود.
- مثال: افزودن یک فراخوانی سیستم جدید یا تغییر رفتار موجود کرنل.
- مزایا و معایب:
- کنترل کامل، ایده آل برای ادغام های عمیق، می تواند در بالادست ادغام شود.
- نیاز به کامپایل مجدد کرنل دارد، می تواند ناپایدار باشد، نگهداری سنگین، توزیع آن سخت، زمان بر، ممکن است وصله تایید نشود.
۳. استفاده از قلاب های کرنل:
- اما قلاب کرنل چیست؟ برخی از قسمت های کرنل “قلاب” یا نقاط توسعه ارائه می دهند که منطق سفارشی را می توان به آنها وصل کرد. اینها مکان های از پیش تعریف شده ای هستند که می توانید بدون تغییر خود کرنل، منطق سفارشی را در آنها قرار دهید.
- کاربرد : مناسب برای گسترش عملکرد کرنل در مناطق خاص مانند زمان بندی، پشته شبکه یا زیرسیستم های امنیتی.
- مثال: استفاده از قلاب های Netfilter برای رهگیری و تغییر ترافیک شبکه.
- مزایا و معایب:
- نقاط توسعه تمیز، در زیرسیستم های خاص پشتیبانی می شود، آزمایش شده، ایمن تر.
- محدود به در دسترس بودن قلاب، پیکربندی محدود، سوء استفاده می تواند باعث ناپایداری شود.
۴. System Tap و DTrace:
-
System Tap و DTrace چه عملکردی دارند؟ اینها ابزارهایی هستند که به درج پویای نقاط ابزار دقیق سازی در یک کرنل در حال اجرا اجازه می دهند. در حالی که به خودی خود منطقی اضافه نمی کنند، به شما امکان مشاهده و ردیابی فعالیت کرنل بدون تغییر کد کرنل را می دهند.
- کاربرد : بیشتر برای مانیتور کردن سیستم، اشکال زدایی کاربرد دارد.
- مثال: نظارت بر استفاده از CPU، تخصیص حافظه یا فعالیت I/O به صورت بلادرنگ.
- مزایا و معایب:
- ردیابی آسان رویدادهای کرنل، تأثیر کم بر عملکرد، نیازی به اصلاح کرنل نیست.
- محدود به نظارت/ردیابی، نیاز به مجوزهای بالا، نه برای منطق سفارشی کرنل و برخی محدودیت های پلتفرم.
۵. eBPF (فیلتر پکت های Berkeley توسعه یافته):
- چطور ؟ eBPF یک مکانیزم قدرتمند و ایمن برای اجرای برنامه های سندباکس شده در داخل کرنل لینوکس بدون تغییر کد منبع کرنل یا اضافه کردن ماژول است. برنامه های eBPF می توانند به صورت پویا بارگذاری شوند و از نظر ایمنی تأیید شوند.
- کاربرد : ایده آل برای مشاهده پذیری، ردیابی، شبکه و منطق امنیتی
نحوه کارکرد eBPF چگونه است ؟
- نوشتن برنامه eBPF: برنامههای eBPF توسط کاربر نوشته میشوند، معمولاً با زبان C، سپس به بایتکد eBPF کامپایل میشوند. این بایتکد قابل فهم و اجرا برای هسته است و امکان پیادهسازی عملیات مشخصی را فراهم میکند، مانند مانیتورینگ ترافیک یا کنترل دسترسی.
- بارگذاری برنامه در هسته: پس از نوشتن و کامپایل بایتکد، برنامه به هسته سیستم عامل بارگذاری میشود. برای این کار، برنامهنویس از یک سیستمکال (syscall) به نام
bpf()
استفاده میکند. این syscall برنامه eBPF را به هسته منتقل میکند. - تایید صحت (Verification): یکی از مراحل مهم در عملکرد eBPF، مرحلهی تایید صحت است که توسط یک verifier انجام میشود. این تاییدکننده، برنامه را قبل از اجرا بررسی میکند تا مطمئن شود که هیچ خطای احتمالی یا مشکل امنیتی ندارد. این مرحله بهخصوص برای جلوگیری از وقوع حلقههای بینهایت و دسترسی غیرمجاز به منابع سیستمی اهمیت دارد.
- کامپایل به کد ماشین با JIT (Just-In-Time Compilation): پس از تایید برنامه، بایتکد eBPF توسط کامپایلر JIT به کد ماشین تبدیل میشود تا با کارایی بالاتر روی پردازنده اجرا شود. این مرحله موجب میشود که برنامهها سریعتر اجرا شوند و بهینهتر عمل کنند.
- اتصال به نقاط پروب (Probes) در هسته: برنامههای eBPF میتوانند به پروبهای مختلفی در هسته متصل شوند. برای مثال، در شبکه، برنامههای eBPF به پروبهای شبکه متصل میشوند تا بستهها را دریافت کرده و تحلیل کنند. این پروبها میتوانند در نقاط مختلفی مانند socketها، تابعهای هسته، یا even tracepointها قرار داشته باشند.
- اجرای برنامه و دریافت خروجی: پس از اتصال به پروبها، برنامههای eBPF اجرا شده و نتایج را تولید میکنند. این نتایج میتوانند به شکل لاگ، اطلاعات شبکه، یا دادههای مرتبط با سیستم به کاربر منتقل شوند.
- جمعآوری و تحلیل اطلاعات: ابزارهایی مانند
bpftrace
وbcc
نتایج برنامههای eBPF را جمعآوری کرده و به کاربر نهایی نمایش میدهند. از این نتایج میتوان برای تحلیل عملکرد سیستم یا شناسایی مشکلات امنیتی استفاده کرد.
به طور خلاصه، عملکرد eBPF به این صورت است که برنامهها ابتدا در فضای کاربر نوشته میشوند، سپس به هسته بارگذاری و تایید میشوند، و در نهایت به نقاط حساس هسته متصل شده و اجرا میشوند تا اطلاعات مورد نظر را به دست آورند.
تمرکز بر eBPF:
eBPF یک گزینه شایسته است زیرا به شما امکان میدهد منطق سفارشی را به طور ایمن و کارآمد در فضای کرنل اجرا کنید، بدون نیاز به اصلاح کرنل یا بارگذاری ماژولهای سنگین. این فناوری به مرور زمان گسترش یافته است و نه تنها ردیابی شبکه، بلکه نظارت بر عملکرد سیستم، فیلتر کردن امنیتی و حتی ردیابی برنامهها را نیز پشتیبانی میکند – که آن را به یکی از متنوعترین ابزارهای عملیات سطح کرنل در امروز تبدیل کرده است. یکی از بزرگترین ویژگیهای آن، توانایی نوشتن کد به زبانهای سطح بالا مانند Go، Python و غیره است.
دانشجوی مهندسی نرم افزار و علاقه مند به دواپس 🙂