اگر در یک کلودپروایدر کار میکنید، یا سیستمی دارید که افراد زیادی قراره ازش استفاده کنند. احتمال اینکه با مشکل ترافیک غیرنرمال و اثرات ناشی از اون مواجه بشید وجود داره. به همین دلیل بهتره راهکارهایی برای جلوگیری از این ترافیک داشته باشید.
توی این مجموعه مقالات من بیشتر راهکاریهای ریاضیاتی و نرمافزاری (پیادهسازی یه سرویس خیلی ریز) برای تشخیص رو بررسی میکنم و خیلی وارد سرویسهایی که از حملات جلوگیری میکنند نمیشم.
قبل از اینکه بخوام در مورد روشهای تشخیص ترافیک غیرنرمال بگم بهتره این مفهوم رو دقیقتر تعریف کنم. بعد از اون به روشهایی برای تشخیص این پترن ترافیکی بپردازم. (البته نمیدونم کلمه غیرنرمال ترجمه خوبی برای anomaly باشه یا نه اگر نیست کلمه مناسب دیگهای به فارسی بلد نبودم=)) همینی که هست رو بپذیرید دیگه)
به طور کلی مفهوم غیرنرمال را به این شکل تعریف میکنم
غیرنرمال : "رفتارهای غیرمنتظرهای در محیط قابل مشاهده."
رفتار : "فرض کنید f یه تابع باشه، بازه دلخواه a تا b رو در نظر بگیر. مقادیر خروجی این تابع توی این بازه میشه یه بازه دیگه مثل f(a) تا f(b). این بازه دوم رفتار تابع در بازه a تا b هست"
غیرمنتطره شاید یه خورده نامفهوم به نظر بیاد به همین دلیل اون رو هم به این شکل تعریف میکنم.
رفتار غیرمنتظره : "اگر ما از تابع f انتظار داشته باشیم که تو تابع a تا b مقادیری در محدوده c تا d بهمون تحویل بده ولی یه مقدار دیگه تحویل بگیریم، رفتار تابع غیرمنظر هست"
تعریف مفهوم انتظار، یا پیشبینی موضوع بحث نیست و در مقالات بعدی در موردش صحبت میکنم
میدونم تعریف کردن همه چیز خسته کننده هست و خب شاید بگید بدیهی هست یکسری چیزها:)) ولی خب چون میخوایم به زبان ریاضی صحبت کنم نیاز بود تعریف کنم.
این رو هم بگم که این خیلی سخت نگیرید، برای خوندن این مقاله نیاز نیست ریاضیات پیشرفته رو بدونید، همین که بدونید بازه و تابع چیه کافیه. شاید در مقالات آینده که از مدلهای پیشرفتهتر صحبت میکنم بدردتون بخوره، ولی در آینده هم سعی میکنم خیلی ساده مفاهیم رو مطرح کنم
ترافیک در شبکه رو من بر اساس مجموع حجم دیتا ورودی یا خروجی به یک کامپیوتر( یا روتر یا هر دیوایس دیجیتال دیگه) در مدت زمان یک ثانیه تعریف میکنم. از حرف "یا" استفاده کردم چون ممکنه دیتا ورودی غیرنرمال تشخیص داده بشه ولی دیتا خروجی غیرنرمال نباشه. ترافیک در شبکه به صورت یکسری زمانی یا stream هست. یعنی ما در ثانیه اول یک عدد داریم، در ثانیه دوم یه عدد دیگه و ....
وقتی میخوایم ترافیک نرمال رو از غیرنرمال تشخیص بدیم معمولا یک پیشبینی از یه بازه زمانی در آینده انجام میدیم، و اگر ترافیک در اون بازه زمانی (مثلا ۳۰ ثانیه) از اون پیشبینی مال فاصله معناداری داشت میگیم ترافیک غیرنرمال هست.
بزارید visuallyتر بیان کنم، تصویر زیر رو در نظر بگیرید. محدوده قرمز و سبز محدود پیش بینی ما هست، و نقاطی که خارج از این محدود قرار گرفتن غیرنرمال هستند.
این که پیش بینی به چه شکل انجام بشه خودش مبحث پیچیدهای هست، و من در این مقاله فقط روش SMA رو معرفی میکنم. در مقالات بعدی روشهای تشخیص بیشتری رو معرفی میکنم و مشکلاتی که در این روش هست رو بیشتر بررسی میکنم.
میانگین متحرک ساده، یک روش آماری هست که برای تجزیه و تحلیل سریهای زمانی و تشخیص الگو آنها استفاده میشود. به شکل خیلی ساده اگر بخوام بگم، ما در یک بازه زمانی مشخص(مثلا ۶۰ ثانیه)، میانگین ترافیک، حد بالا، حد پایین و واریانس رو بدست میاریم. و با دادههایی که در آینده دریافت میکنیم مقایسه میکنیم.
در روش میانگین متحرک ساده، فقط میانگین رو در نظر میگیریم (در نظر گرفتن حد بالا و پایین هم میتونه برای محاسبه threshold استفاده بشه ولی موضوع بحث نیست)
با استفاده از میانگین متحرک ساده میتونیم الگوهای ترافیک غیرنرمال رو تشخیص بدیم (افت ناگهانی، افزایش ناگهانی). برای تشخیص DDoS هم با استفاده از میانگین متحرک ساده، میتوانیم میزان ترافیک ورودی به سرور یا شبکه را به طور مداوم نظارت کنیم. سپس با استفاده از میانگین متحرک ساده، مقدار میانگین ترافیک ورودی را در بازههای زمانی کوتاه (مثلاً چند دقیقه) محاسبه کنیم.
با تنظیم یک آستانه (Threshold) برای مقادیر میانگین متحرک ساده، میتوانیم تشخیص دهیم که آیا ترافیک در حال حاضر بیش از حد معمول است یا خیر. اگر مقدار ترافیک بیشتر از آستانه تعیین شده باشد، ممکن است نشونهای از حمله DDoS باشد و میتوانیم اقدامات لازم مثل مسدود کردن آدرسهای IP مشکوک یا استفاده از روشهای DDoS Protection جلو حمله رو بگیریم.
فرض کنید p سری زمانی ترافیک ورودی باشه، و Pn که n زمانی رو نشون میده، ترافیک در هر ثانیه باشه. و k دوره مد نظر برای محاسبه میانگین ترافیک در این صورت ما SMA_k رو به صورت زیر تعریف میکنیم.
مجموع تمام نقاط در بازه n تا k تقسیم بر k که تعداد نقاط هست.
کد Go پیادهسازی تابع:
برای اینکه بتونیم ترافیک غیرنرمال با آستانه مشخص رو تشخیص بدیم، من تابع زیر رو نوشتم (ساده هست)
در این مثال، تابع DetectAnomalyWithSMA سه پارامتر میگیره:اولی تکهای از مقادیر float64 (دادههای ترافیکی)، یک عدد صحیح (دوره بررسی) نشان دهنده تعداد دوره هایی برای استفاده در محاسبه میانگین متحرک، و یک مقدار float64 (آستانه) که حداکثر اختلاف مجاز بین مقدار فعلی و میانگین متحرک را نشان میدهد. این تابع مجموعهای از نقاط تشخیص ترافیک غیرنامل را برمی گردوند. این تابع ابتدا میانگین متحرک ساده داده های ورودی را با استفاده از تابع SMA() محاسبه می کند. سپس روی داده های ورودی حلقه زده و هر مقدار را با مقدار میانگین متحرک مربوطه مقایسه می کند. اگر اختلاف مطلق بین دو مقدار بیشتر از آستانه باشد، عنصر مربوطه در آرایه anomalies مقدار true میگیرد می شود.
میتونید کد کامل این پیادهسازی رو توی این repo گیتهاب ببینید
https://github.com/soroosh-tanzadeh/anomaly-detector
این مدل تشخیص کارآمد نیست، این سناریو رو فرض کنید:
بازی دربی قراره ساعت ۷ برگزار بشه، و تلوبیون هم این بازی رو پخش خواهد کرد. قطعا در ساعت پخش بازی سرورهای این وبسایت افزایش ترافیک ناگهانی رو تجربه خواهند کرد. با استفاده از روش SMA این افزایش ناگهانی حمله تشخیص داده میشه و اقدام برای جلوگیری از حمله در نظر گرفته میشه!
برای حل این مشکل، میشه چندین آستانه افزایش/کاهش ترافیک رو در نظر بگیریم
در واقع ترافیک عمده سرویسها فصلی یا seasonal هست، یک روند یکنواخت افزایش و کاهش ترافیک وجود نداره.
این روش روش تا حدی میتونی جلوی تشخیص اشتباه رو بگیره. اما باز هم روش مناسبی نیست.
میدونید دلیل مناسب نبودنش چیه؟ اگر نمیدونید بهش فکر کنید تا مقاله بعدی (تعاریف رو برای هم برای همین گفتم که برید با مفاهیم آنالیز عددی، آنالیز حقیقی و روشهای آماری بازی کنید و corner case در بیارید)