📘 پلی‌بوک هفته اول

عادی‌سازی لاگ‌های فورتی‌گیت و طراحی کنش سریع

📖 مقدمه: شناخت Splunk و مفاهیم لاگ

Splunk یک پلتفرم جامع برای جمع‌آوری، نمایه‌سازی (Indexing) و تحلیل داده‌های ماشین (Machine Data) در مقیاس بزرگ است. برخلاف پایگاه‌های داده سنتی که نیازمند تعریف پیشینی طرح (Schema) هستند، Splunk عمدتاً از رویکرد Schema-on-the-Fly بهره می‌گیرد: بخش عمده‌ای از استخراج فیلدها هنگام جستجو (Search Time) انجام می‌شود، اگرچه برخی استخراج‌ها نیز می‌توانند در زمان ایندکس (Index Time) صورت پذیرند. این انعطاف‌پذیری باعث می‌شود Splunk برای محیط‌های چندمنبعی مانند مراکز عملیات امنیت (SOC) ابزاری ایده‌آل باشد.

خط لوله پردازش داده در Splunk از مراحل اصلی زیر تشکیل می‌شود:

  • ورودی (Input): دریافت جریان داده از Forwarderها، پورت‌های شبکه (مثلاً Syslog روی TCP/UDP)، اسکریپت‌ها یا HTTP Event Collector (HEC).
  • تجزیه (Parsing): شکستن جریان به رخدادهای منفرد، شناسایی sourcetype، استخراج زمان (Timestamp Extraction) و اعمال قوانین شکست خط (Line Breaking).
  • نوع‌بندی (Typing): اعمال قوانین استخراج فیلد از پیش تعریف‌شده (مانند transforms.conf) برای غنی‌سازی رخدادها قبل از ذخیره‌سازی.
  • نمایه‌سازی (Indexing): ذخیره‌سازی رخدادها در ساختار اختصاصی ایندکس (شامل bucketها با فایل‌های فشرده داده خام و واژه‌نامه‌های بهینه) که جستجوهای بلادرنگ را ممکن می‌سازد.
  • جستجو (Searching): بازیابی و تحلیل رخدادها با زبان SPL که قابلیت فیلتر، تجمیع، همبستگی و مصورسازی را فراهم می‌کند.

هسته جستجو در Splunk زبان خط‌لوله‌ای SPL (Search Processing Language) است که مجموعه بزرگی از دستورات را برای کاوش، تبدیل و تحلیل داده‌ها در اختیار تحلیل‌گر قرار می‌دهد. با SPL می‌توان پرسش‌های پیچیده امنیتی را در میان میلیاردها رخداد در کسری از ثانیه پاسخ داد.

اما پیش از هر تحلیلی باید لاگ (Log) را به درستی شناخت. لاگ یک رکورد خودکار از رویدادهای سیستم است که توسط سیستم‌عامل‌ها، برنامه‌ها، تجهیزات شبکه (مانند فایروال FortiGate) و سایر مؤلفه‌های دیجیتال تولید می‌شود. هر رخداد لاگ استاندارد از چند مؤلفه کلیدی تشکیل شده است:

  • Timestamp: زمان دقیق وقوع رویداد که مبنای تحلیل‌های زمانی قرار می‌گیرد.
  • Host: نام یا آدرس IP دستگاهی که رویداد را تولید کرده است.
  • Source: منبعی که رخداد از آن خوانده شده است. این منبع می‌تواند یک فایل، یک پورت شبکه (TCP/UDP)، یک جریان HEC، یا حتی یک اسکریپت سفارشی باشد.
  • Sourcetype: یک برچسب منطقی که قالب رویداد را مشخص می‌کند. این فراداده تعیین می‌کند که Splunk چگونه رویدادها را بشکند، زمان را استخراج کند و فیلدها را جدا نماید. تنظیم نادرست sourcetype باعث تحلیل‌های اشتباه یا از دست رفتن داده‌ها می‌شود.
  • _raw: محتوای اصلی رویداد به صورت متن خام، پیش از هرگونه استخراج. تمام فیلدهای بعدی از دل این متن بیرون کشیده می‌شوند.

لاگ‌ها در قالب‌های متنوعی تولید می‌شوند: Syslog (طبق استانداردهای RFC3164 یا RFC5424)، JSON، CSV، Key-Value (مانند نمونه‌های FortiGate با ساختار key=value) و XML. هر یک از این قالب‌ها روش استخراج فیلد متفاوتی می‌طلبد. اَدآن‌های (Add-ons) Splunk برای تجهیزات شناخته‌شده – از جمله FortiGate – این فرآیند را خودکار کرده و فیلدهایی مانند srcip، dstip، action، service، policyid و ... را از پیش استخراج می‌کنند.

چالش بزرگ در محیط‌های واقعی، ناهمگونی (Heterogeneity) لاگ‌هاست. یک مفهوم واحد مانند «کشور مبدأ» ممکن است در فایروال FortiGate با نام srccountry، در روتر Cisco با source_country، در یک پروکسی با country و در سرور لینوکسی دیگری با geo_src نمایش داده شود. بدون عادی‌سازی (Normalization) – از جمله تعریف Field Aliases، Calculated Fields و یکسان‌سازی sourcetype – جستجوهای امنیتی ناقص می‌مانند و مهاجمان از شکاف‌های ناشی از این آشفتگی عبور می‌کنند.

در این پلی‌بوک، با استفاده از داده‌های واقعی یک FortiGate 400F که از طریق اَدآن رسمی وارد Splunk شده، مفاهیم عادی‌سازی، Field Alias، فیلدهای محاسباتی و Workflow Actions را به صورت عملی فرا می‌گیریم. هدف نهایی آن است که تحلیل‌گر امنیتی پیش از شروع هرگونه شکار تهدید، داده‌های خود را به وضعیتی یکپارچه و آماده تحلیل برساند.

🎓 بخش اول: مباحث تدریس

۱. عادی‌سازی (Normalization)

در مراکز عملیات امنیت (SOC)، لاگ‌ها از منابع مختلف با قالب‌های متفاوت جمع‌آوری می‌شوند. عادی‌سازی یعنی یکسان‌سازی نام فیلدها، نوع مقادیر و ساختار داده‌ها تا تحلیل، جستجو و هشدارها سریع‌تر و دقیق‌تر اجرا شوند.

۲. نام‌های مستعار فیلد (Field Aliases)

تعریف: نگاشتی از چند نام مختلف فیلد به یک نام واحد.
کاربرد: در فورتی‌گیت، کشور مبدأ گاهی با country و گاهی با srccountry نمایش داده می‌شود. با تعریف Alias با نام src_country، می‌توان بدون نگرانی از نام دقیق، همه‌ی رویدادها را با یک دستور تحلیل کرد.
اهمیت: بدون Alias، کوئری stats count by country تنها بخشی از داده‌ها را پوشش می‌دهد و باعث تحلیل ناقص می‌شود.

۳. فیلدهای محاسباتی (Calculated Fields)

تعریف: فیلدی که مستقیماً در لاگ خام وجود ندارد و با استفاده از eval از روی فیلدهای موجود ساخته می‌شود.
مثال: total_bytes = sentbyte + rcvdbyte حجم کل ترافیک یک نشست را نشان می‌دهد.

۴. استخراج فیلد (Field Extraction)

تعریف: جداسازی فیلدهای معنی‌دار از متن خام رویداد (_raw).
اَدآن رسمی FortiGate برای Splunk بیشتر فیلدها را به‌طور خودکار استخراج می‌کند. درک این فرآیند برای عیب‌یابی ضروری است.

۵. تغییر نام sourcetype (Source Type Renaming)

مسئله: ممکن است لاگ‌های یک دستگاه با sourcetype اشتباه یا قدیمی (مثلاً fortigate_old) ایندکس شده باشند.
راهکار موقت: eval sourcetype = "fortigate"
راهکار دائمی: تنظیم rename در فایل props.conf.

۶. کنش‌های گردش کار (Workflow Actions)

تعریف: دکمه‌ای قابل کلیک در نتایج جستجو که روی مقدار یک فیلد (مثلاً srcip) عملی مانند باز کردن URL خارجی را انجام می‌دهد.
مثال: جستجوی Whois با کلیک روی IP.

🚨 بخش دوم: سناریوی عملی

شرح مأموریت

شما تحلیلگر تیم امنیت هستید. مدیر شما متوجه افزایش ترافیک فورتی‌گیت ۴۰۰F شده، اما گزارش‌ها ناقص است. بررسی اولیه نشان می‌دهد:

  • برخی رویدادها با sourcetype=fortigate و برخی با fortigate_old ایندکس شده‌اند.
  • کشور مبدأ گاهی country و گاهی srccountry نام دارد.
  • نیاز به محاسبه مجموع بایت‌های هر نشست و امکان Whois سریع روی IPهای مشکوک دارید.
2024-06-15 02:14:23 srcip=192.168.10.5 dstip=10.0.0.1 action=accept service=DNS srccountry="South Korea" dstcountry="United Kingdom" policyid=19 sentbyte=150 rcvdbyte=200 sourcetype=fortigate
2024-06-15 02:14:25 srcip=10.10.10.99 dstip=10.0.0.1 action=timeout service=Email_PORT_587 srccountry="Iran" dstcountry="United Kingdom" policyid=97 sentbyte=500 rcvdbyte=0 sourcetype=fortigate_old
2024-06-15 02:14:27 srcip=172.16.0.8 dstip=10.0.0.1 action=ip-conn service=IKE srccountry="China" dstcountry="United Kingdom" policyid=55 sentbyte=3000 rcvdbyte=1200 sourcetype=fortigate_old
2024-06-15 02:14:30 srcip=192.168.10.5 dstip=10.0.0.1 action=accept service=DNS srccountry="South Korea" dstcountry="United Kingdom" policyid=19 sentbyte=200 rcvdbyte=250 sourcetype=fortigate
2024-06-15 02:14:33 srcip=10.10.10.99 dstip=10.0.0.1 action=timeout service=Email_PORT_587 srccountry="Iran" dstcountry="United Kingdom" policyid=97 sentbyte=450 rcvdbyte=0 sourcetype=fortigate_old
2024-06-15 02:14:40 srcip=10.20.30.40 dstip=10.0.0.1 action=accept service=IKE srccountry="Germany" dstcountry="United Kingdom" policyid=55 sentbyte=1800 rcvdbyte=900 sourcetype=fortigate

🧭 گام‌های عملی

۱. مشاهده وضعیت فعلی
index=main sourcetype=fortigate OR sourcetype=fortigate_old
| head 20

دو sourcetype متفاوت و نام‌های ناسازگار کشور مبدأ را ببینید.

۲. یکسان‌سازی موقت sourcetype
index=main (sourcetype=fortigate OR sourcetype=fortigate_old)
| eval sourcetype = "fortigate"
۳. تعریف Field Alias برای کشور مبدأ

Settings → Fields → Field aliases → New:

  • Alias name: src_country
  • Field(s): country, srccountry

اکنون می‌توانید از src_country استفاده کنید.

۴. ساخت فیلد محاسباتی مجموع ترافیک
... | eval total_bytes = sentbyte + rcvdbyte
۵. تحلیل‌های سریع

آمار اتصالات بر اساس کشور مبدأ:

... | stats count by src_country | sort - count

پنج IP پرحجم از نظر ترافیک کل:

... | stats sum(total_bytes) as bytes_total by srcip | sort - bytes_total | head 5

توزیع وضعیت اتصال (action) برای هر کشور:

... | stats count by src_country, action
۶. راه‌اندازی Workflow Action برای Whois

Settings → Fields → Workflow actions → New:

  • Label: Whois_SrcIP
  • Action type: link
  • URI: https://who.is/whois-ip/ip-address/$srcip$
  • Apply to: sourcetype=fortigate

با کلیک روی هر IP، Whois آن در مرورگر باز می‌شود.

🎯 سه چالش ارزیابی

🕵️ چالش اول – تفسیر کوئری

کوئری زیر را گام‌به‌گام تفسیر کنید و بگویید هدف نهایی آن چیست. چرا استفاده از src_country به جای srccountry حیاتی است؟

index=main sourcetype=fortigate
| eval total_bytes = sentbyte + rcvdbyte
| stats sum(total_bytes) as bytes, dc(dstip) as unique_dest by srcip, src_country
| where bytes > 10000 AND unique_dest > 3
| sort - bytes

🛠️ چالش دوم – تغییر کوئری

مدیر از شما می‌خواهد به‌جای مجموع بایت، درصد اتصالات timeout هر IP را محاسبه کنید و فقط IPهایی را نمایش دهید که این نسبت برایشان بالای ۵۰٪ باشد و حداقل ۱۰ اتصال کل داشته باشند. کوئری چالش اول را چگونه تغییر می‌دهید؟

🧠 چالش سوم – پرسش مفهومی از تدریس

با استناد به مفهوم Field Alias توضیح دهید: اگر چندین دیوایس مختلف وجود داشته باشد که هرکدام نام کشور مبدأ را متفاوت بنویسند، چرا عدم تعریف Alias منجر به تحلیل ناقص می‌شود؟ در سناریوی بالا، اگر فقط از srccountry استفاده می‌کردیم، چه بخشی از رویدادها نادیده گرفته می‌شد؟ با یک مثال عددی توضیح دهید.