انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید

توزیع گنو/لینوکس اوبونتو ۲۰ ساله شد 🎉

نویسنده موضوع: Linux Tracing با Lttng و تحلیل با Tracecompass  (دفعات بازدید: 555 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین prbzr

  • Newbie
  • *
  • ارسال: 10
Linux Tracing با Lttng و تحلیل با Tracecompass
« : 16 خرداد 1402، 08:28 ب‌ظ »
آزمایش اول:

ایجاد فایل حاوی کدهای Lttng:

vim یک ادیتورمتنی است که با استفاده از آن می توانیم به راحتی فایل خود از نوع sh.  را ایجاد نماییم. فایل های sh. شامل یک سری دستورات مربوط به سیستم عامل های بر پایه ی لینوکس می باشد (Shell Script). یک ترمینال باز می کنیم:

sudo apt install vim ↲ دستور نصب
vim ↲ دستور اجرای ادیتور
vi experiment1.sh ↲ دستور ساخت فایل مورد نظر

حالا می توانیم کدهای مورد نظر خود را در فایل ایجاد شده وارد نماییم:



اکنون با فشردن دکمه ی ESC وارد Exit Mode شده و از طریق تایپ w: و زدن کلید ↲ فایل را ذخیره می نماییم.

توضیح کدها:

سرآیند یک فایل sh.
#!/bin/sh
ایجاد یک سشن Lttng
lttng create $1
فعال کردن رویدادهای درخواستی در آزمایش جهت ردیابی
lttng enable-event -k sched_switch,sched_waking,sched_wakeup,net_*,skb_*,irq_*
افزودن کانتکس های درخواستی در آزمایش جهت ردیابی
lttng add-context -k -t vtid -t vid -t procname
اعلان آغاز ردیابی
lttng start
۱۰ ثانیه وقفه
sleep 10
اعلان پایان ردیابی
lttng stop
بستن سشن Lttng
lttng destroy

ایجاد یک ارتباط Client-Server:

پس از آغاز عملیات ردیابی، لازم است تا یک بار کاری (Workload) ایجاد کنیم تا سپس بر اساس آن به ردیابی و تحلیل اطلاعات جمع آوری شده مبادرت نماییم.

برای این منظور ما از Netcat استفاده خواهیم کرد. Netcat ابزاری برای مانیتورینگ، تستینگ و ارسال  داده از طریق ارتباطات شبکه ای می باشد. Netcat به صورت پیش فرض با ایجاد یک ارتباط TCP به Remote Host عمل می نماید:

netcat [option] host port ↲ ایجاد یک ارتباط تی سی پی با هاست و پورت دلخواه

البته با Netcat می توان ارتباط UDP و اسکن بازه ای از پورت ها را نیز انجام داد:

netcat -u host port ↲ ایجاد یک ارتباط یو دی پی با هاست و پورت دلخواه
netcat -z -v domain.com 1-1000 ↲  اسکن بازه ی پورت از ۱ تا ۱۰۰۰  روی یک دامنه


اما Netcat فقط محدود به ارسال پکت های TCP یا UDP نیست بلکه همچنین می تواند به یک پورت برای ارتباطات و پکت ها گوش دهد؛ به این ترتیب می توان دو نمونه از Netcat را در یک ارتباط کلاینت-سروری به یکدیگر مرتبط نماییم. اینکه کدام کامپیوتر سرور و کدام کلاینت باشد، فقط در کانفیگ اولیه تصریح می گردد؛ وقتی که ارتباط برقرار شد، این ارتباط در هردو جهت مشابه خواهد بود:

netcat -l 4444 ↲ گوش دادن به ارتباطات تی سی پی روی یک پورت دلخواه

حالا روی سرور دوم می توانیم روی همان پورتی که انتخاب کرده ایم به ماشین اول متصل شویم:

netcat domain.com 4444 ↲ ارتباط با ماشین اول روی پورت مشخص شده

برای ایجاد یک ارتباط کلاینت-سروری روی یک ماشین یک ترمینال جدید باز کرده و دستور دوم را به این شکل وارد می کنیم:
netcat localhost 4444 ↲


اکنون اگر در هر طرف پیامی بنویسیم و کلید ↲ را بزنیم، پیام ما در طرف دیگر ظاهر خواهد شد. این پیام از طریق یک ارتباط TCP بین دو طرف انتقال یافته است:



و در طرف دیگر:



با فشردن دکمه های Ctrl+c ارتباط بسته خواهد شد.

اجرای کدهای Lttng:


اکنون که یاد گرفتیم چطور با استفاده از Netcat یک ارتباط کلاینت-سروی را به عنوان جریان کاری خود ایجاد نماییم، می توانیم کدهای ردیابی خود را اجرا و در مدت زمان ردیابی، یک پیام را از طریق ارتباط TCP ایجاد شده توسط Netcat منتقل نماییم.
برای اجرای کدهای فایل expriment1.sh، در ترمینال و در مسیر فولدری که حاوی فایل می باشد، ابتدا دستور زیر را وارد می کنیم:

↲ sudu su

سپس گذرواژه ی خود را وارد کرده و پس از تایید آن، دستور زیر را برای اجرای کدهای ردیابی تایپ می نماییم:

bash ./experiment1.sh exp1 ↲

توجه داشته باشید که از پیش باید Lttng را بر روی سیستم عامل خود نصب کرده باشید. اگر همه چیز درست پیش رفته باشد، پیامی مطابق تصویر زیر را خواهید دید:



همانطور که مشاهده می شود، خط به خط کدهای ما اجرا می شوند و سپس ردیابی به کار خود پایان می دهد؛ تا پیش از پایان یافتن ردیابی ما مهلت داریم تا پیامی را در ارتباط TCP که قبلا از طریق Netcat ایجاد کرده ایم منتقل نماییم.

در اطلاعات تصویر بالا، در خط سوم مسیر خروجی ردیابی ذخیره شده نشان داده شده است. این همان مسیری است که در مرحله ی بعدی برای تحلیل اطلاعات ردیابی جمع آوری شده توسط Lttng به سراغ آن خواهیم رفت.

تحلیل با استفاده از Trace Compass:


اکنون نوبت آن است که اطلاعات ردیابی ذخیره شده را مشاهده و تحلیل نماییم. برای این منظور ابزار Trace Compass را نصب و اجرا می نماییم. پس از باز شدن نرم افزار، از منوی File>Import به وارد کردن فولدری که اطلاعات ردیابی ما توسط Lttng درآن ذخیره شده است، اقدام می نماییم.

اطلاعاتی شامل مجموعه ای از نمودارها و داده های عددی پیش روی ما به نمایش در خواهند آمد:



همانطور که مشاهده می شود، تب هایی جهت نمایش منابع و جریان کنترلی و اطلاعات آماری وجود دارد. ماشین مورد آزمایش ما فقط دارای دو هسته CPU می باشد.
مستقیما به سراغ فشردن تب Control Flow از ردیف اول و تب Properties از ردیف سوم می رویم و در ردیف وسط در ستون Contents، در قسمت <srch> عبارت netcat  را تایپ می کنیم تا محتویات را بر اساس وجود netcat فیلتر نماییم و بتوانیم راحت تر فقط به بررسی جریان کاری ایجاد شده توسط Netcat بپردازیم:



اگر بروی یکی از گزینه های سورت شده در سطر وسط کلیک کنیم، به رنگ نارنجی هایلایت شده و نشانگر زمان ردیف بالا، بر اساس Timastamp رویداد انتخابی جابه جا خواهد شد. برای نمونه از موارد فیلتر شده بر اساس netcat، یکی از رویدادهای sched-wakeup را انتخاب می کنیم:



همانطور که مشاهده می شود، اطلاعات کاملی از رویداد مورد نظر در هر ردیف یه شکل های گوناگونی به نمایش در می آید. مثلا در این مورد CPU شماره ی یک به این رویداد پرداخته است. نوع رویداد sched-wakeup می باشد. Vtid و vpid این رویداد برابر با 2940 است و procname آن kworker/u8:1 می باشد. TID، Prio و PID و همچنین Timestamp  این رویداد نیز مشخص شده است.

معرفی رویدادهای CPU:

    • sched_switch: این یک رویداد مربوط به CPU می باشد که مسئولیت سوئیچ بین پردازش ها (Processe) را بر عهده دارد.
    • sched_waking: در حالی که رویدادهای sched_switch تنها زمانی منتشر می‌شوند که یک ترد در وضعیت R (Unable)  و در صف اجرای CPU در حال اجرا باشد، رویدادهای sched_waking  زمانی منتشر می‌شوند که هر رویدادی باعث تغییر وضعیت ترد شود.
    • sched_wakeup: باید توجه داشت sched_waking و sched_wakeup تقریباً اطلاعات مشابهی را ارائه می دهند. تفاوت در رویدادهای بیدار شدن در بین CPU ها است که شامل وقفه های بین پردازنده می گردد. اولی در CPU منبع (wakee) و دومی در CPU مقصد (waked) منتشر می شود. sched_waking معمولاً برای تجزیه و تحلیل تأخیر کافی است، مگر اینکه به دنبال شکستن تأخیر به دلیل سیگنال دهی بین پردازنده باشید.
 با این توضیح و نگاه به اطلاعات جمع آوری شده از ردیابی در این آزمایش، می توان دریافت که ظاهر شدن الگوی نمایش داده شده در قسمت هایلایت نارنجی تصویر زیر معمولا (و نه همیشه) اتفاق می افتد؛ در این تصویر هیچ فیلتری برای نمایش رویدادها اعمال نشده است:



 در تصویر آخری که در آزمایش اول نشان می دهیم، نگاهی به اطلاعات آماری رویدادها و نمودار Pie آن ها خواهیم داشت. همانظور که از شکل زیر بر می آید، بیشتر رویدادهای منتشر شده مربوط به رویدادهای مربوط به CPU است و سپس skbها و irqها بیشتری سهم را دارند. توجه داشته باشید که رخداد netها آنقدر اندک است که حتی در نمودار نمایان نشده اند. این مورد در مقایسه با آزمایش دوم که قرار است یک ارتباط خارجی در بستر شبکه ایجاد نماییم اهمیت می یابد:






آزمایش دوم:


در این آزمایش از همان کدهای Lttng نوشته شده در آزمایش اول برای جمع آوری داده های مربوط به ردیابی استفاده می نماییم. اما بلافاصله پس از اجرای این کدهاُ با استفاده از telnet یک درخواست GET برای دامنه ی google.com روی پورت ۸۰ ارسال خواهیم کرد. این بار بر خلاف آزمایش اول، یک ارتباط خارجی بر روی اینترنت ایجاد می کنیم تا ببینیم چه رویدادهایی بیشتر از دفعه ی قبل در این فرآیند ظاهر می شوند:

telnet [url=http://www.google.com]www.google.com[/url] 80 ↲
Trying 216.239.38.120...
Connected to [url=http://www.google.com]www.google.com[/url].
Escape character is '^]'.
GET / HTTP/1.1 ↲



پیام HTTP/1.1 200 OK به معنی ارسال موفقیت آمیز درخواست GET از سمت ما و دریافت موفقیت آمیز پاسخ از سمت google بوده است.
حالا مطابق آزمایش اول، اطلات جمع آوری شده توسط Lttng را (با توجه به مسیری که این بار در گزارش خود اعلام کرده است) در Trace Compass وارد می کنیم.
در نگاه اول آنچه توجه بر انگیز است سهم بیشتر رویدادهای مربوط به netها می باشد:



معرفی رویدادهای net:


یکی از روش های درک عملکرد توابع لینوکسی، مطالعه ی و کنکاش کدهای سیستم عامل می باشد. از آنجا که لینوکس یک سیستم عامل متن باز است، می توان کدهای آن را از مخزن آن در Github دانلود و سپس توسط یک IDE مانند VSCode بررسی نمود. برای دانلود کدهای لینوکس، پس از نصب GIT بر روی سیستم عامل خود، دستور زیر را وارد کرده تا فایل های مربوطه روی سیستم شما دانلود شوند:

git clone [url]https://github.com/torvalds/linux.git[/url] ↲

حالا VSCode  را اجرا کرده و پس از باز کردن فولدر مربوط به کدهای لینوکس در آن، رویدادهای مربوط به شبکه را جستجو می نماییم.
    • net_dev_queue: آنچه در ابتدا نظر ما را در کدهای لینوکس جلب می نماید، کدی است که به تعریف این رویداد پرداخته است:



و در موارد دیگر مشاهده می شود که این رویداد در عملکرد توابع چندی نقش دارد:




توضیحات سبزرنگ، اطلاعات مناسبی از توابع مورد نظر را در اختیار قرار داده اند. مثلا در توضیح تابع اول نوشته شده است که این تابع تمام صف های net_device را بیدار می نماید.
    • net_dev_xmit: از جستجو در کدهای لینوکس، تابع هندلر این رویداد پیدا می شود:



همانطور که از تصویر بر می آید، این تابع اطلاعاتی راجع به رویداد (نظیر name، context، cpu، time، pid و …) را به عنوان آرگومان دریافت کرده و اقداماتی را انجام می دهد. برای درک عمیق نحوه ی عملکرد توابع باید فراخوانی ها را پی در پی دنبال کنیم. مثلا اگر تایع A، تابع B و تابع B، تابع C را فرامی خواند، باید این روند بررسی و تعقیب شود. همانطور که مشاهده می شود این تعقیب از روی کدها بسیار دشوار است از این رو مطالعه ی Stack می تواند یک راه عملیاتی و مناسب برای دریافت ترتیب این فراخوانی ها محسوب شود و درک عملکرد لینوکس را میسر سازد.
 دو رویداد بالا در مجموع هر یک ۶۰ بار و رویداد net_if_receive_skb در مجموع ۵۸ بار و رویدادهای net_napi_gro_receive_entry  و net_napi_gro_receive_exit در مجموع هریک ۵۴ بار اتفاق افتاده اند.

حالا در یک بررسی دیگر، در ردیف وسط، نتایج را بر اساس telnet و رویداد net_dev_queue فیلتر می کنیم و یکی از موارد به نمایش درآمده را انتخاب کرده تا جزئیات مربوط به آن را از تب properties ردیف آخر مشاهده نماییم:



همانطور که ملاحظه می شود می توان اطلاعات جامعی راجع به پکت های ارسالی دریافت نمود. ما بر روی پورت ۸۰ یک ارتباط را از طریق telnet با google.com ایجاد کرده بودیم. این مورد در تصویر بالا مشخص شده است.
در این آزمایش، در مقایسه با آزمایش قبلی به وضوح روشن است که  رویدادهای مربوط به برقراری ارتباط در بستر اینترنت فعال شده اند و می توان از طریق اطلاعات ردیابی شده در Trace Compass مشاهده نمود.



آزمایش سوم:


این بار نیز همان کدهای Lttng استفاده شده در آزمایش اول و دوم را برای جمع آوری اطلاعات و ردیابی استفاده می نماییم اما ارتباط و بار کاری که ایجاد خواهیم کرد متفاوت خواهد بود: Ping Flood

Ping Flood چیست؟ - Ping Flood  را با Pink Floyd اشتباه نگیرید!!


یک Ping Flood، یک حمله ی DOS ساده است که در آن مهاجم، قربانی را با بسته های ICMP (echo request) (پینگ) غرق می کند. این کار با استفاده از گزینه ی flood پینگ که بسته‌های ICMP را در سریع‌ترین زمان ممکن بدون انتظار برای پاسخ ارسال می‌کند، صورت می گیرد. اکثر پیاده سازی های پینگ برای تعیین گزینه ی flood به کاربر نیاز دارند که دارای امتیاز باشد. اگر مهاجم پهنای باند بیشتری نسبت به قربانی داشته باشد (مثلاً مهاجمی با خط DSL و قربانی روی یک مودم Dial-up) این حمله بسیار موفق خواهد بود. مهاجم امیدوار است که قربانی با بسته های ICMP (echo reply) پاسخ دهد، بنابراین هم پهنای باند خروجی و هم پهنای باند ورودی را مصرف می کند. اگر سیستم هدف به اندازه ی کافی کند باشد، ممکن است تا جایی از چرخه های CPU خود استفاده کند تا کاربران متوجه کندی قابل توجهی شوند.

یک ping flood همچنین می تواند به عنوان یک تشخیص برای مسائل از دست رفتن بسته های شبکه و توان عملیاتی استفاده شود.

ایجاد Ping Flood بر روی Default Gateway به منظور آزمایش:
برای ایجاد یک Ping Flood بر روی Default Gateway IP ماشین خود، ابتدا با استفاده دستور زیر Default Gateway IP ماشین خود را پیدا می کنیم:

ip route ↲



همانطور که مشاهده می شود Default Gateway IP سیستم ما 192.168.1.1 می باشد.
ابتدا کدهای Lttng  را اجرا کرده تا ردیابی آغاز شود:



و فورا با استفاده از دستور زیر بر روی Default Gateway IP ماشین خود یک Ping Flood ایجاد می کنیم:

↲ ping -f 192.168.1.1



همانطور که مشاهده می شود، حدود ۱۰ ثانیه پس از اجرا دستور، با فشردن کلیدهای Ctrl+c انجام ping را متوقف کرده ایم و در این مدت حدود 4900 پکت منتقل شده است.

حالا با توجه به مسیر اعلام شده در گزارش Lttng، از طریق Trace Compass به سراغ اطلاعات جمع آوری شده می رویم و فولدر مربوطه را در Trace Compass وارد می کنیم.

آنچه در نگاه اول توجه بر انگیز است، درصد بالای از رویدادهای CPU است که بیش از ۸۰ درصد کل رویدادها را به خود اختصاص داده است. همانطور که پیشتر در توضیح مربوط به Ping Flood گفته شد، این نوع حمله می تواند منجر به استفاده ی بیش از حد از سیکل های پردازنده شود که به دنبال آن افت کارایی سیستم را به بار خواهد آورد. این دقیقا چیزی است که در آزمایش به وضوح مشاهده می گردد:



نکته ی دیگر اینکه در تب Histogram موجود در ردیف پایین، یک ناحیه ی متراکم توجه مان را جلب می کند. با کلیک در این ناحیه و جابه جا شدن نشانگر زمانی متوجه می شویم که انبوهی از رویدادهای مربوط به CPU به طور متوالی و مکرر منتشر شده اند:



و یک گزارش دیگر از همین لحظه:



حالا رویدادها را بر اساس محتویات ping و نوع رویداد net_dev_queue فیلتر می کنیم و توصیف مفصل یکی از موارد را در نظر می گیریم:



حالا در یک ردیابی دیگر با استفاده از Lttng، با استفاده از دستور زیر بار کاری جدیدی ایجاد می کنیم که در آن اندازه ی پکت ها در Ping Flood به مقدار 64KB تنظیم شده اند:

sudo ping -f -s 65507  192.168.1.1 ↲

نخست آنکه همانطور که از مقایسه ی تصویر بالا با تصویر زیر بر می آید، با انجام یک فیلتر مشابه و انتخاب یکی از گزینه ها می بینیم که پارامتر len از ۹۸ به ۱۵۱۴ تغییر کرده است:



همچنین این بار در گزارش آماری رویداد می بینیم که با افزایش حجم پکت ها از میزان انتشار رویدادهای CPU کاسته شده است و حدود ۲۶ درصد کل رویدادهاست:



این درصد در آزمایش قبلی ۸۰ درصد بود که به میزان قابل توجهی در این آزمایش کاسته شده است. به نظر می آید برای اینکه بتوانیم یک حمله ی موثر تر با Ping Flood داشته باشیم، بهتر است حجم پکت های خود را کوچکتر در نظر بگیریم.

توسط پوریا بازیار
زیر نظر جناب دکتر سید وحید ازهری



« آخرین ویرایش: 16 خرداد 1402، 08:45 ب‌ظ توسط prbzr »