สร้าง SOC ตั้งแต่ศูนย์: บันทึกจากสนามจริงด้วย Wazuh + IRIS-web

บันทึกกว่าสามสัปดาห์ ติดตามทุก commit จากการสร้าง Security Operations Center ด้วย Wazuh 4.x, IRIS-web และ FastAPI integrator ที่พัฒนาเอง — ทั้ง detection rules, alert pipeline, IOC enrichment และบั๊กโครงสร้างพื้นฐานที่ไม่มีใครใส่ไว้ใน architecture diagram

Stack: Wazuh 4.x · IRIS-web · soc-integrator (FastAPI) · OpenSearch · Docker Compose · VirusTotal API · AbuseIPDB

flowchart TD
  subgraph "Log Sources"
    A["Windows Agent"]
    B["FortiGate Syslog"]
    C["Simulator Scripts"]
  end

  subgraph "Wazuh"
    D["Wazuh Manager"]
    E["Decoders + Rules"]
    F["OpenSearch Indexer"]
  end

  subgraph "soc-integrator (FastAPI)"
    G["Alert Poller"]
    H["Severity Filter"]
    I["IOC Enricher"]
    J["WazuhSyslogAdapter"]
    K["Webhook Receiver"]
    L["Email Notifier"]
  end

  subgraph "External Threat Intel"
    M["VirusTotal"]
    N["AbuseIPDB"]
    O["Feodo / URLhaus / ThreatFox"]
  end

  subgraph "IRIS-web"
    P["IRIS Alerts"]
    Q["Cases + Triage"]
    R["Outbound Webhook"]
  end

  A --> D
  B --> D
  C --> D
  D --> E
  E --> F
  F --> G
  G --> H
  H --> I
  I --> M
  I --> N
  O --> I
  I --> P
  P --> Q
  Q --> R
  R --> K
  K --> L
  J --> D
  I --> J

สัปดาห์ที่ 1: จุดเริ่มต้นจากกระดาษเปล่า

ทุกโปรเจกต์ SOC เริ่มต้นเหมือนกันหมด: cursor กะพริบอยู่บนหน้าจอ กับรายการ threat scenarios ที่ต้องตรวจจับ

ของเราเริ่มจากเอกสารกำหนดงานภายใน — แบ่งเป็นสามภาคผนวก:

  • ภาคผนวก A — การโจมตี Windows และ Active Directory
  • ภาคผนวก B — เหตุการณ์เครือข่ายและ firewall (FortiGate)
  • ภาคผนวก C — Identity: impossible travel, credential abuse, lateral movement โดย admin

Commit แรกๆ ไม่ได้น่าตื่นเต้นอะไร — เพิ่ม dependency multipart, commit ไฟล์ log ตัวอย่างสำหรับทั้งสามภาคผนวก รวม 137 บรรทัดของข้อมูล firewall, authentication และ Windows event จากระบบที่ใกล้เคียง production จากนั้นก็มีไฟล์ pass.txt โผล่ขึ้นมาใน repo: โน้ตรหัสผ่านและผลลัพธ์จาก SSH session ช่วงแรก

ภายในวันที่ 16 มีนาคม milestone แรกที่แท้จริงก็มาถึง: script test-firewall-syslog.py ที่ยิง UDP syslog packet แบบ FortiGate ไปยัง port 514 ของ Wazuh ครอบคลุม 10 scenario ที่แตกต่างกัน

ปัญหา Docker NAT

flag --via-docker ถูกเพิ่มเข้ามาเกือบทันที — ในวันที่สอง ถ้าไม่มี flag นี้ ทุก packet ที่เดินทางเข้า Wazuh จะมี source IP เป็น Docker gateway แทนที่จะเป็น host จริง ทำให้การ match rule ด้วย source IP ไม่มีประโยชน์เลย flag นี้บังคับให้ packet วิ่งผ่าน host network stack เพื่อให้ Wazuh เห็น IP ต้นทางที่ถูกต้อง

ถ้ากำลังสร้าง Wazuh simulation อยู่ใน Docker แล้ว source-IP rule ไม่เคย fire — นี่คือสาเหตุ

flowchart TD
  A["test-firewall-syslog.py"]
  B{"--via-docker flag?"}
  C["Packet ออกทาง Docker NAT"]
  D["Wazuh เห็น Docker gateway IP"]
  E["Source-IP rules ไม่ match เลย"]
  F["Packet ออกทาง host network"]
  G["Wazuh เห็น host IP จริง"]
  H["Source-IP rules match ถูกต้อง"]

  A --> B
  B -- "No" --> C
  C --> D
  D --> E
  B -- "Yes" --> F
  F --> G
  G --> H

สัปดาห์ที่ 2: Rules, Decoders และกับดัก OR

Detection engineering ส่วนใหญ่คือการเขียนใหม่สิ่งที่คิดว่าถูกต้องแล้ว

วันที่ 17 มีนาคม มี commit หลั่งไหลออกมาติดป้าย progress, progress-update, rule update — กฎ simulation 59 ข้อกำลังก่อร่างขึ้นทั้งในภาคผนวก A, B และ C แต่มีบางอย่างผิดปกติ: rule A2 และ A3 fire ในเวลาที่ไม่ควร

สาเหตุที่แท้จริง: กับดัก OR ของ multi-<match>

Wazuh อนุญาตให้ใส่ tag <match> หลายอันในกฎเดียวกัน วิศวกรส่วนใหญ่ตีความว่านี่คือ AND logic แต่ใน Wazuh 4.x บาง decoder chain มันทำงานเป็น OR

กฎที่ตั้งใจให้ fire เฉพาะเมื่อมีทั้ง action=deny และ logid=13 กลับ fire บางครั้งแม้มีเพียงเงื่อนไขเดียว

<!-- ผิด: ทำงานเป็น OR ใน decoder chain บางตัว -->
<rule id="100201" level="10">
  <match>action=deny</match>
  <match>logid=13</match>
  <description>Firewall block — specific log ID</description>
</rule>

<!-- ถูก: regex เดียวบังคับใช้ AND -->
<rule id="100201" level="10">
  <regex>action=deny.*logid=13|logid=13.*action=deny</regex>
  <description>Firewall block — specific log ID</description>
</rule>

commit วันที่ 22 มีนาคมบรรยายการแก้ไขสั้นๆ ว่า:

"fix A2/A3 rule OR-trap: replace multi-<match> with single <regex> lookaheads."

หนึ่ง commit line นั้นซ่อนบ่ายวันหนึ่งที่นั่งทดสอบผ่าน wazuh-logtest ป้อน event ตัวอย่างแล้วดูกฎระเบิดใส่ input ที่ไม่ควร fire ถ้า Wazuh rule ของคุณ fire กว้างเกินไป ให้ตรวจดูว่ามี tag <match> หลายอันในกฎเดียวกันหรือไม่

flowchart TD
  subgraph "WRONG: multi-match ทำงานเป็น OR"
    A1["Incoming log event"]
    B1["match: action=deny"]
    C1["match: logid=13"]
    D1["Rule fire ถ้า match อย่างใดอย่างหนึ่ง"]
    A1 --> B1
    A1 --> C1
    B1 --> D1
    C1 --> D1
  end

  subgraph "CORRECT: single regex บังคับใช้ AND"
    A2["Incoming log event"]
    B2["regex: action=deny AND logid=13"]
    C2["Rule fire เฉพาะเมื่อ match ทั้งคู่"]
    A2 --> B2
    B2 --> C2
  end

สัปดาห์ที่ 3: เชื่อมต่อ Wazuh เข้ากับ IRIS

การที่ Wazuh rule fire แล้วเห็นผลใน log file เป็นเรื่องหนึ่ง แต่การส่งข้อมูลเข้าสู่แพลตฟอร์ม case management ที่ analyst ใช้ triage ได้จริงนั้นเป็นอีกปัญหาหนึ่งโดยสิ้นเชิง

Pipeline ของ soc-integrator

คำตอบคือ soc-integrator — FastAPI service ที่นั่งอยู่ระหว่าง Wazuh และ IRIS-web:

flowchart TD
  A["Raw Security Event"]
  B["Wazuh Manager"]
  C["Decoder Chain"]
  D["Rule Matching"]
  E["OpenSearch Indexer"]
  F["soc-integrator Poller"]
  G{"Severity >= threshold?"}
  H["ทิ้ง (noise)"]
  I["สร้าง IRIS Alert"]
  J["IRIS-web Case Queue"]

  A --> B
  B --> C
  C --> D
  D --> E
  E --> F
  F --> G
  G -- "No" --> H
  G -- "Yes" --> I
  I --> J

integrator ทำหน้าที่:

  • Poll Wazuh Indexer (OpenSearch) ทุก N วินาที
  • ส่งต่อเฉพาะ alert ที่มีความรุนแรงถึง threshold ที่กำหนด (ค่าเริ่มต้น: medium — ต่ำกว่านั้นถือเป็น noise)
  • เปิด endpoint GET/PUT ให้ analyst ปรับ threshold ได้แบบ real-time โดยไม่ต้อง restart service
  • สร้าง IRIS Alert พร้อม metadata ครบถ้วน

script ทดสอบ end-to-end 7 ขั้นตอนยืนยันการทำงานตั้งแต่ raw event จนถึง IRIS Alert ในวันที่ 23 มีนาคม

แก้ปัญหา Timezone สามจุดในวันเดียว

container ทุกตัวรัน UTC อยู่ analyst ในกรุงเทพฯ (ICT, UTC+7) มองเห็น timestamp คลาดเคลื่อนเจ็ดชั่วโมง

  • container ทั่วไป: เพิ่ม TZ=Asia/Bangkok ใน Docker Compose env block
  • base image แบบ Go/scratch: ถูกตัด timezone database ออกตั้งแต่ build time — ต้อง mount เข้ามาแบบ explicit เป็น volume
  • เพิ่มเติม: widget นาฬิกาแบบคู่ ICT/UTC ในแถบนำทางของ IRIS

analyst สังเกตเห็นทันที เรื่องเล็กน้อยแต่ส่งผลจริง


IOC Enrichment และการถอด Shuffle SOAR ออก

จนถึงวันที่ 24 มีนาคม การวิเคราะห์ threat intelligence ยังทำมือ — analyst ต้องเปิดหน้าเว็บค้นหา IP ต้องสงสัยเอง pipeline IOC ใหม่เข้ามาแทนทั้งหมด:

ค้นหาแบบ ad-hoc:

  • VirusTotal — ตรวจสอบชื่อเสียงของ IP/domain/hash
  • AbuseIPDB — ประวัติการละเมิดของ IP

ดึงข้อมูลแบบ background feed:

  • Feodo Tracker — โครงสร้างพื้นฐาน C2
  • URLhaus — URL อันตราย
  • ThreatFox — รวม IOC จากหลายแหล่ง
  • MalwareBazaar — hash ของ malware

ไฟล์ CDB list ของ Wazuh (malicious-ip, malicious-domains, malware-hashes) ถูกสร้างใหม่และ hot-reload ผ่าน Wazuh API rule ใหม่ 110600–110602 จัดการการ match แบบ inline CDB

flowchart TD
  subgraph "Ad-hoc Lookups"
    A["Suspicious IP / Domain / Hash"]
    B["VirusTotal API"]
    C["AbuseIPDB API"]
    A --> B
    A --> C
  end

  subgraph "Background Feed Ingestion"
    D["Feodo Tracker (C2 IPs)"]
    E["URLhaus (Malicious URLs)"]
    F["ThreatFox (IOC Aggregator)"]
    G["MalwareBazaar (Hashes)"]
  end

  subgraph "Wazuh CDB Hot-Reload"
    H["malicious-ip list"]
    I["malicious-domains list"]
    J["malware-hashes list"]
    K["Wazuh API reload trigger"]
    H --> K
    I --> K
    J --> K
  end

  subgraph "Detection Rules"
    L["Rule 110600: IP match"]
    M["Rule 110601: Domain match"]
    N["Rule 110602: Hash match"]
  end

  B --> H
  C --> H
  D --> H
  E --> I
  F --> H
  F --> I
  G --> J
  K --> L
  K --> M
  K --> N

Shuffle SOAR ถูกถอดออกทั้งหมด การเรียก API โดยตรงเร็วกว่า เรียบง่ายกว่า และไม่ต้องดูแล workflow platform แยกต่างหาก

ปัญหา Private IP รั่ว

ช่วงทดสอบแรก integrator ส่ง IP ในช่วง 192.168.x.x และ 10.x.x.x ไปยัง VirusTotal ทำให้ quota หมดและเกิด error 429 rate-limit จาก traffic scan ภายใน

แนวทางแก้ไข: ตรวจสอบ RFC1918 และ loopback range ก่อนเรียก API ภายนอกเสมอ อย่าลืม filter private IP ออกก่อนส่งไปยัง threat intelligence API


Disk Pressure, Dashboard ที่ไม่แสดงข้อมูล และ Sync ที่รกหูรกตา

หายนะของ logall_json

การตั้งค่า logall_json ใน Wazuh Manager ถูกเปิดไว้ระหว่างพัฒนาเพื่อ debug ในระบบ production มันเขียน archives.json วันละ 14 GB

วิธีแก้: ปิด logall_json กำหนด OpenSearch ISM policy ให้ลบ index เก่าหลัง 30 วัน เพิ่ม log rotation ระดับ OS ภายใน container

Dashboard ที่ไม่แสดงอะไรเลย

Dashboard ของภาคผนวก C ตั้งค่า filter เป็น rule.id:1005* ซึ่งเป็น rule ID ช่วงพัฒนา แต่ในระบบ production การตรวจจับจริงอยู่ในช่วง 110xxx dashboard จึงไม่คืนผลลัพธ์ใดๆ สำหรับ event จริง

วิธีแก้: เปลี่ยนจาก rule ID filtering มาเป็น rule.groups:appendix_c การ filter ด้วย group รอดพ้นจากการเปลี่ยน rule ID

Event Type ที่ไม่ตรงกันใน Sync Filter

Wazuh→IRIS sync เคย filter ด้วย field ข้อความ event_type ซึ่งไม่มีอยู่ใน Windows event จริงจาก Wazuh agent — มันเป็นแค่ artifact จากการ simulate

วิธีแก้: สร้าง filter ใหม่เป็น frozenset ของ rule ID แบบชัดเจน กำหนดได้แน่นอน ตรวจสอบได้ง่ายในการ code review


สัปดาห์ที่ 4: Webhook, Email และการปิด Loop

วันที่ 28 มีนาคมเป็นวันที่แน่นที่สุดของโปรเจกต์

Webhook Receiver ของ IRIS

เมื่อ IRIS สร้างหรืออัปเดต alert — analyst เวรจะรู้ได้อย่างไร? คำตอบคือ webhook receiver ใน soc-integrator IRIS รองรับ outbound webhook ผ่านระบบ module

flowchart TD
  A["IRIS Alert ถูกสร้างหรืออัปเดต"]
  B["IRIS outbound webhook module"]
  C["POST /iris/webhook (soc-integrator)"]
  D["Parse alert payload"]
  E["Enrich: entity name + event type"]
  F["Resolve IRIS_EXTERNAL_URL"]
  G["Format email body"]
  H["smtplib send"]
  I["กล่องเมลของ analyst เวร"]

  A --> B
  B --> C
  C --> D
  D --> E
  E --> F
  F --> G
  G --> H
  H --> I

การแจ้งเตือนทาง email ผ่านการปรับปรุงสามรอบในวันเดียว:

เวอร์ชัน สิ่งที่เปลี่ยน
v1 แจ้งเพียงว่า "มี event เข้ามา"
v2 Subject: "A1-02 Brute Force" แทน "IRIS Event"
v3 ข้อมูลครบ: Alert ID, title, case ที่เชื่อมโยง, URL ตรงสู่หน้า alert

บั๊กในการ parse comment ของ .env

IRIS_EXTERNAL_URL=http://10.0.0.5 # production host ถูก parse เป็นค่าเต็มรวม comment ด้วย: http://10.0.0.5 # production host — comment หลัง # ในบรรทัด env variable ทำให้ค่าเสียอย่างเงียบๆ

ควรลบ comment ออกก่อน parse หรือใช้ parser ที่ถูกต้องอย่าง python-dotenv ของ Python ซึ่งจัดการกรณีนี้ได้

การแยก Decoder สำหรับ Simulation และ Production

Windows event จาก Wazuh agent จริงใช้ decoder chain windows_eventchannel ส่วน event จาก simulator ที่ inject ผ่าน syslog ใช้ JSON decoder ทั้งสองเส้นทาง ทำงานแยกกันโดยสิ้นเชิง — กฎที่ต่อจาก windows_eventchannel จะไม่มีวัน fire สำหรับ event จาก simulator

flowchart TD
  A["Incoming Windows Event"]
  B{"Source type?"}
  C["Wazuh Agent จริง"]
  D["Syslog Simulator"]
  E["windows_eventchannel decoder"]
  F["JSON decoder"]
  G["Production anchor rule"]
  H["Simulation anchor rule 100270"]
  I["กฎ Production 16 ข้อของ A4"]
  J["กฎ Simulation 16 ข้อของ A4"]

  A --> B
  B -- "Agent" --> C
  B -- "Simulator" --> D
  C --> E
  D --> F
  E --> G
  F --> H
  G --> I
  H --> J

วิธีแก้: สร้าง anchor rule (100270) สำหรับเส้นทาง JSON decoder และให้กฎ simulation ทั้ง 16 ข้อของ A4 ชี้ไปที่ anchor นี้แทน

การ Format JSON ไม่ใช่แค่เรื่องสวยงาม

คำอธิบาย alert ของ Windows event แสดงผลเป็น JSON ทั้งหมดใน บรรทัดเดียว ต้องแก้สองจุด:

  1. ฝั่ง integrator: ตรวจสอบว่าเป็น JSON string แล้ว format ให้ย่อหน้า 2 space ก่อนบันทึกลง IRIS
  2. ฝั่ง frontend: tag <span> ตัดช่องว่างออก — ต้องเปลี่ยนเป็น <pre style="white-space:pre-wrap"> เพื่อให้ JSON ที่ format แล้วแสดงผลได้จริง

คำอธิบาย alert ที่แสดงเป็น JSON ย่อในบรรทัดเดียวจะถูกมองข้าม แต่ข้อมูลเดียวกันที่ย่อหน้าถูกต้องจะถูกอ่านและดำเนินการ การ format เป็นส่วนหนึ่งของ detection pipeline


สัปดาห์ที่ 5: ปิด Feedback Loop และกำจัด False Positive

ปิด Feedback Loop ของ Wazuh

การตรวจจับ C-series (C1 impossible travel, C2 credential abuse, C3 lateral movement) ทำงานได้ถูกต้องแต่เงียบเกินไป integrator ยืนยันการ match และสร้าง IRIS Alert — แต่ Wazuh เองไม่รู้เรื่องเลย

สิ่งนี้มีผลสองประการ:

  1. กฎ level 15 ใน Wazuh ควร fire เมื่อมีการโจมตียืนยันแล้ว ไม่ใช่แค่ raw event
  2. ถ้า Wazuh ไม่รู้ว่ามีการตรวจจับยืนยันแล้ว SOC dashboard จะไม่แสดงผล

วิธีแก้: WazuhSyslogAdapter — UDP sender เล็กๆ ภายใน integrator หลังจากยืนยัน C1 match integrator จะส่ง syslog event แบบ structured กลับไปยัง Wazuh:

soc_event=correlation event_type=c1_impossible_travel user="..." src_ip=...

Wazuh decode ผ่าน decoder soc-prod-integrator กด anchor rule 100260 จากนั้น fire rule 110502 ระดับ 15 (critical ยืนยันแล้ว) loop ปิดครบ dashboard แสดงผลตามความเป็นจริง

flowchart TD
  A["Login event จากสองพื้นที่"]
  B["Wazuh raw rule fire (level ต่ำ)"]
  C["OpenSearch Indexer"]
  D["soc-integrator poller"]
  E["C1 correlation logic"]
  F{"Impossible travel ยืนยันแล้ว?"}
  G["ทิ้ง"]
  H["สร้าง IRIS Alert"]
  I["WazuhSyslogAdapter"]
  J["UDP syslog กลับไปยัง Wazuh port 514"]
  K["soc-prod-integrator decoder"]
  L["Anchor rule 100260"]
  M["Rule 110502 fire (level 15 critical)"]
  N["SOC dashboard อัปเดต"]
  O["ส่ง Email แจ้งเตือน"]

  A --> B
  B --> C
  C --> D
  D --> E
  E --> F
  F -- "No" --> G
  F -- "Yes" --> H
  H --> I
  I --> J
  J --> K
  K --> L
  L --> M
  M --> N
  H --> O

บั๊ก Timezone ของการตรวจจับนอกเวลาทำงาน

ช่วงเวลา off-hours ของ C2 ถูกตั้งค่าเป็น 20:00–06:00 UTC ฟังดูสมเหตุสมผล แต่เมื่อแปลงเป็นเวลาท้องถิ่น:

  • 20:00 UTC = 03:00 ICT (กรุงเทพฯ)
  • เวลาทำการในกรุงเทพฯ เริ่ม 08:00 ICT = 01:00 UTC

กฎ fire ระหว่างช่วงเช้าของวันทำการปกติ

ช่วงเวลาที่แก้ไขแล้ว: 11:00–01:00 UTC = 18:00–08:00 ICT ควรตั้งค่า time-based detection rule ใน timezone ของ analyst ก่อน แล้วค่อยแปลงเป็น UTC

C3-03: False Positive 24 ครั้ง → 0

Rule C3-03 ตรวจจับ admin lateral movement ผ่าน RDP type-3 logon แต่มัน fire 24 ครั้งต่อวันบน FPBIADFS01

สาเหตุ: AD FS ทำ service-to-service type-3 authentication อยู่ตลอดเวลาโดยไม่มี source IP — ตรงกับ pattern ที่กฎมองหาพอดี แต่มาจาก service account ที่รู้จักว่าปลอดภัย

วิธีแก้: เพิ่มเงื่อนไขเดียว — ipAddress ต้องมีอยู่และไม่ใช่ loopback AD FS service auth ไม่มี source IP จึงถูกกรองออก ส่วน lateral movement จริงที่มาจาก remote source ยังคง trigger กฎ

flowchart TD
  A["ตรวจพบ Type-3 logon event"]
  B{"ipAddress มีอยู่และไม่ใช่ loopback?"}
  C["FPBIADFS01 service auth (ไม่มี IP)"]
  D["กฎถูก suppress — หลีกเลี่ยง false positive"]
  E["Remote admin session (มี IP จริง)"]
  F["C3-03 fire — lateral movement alert"]

  A --> B
  B -- "No" --> C
  C --> D
  B -- "Yes" --> E
  E --> F

เงื่อนไขเดียว อัตรา false positive: ศูนย์


หมายเหตุโครงสร้างพื้นฐานที่ไม่ปรากฏใน Commit Message ไหนเลย

ปัญหา inode ของ Bind-Mount บน macOS

Docker บน macOS ติดตามไฟล์ที่ bind-mount ด้วย inode เมื่อ editor สร้าง inode ใหม่ตอน save (เกิดได้กับ sed -i หรือบาง IDE) container ยังคงอ่านจาก inode เดิม อาการ: แก้ไข Wazuh rule, reload Wazuh, ทดสอบ — พฤติกรรมเดิมยังคงอยู่

วิธีแก้: รัน docker compose up --force-recreate เสมอหลังแก้ไขไฟล์ config ที่ bind-mount บน macOS บันทึกไว้ใน README ตั้งแต่วันแรก

wazuh-logtest stdin ค้าง

การ pipe ไฟล์ทดสอบ 20 บรรทัดเข้า wazuh-logtest ผ่าน docker exec -i จะค้างหลัง phase 2 ของ event สุดท้าย

วิธีแก้: เขียนลงไฟล์ชั่วคราวภายใน container แล้ว redirect จากที่นั่น หรือ wrap การเรียกด้วย timeout

ส่งไฟล์ขนาดใหญ่ผ่าน docker exec

pipe ถูกตัดที่ประมาณ 64KB บน host บางเครื่องเมื่อส่งไฟล์ขนาดใหญ่ผ่าน docker exec

วิธีแก้: encode ไฟล์เป็น base64 บน host, pipe string ที่ encode แล้วเข้า container, decode ด้วย Python ในอีกฝั่ง


สถานะปัจจุบัน

ณ วันที่ 1 เมษายน 2026

ส่วนงาน สถานะ
ภาคผนวก A — Windows/AD simulation กฎ 59 ข้อ ทุกข้อ fire end-to-end
ภาคผนวก B — Network/Firewall Production rules ทำงาน FortiGate syslog ingesting
ภาคผนวก C — Identity (C1/C2/C3) Detection + Wazuh feedback loop ปิดครบ
Wazuh → IRIS sync ทำงาน กรองด้วย severity และ rule ID
IOC enrichment VT + AbuseIPDB + 4 threat feeds, CDB hot-reload
Email notification ทุก IRIS webhook event พร้อมข้อมูล alert ครบถ้วน
False positive controls C3-03 ADFS guard, C2 timezone, logon-type filters
Log retention Wazuh 3 วัน, OpenSearch ISM policy 30 วัน

บทเรียนสำคัญ

1. Detection engineering คือการทำซ้ำ ไม่ใช่การเพิ่มเติม

commit ที่เพิ่มกฎและ commit ที่แก้ false positive มีความสำคัญเท่ากัน กฎที่ fire กับทุกอย่างแย่กว่าการไม่มีกฎเลย เพราะมันฝึกให้ analyst เพิกเฉยต่อ alert ซึ่งขัดกับเป้าหมายของ SOC ทั้งหมด

2. Feedback loop สำคัญมาก

การตรวจจับที่เข้า IRIS แต่ไม่ register กลับใน Wazuh คือครึ่งการตรวจจับ SIEM ต้องรู้ว่า correlator ยืนยันอะไร มิฉะนั้น dashboard จะโกหก และความเชื่อถือของ analyst จะพังทลาย

3. บั๊กโครงสร้างพื้นฐานเล็กๆ สะสมได้

บั๊ก timezone, การ parse comment ของ .env, การส่ง private IP ไปยัง VirusTotal — ทั้งหมดนี้ไม่ทำให้ demo พัง แต่ใน production มันสร้าง noise ต่อเนื่องที่กัดกร่อนความเชื่อถือในแพลตฟอร์ม แก้ไขแต่เนิ่นๆ ก่อนที่มันจะกลายเป็น "ปัญหาที่รู้อยู่แล้วแต่ปล่อยไว้"

4. ตรวจสอบกับดัก OR ใน Wazuh rule เสมอ

tag <match> หลายอันในกฎ Wazuh เดียวกันอาจทำงานเป็น OR ใน decoder chain บางตัว ถ้า rule fire กว้างเกินคาด ให้รวมเป็น <regex> เดียวที่บังคับใช้ AND logic อย่างชัดเจน

5. การ format ไม่ใช่แค่เรื่องความสวยงาม

คำอธิบาย alert ที่เป็น JSON บรรทัดเดียวจะถูกมองข้าม ข้อมูลเดียวกันที่ย่อหน้าถูกต้องจะถูกอ่านและดำเนินการ การ format เป็นส่วนหนึ่งของ detection pipeline


แหล่งข้อมูลที่เกี่ยวข้อง


สร้างโดย Simplico Co., Ltd. — บริษัทพัฒนาซอฟต์แวร์และผลิตภัณฑ์ในกรุงเทพฯ เชี่ยวชาญด้านระบบ AI/RAG, โซลูชัน Cybersecurity/SOC และการ integrate ระบบองค์กรสำหรับตลาดไทย ญี่ปุ่น จีน และอังกฤษ

Stack: Wazuh 4.x · IRIS-web · soc-integrator (FastAPI) · OpenSearch · Docker Compose · macOS dev environment


Get in Touch with us

Chat with Us on LINE

iiitum1984

Speak to Us or Whatsapp

(+66) 83001 0222

Related Posts

Our Products