Wazuh Decoders & Rules: โมเดลความเข้าใจที่หายไป

คู่มือฉบับสมบูรณ์สำหรับมือใหม่ — อธิบายว่า Wazuh decoders และ rules ทำงานร่วมกันอย่างไร, field คืออะไร, มาจากไหน, เมื่อไหรต้องใช้ decoder และ log กลายเป็น alert ได้อย่างไร

Tags: Wazuh · OSSEC · SIEM · Blue Team · Detection Engineering
ระดับ: มือใหม่ → ระดับกลาง | เวลาอ่าน: 15 นาที


ถ้าคุณเคยมองไฟล์ Wazuh rule แล้วถามตัวเองว่า:

  • "field นี้มาจากไหนกันแน่ — จาก rule, decoder หรือ log ตัวเอง?"
  • "จำเป็นต้องมี decoder ไหมถึงจะให้ rule ทำงานได้?"
  • "ทำไม rule <field> ของฉันถึงไม่ยิง ทั้งๆ ที่เห็น string อยู่ใน log ชัดๆ?"

…คุณไม่ได้อยู่คนเดียว นี่คือคำถามที่คนส่วนใหญ่เจอตอนเริ่มเขียน Wazuh rules บทความนี้จะตอบทุกข้อ ทีละขั้น พร้อม diagram ทุกช่วง


1. ภาพรวม: Wazuh ประมวลผล Log อย่างไร

ก่อนที่ rule จะถูกประเมินแม้แต่ข้อเดียว Wazuh จะส่ง log ที่เข้ามาทุกรายการผ่าน pipeline สองขั้นตอน:

flowchart LR
    A(["📄 Raw Log"]) --> B["Decoder Stage\nextract named fields"]
    B --> C["Rules Engine\nmatch conditions"]
    C --> D(["🚨 Alert or No Alert"])

    style A fill:#1a1f2e,stroke:#5b8fff,color:#c8cdd8
    style B fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8
    style C fill:#2a1f10,stroke:#ff6b35,color:#c8cdd8
    style D fill:#0d2e1a,stroke:#00e5a0,color:#00e5a0

ขั้นที่ 1 — Decoder: รับ raw log string และดึง field ที่มีชื่อออกมาเป็นโครงสร้าง ขั้นตอนนี้ไม่บังคับ — ถ้าไม่มี decoder ตรงกับ log นั้น log จะผ่านไปเป็น plain string ตามเดิม

ขั้นที่ 2 — Rules Engine: ประเมิน log (และ field ที่ decode แล้ว) กับ rules ของคุณ ขั้นตอนนี้ทำงานเสมอ ไม่ว่าจะมี decoder หรือไม่

สิ่งสำคัญที่ต้องจำ: rules engine จะเห็นอะไรนั้น ขึ้นอยู่กับว่า decoder ทำงานก่อนหรือเปล่า


2. "Field" ใน Wazuh คืออะไร?

field คือข้อมูลที่มีชื่อ ซึ่งถูกดึงออกจาก raw log โดย decoder

ลองดู raw SSH log นี้:

Jan 10 12:00:00 webserver sshd[1234]: Failed password for root from 203.0.113.5 port 22

Wazuh มี SSH decoder ในตัวที่อ่านบรรทัดนั้นและดึงข้อมูลออกมา:

srcip  = 203.0.113.5
user   = root
action = Failed password

ข้อมูลเหล่านี้กลายเป็น named fields ที่ rules สามารถ match ได้อย่างแม่นยำ แทนที่จะต้องสแกน raw string ทั้งบรรทัด

ถ้าไม่มี decoder, rules engine จะเห็นแค่ raw log text เท่านั้น แต่ถ้ามี decoder, มันจะเห็นทั้ง raw text และ field ที่ดึงออกมาด้วย


3. Rules และ Decoders เชื่อมกันอย่างไร

นี่คือจุดที่คนส่วนใหญ่สับสน มี rule tags หลายตัว และแต่ละตัวทำงานต่างกันมากขึ้นอยู่กับว่า decoder ทำงานหรือไม่:

Rule Tag ต้องการ Decoder? จับ match อะไร
<match> ❌ ไม่ต้อง ค้นหา substring ใน raw log line
<field name="x"> ✅ ต้อง ค่าของ field ที่ decoder ดึงออกมา
<decoded_as> ✅ ต้อง ตรวจว่า decoder ที่ระบุประมวลผล log นี้หรือไม่
<if_sid> ❌ ไม่ต้อง ตรวจว่า parent rule เคย fire ก่อนหน้าหรือไม่ (chaining)
<same_field> ✅ ต้อง เชื่อม field ระหว่างหลาย event
<list field="x"> ✅ ต้อง ค้นหาใน CDB / threat-intel list
flowchart TD
    A(["Raw Log"]) --> B{"Did a decoder\nrun on this log?"}

    B -- "No" --> C["Only raw string\navailable to rules"]
    B -- "Yes" --> D["Named fields\navailable to rules"]

    C --> E["match ✅\nif_sid ✅\nfield ❌\ndecoded_as ❌"]
    D --> F["match ✅\nif_sid ✅\nfield ✅\ndecoded_as ✅"]

    style A fill:#1a1f2e,stroke:#5b8fff,color:#c8cdd8
    style B fill:#2a1f10,stroke:#ff6b35,color:#ff6b35
    style C fill:#2e0d0d,stroke:#ff4444,color:#c8cdd8
    style D fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8
    style E fill:#2e0d0d,stroke:#ff4444,color:#c8cdd8
    style F fill:#0d2e1a,stroke:#00e5a0,color:#c8cdd8

<match> ทำงานได้เสมอเพราะเป็นแค่การค้นหา substring ใน raw log — ไม่สนใจว่า decoder ทำงานหรือเปล่า <field> จะทำงานได้ก็ต่อเมื่อ decoder ดึง field นั้นออกมาแล้วเท่านั้น


4. โครงสร้าง Wazuh Decoder: name, prematch, regex, order

มาสร้าง decoder ตั้งแต่ต้นและอธิบายทุก tag สมมติว่าแอปของคุณเขียน log แบบนี้:

2024-01-10 12:00:00 app=myapp action=login user=alice srcip=203.0.113.5 status=failed

นี่คือ decoder ที่ดึง field ที่ต้องการ:

<decoder name="myapp">
  <prematch>app=myapp</prematch>
  <regex>action=(\w+) user=(\w+) srcip=(\d+\.\d+\.\d+\.\d+) status=(\w+)</regex>
  <order>action, user, srcip, status</order>
</decoder>
flowchart LR
    A(["Raw Log\napp=myapp action=login user=alice ..."])
    A --> B{"prematch\napp=myapp found?"}
    B -- "No" --> C(["Skip this decoder"])
    B -- "Yes" --> D["Run regex\nextract capture groups"]
    D --> E["Map via order\ngroup 1 to action\ngroup 2 to user\ngroup 3 to srcip\ngroup 4 to status"]
    E --> F(["Fields ready\naction=login\nuser=alice\nsrcip=203.0.113.5\nstatus=failed"])

    style A fill:#1a1f2e,stroke:#5b8fff,color:#c8cdd8
    style B fill:#2a1f10,stroke:#ff6b35,color:#ff6b35
    style C fill:#2e0d0d,stroke:#ff4444,color:#888
    style D fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8
    style E fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8
    style F fill:#0d2e1a,stroke:#00e5a0,color:#00e5a0

name="myapp"

ชื่อ label ของ decoder นี้ Rules สามารถอ้างอิงได้ด้วย <decoded_as>myapp</decoded_as> เพื่อให้ fire เฉพาะ log ที่ decoder นี้ประมวลผลแล้ว

<prematch> — ตัวกรองด่วนก่อน regex

ก่อนรัน regex ที่หนัก Wazuh จะตรวจก่อนว่า: string นี้มีอยู่ใน log ไหม? ถ้าไม่มี decoder จะถูกข้ามทันที นี่คือ การ optimize ประสิทธิภาพ — regex นั้น cost สูง แต่ prematch cost ต่ำ ควรใส่ไว้เสมอ

Log: "2024-01-10 app=myapp action=login user=alice ..."
                  ^^^^^^^^
              prematch พบ "app=myapp" → ไปต่อที่ regex

Log: "Jan 10 kernel: eth0 link up"
              ไม่พบ "app=myapp" → ข้าม decoder ทั้งหมด

<regex> — capture groups ดึงค่า

วงเล็บ () แต่ละคู่คือ capture group ค่าที่ regex จับได้ข้างในจะกลายเป็นค่าของ field

action=(\w+)
        └──┘  group 1 — จับอักขระ word ตั้งแต่ 1 ตัวขึ้นไป
              Input:  action=login
              Result: login  → group 1

user=(\w+)
      └──┘  group 2
              Input:  user=alice
              Result: alice  → group 2

srcip=(\d+\.\d+\.\d+\.\d+)
       └─────────────────┘  group 3 — pattern IP address
              Input:  srcip=203.0.113.5
              Result: 203.0.113.5  → group 3

status=(\w+)
        └──┘  group 4
              Input:  status=failed
              Result: failed  → group 4

<order> — ตั้งชื่อ capture groups

<order>action, user, srcip, status</order>

นี่คือการ map: group 1 → action, group 2 → user, group 3 → srcip, group 4 → status

⚠️ กฎสำคัญ: จำนวนชื่อใน <order> ต้อง ตรงกันพอดี กับจำนวน () groups ใน <regex> สี่ groups → สี่ชื่อ ถ้าไม่ตรง decoder จะ fail โดยไม่มีการแจ้งเตือน


5. ข้อผิดพลาดที่พบบ่อย: <prematch> ไม่ได้ดึง Field ออกมา

นี่คือความเข้าใจผิดที่พบบ่อยที่สุดในหมู่คนที่เพิ่งเริ่มใช้ Wazuh

Q: <prematch> ตรวจหา app=myapp — แปลว่า app กลายเป็น field ที่ใช้ใน rules ได้ไหม?

ไม่. <prematch> เป็นแค่ตัวกรอง มันตรวจว่า string มีอยู่ใน log หรือไม่ เพื่อตัดสินใจว่าจะทำงานต่อหรือหยุด มันไม่ดึงอะไรออกมาเลย

flowchart TD
    A["prematch: app=myapp"] --> B["Filter only ❌\napp NOT a field\ncannot use in rules"]
    C["regex: app=group1 user=group2\norder: app, user"] --> D["app = myapp ✅\nuser = alice ✅\nboth usable in rules"]

    style A fill:#2a1f10,stroke:#ff6b35,color:#c8cdd8
    style B fill:#2e0d0d,stroke:#ff4444,color:#c8cdd8
    style C fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8
    style D fill:#0d2e1a,stroke:#00e5a0,color:#c8cdd8

Field จะมาจาก <regex> capture groups ที่ map ผ่าน <order> เท่านั้น ถ้าอยากให้ app เป็น field ที่ใช้งานได้ ต้องจับมันใน regex:

<!-- app ไม่ใช่ field — ใช้แค่เป็น pre-filter -->
<prematch>app=myapp</prematch>
<regex>action=(\w+) user=(\w+)</regex>
<order>action, user</order>

<!-- app เป็น field — จับใน regex แล้ว -->
<prematch>app=</prematch>
<regex>app=(\w+) action=(\w+) user=(\w+)</regex>
<order>app, action, user</order>

6. Flow ทั้งหมด: Raw Log → Decoder → Rule Chain → Alert

มาติดตามตัวอย่างที่เป็นจริงตั้งแต่ต้นจนจบ ผู้ใช้ login ผิดสามครั้ง — เราต้องการ detect สิ่งนี้ด้วย rule chain

Raw log:

2024-01-10 12:00:00 app=myapp action=login user=alice srcip=203.0.113.5 status=failed
flowchart TD
    A(["Raw Log - app=myapp action=login user=alice status=failed"])
    A --> B{"prematch - app=myapp found?"}

    B -- "No" --> C(["No decoder runs - log stays as raw string"])
    B -- "Yes" --> D["Regex extracts: action=login, user=alice, srcip=203.0.113.5, status=failed"]

    C --> F
    D --> F

    F(["Rules Engine"])
    F --> G

    G{"Rule 1000 - match: app=myapp"}
    G -- "string not found" --> Z(["No Alert"])
    G -- "string found" --> H

    H{"Rule 1001 - if_sid: 1000 - field: status=failed"}
    H -- "field missing - no decoder ran" --> Z
    H -- "field exists" --> I

    I{"Rule 1002 - if_sid: 1001 - same_field: user - frequency 3 in 60s"}
    I -- "not yet 3 times" --> Z
    I -- "3 failures same user" --> J

    J(["ALERT level 10 - Brute force: alice failed 3 times"])

    style A fill:#1a1f2e,stroke:#5b8fff,color:#c8cdd8
    style B fill:#2a1f10,stroke:#ff6b35,color:#ff6b35
    style C fill:#1a1f2e,stroke:#444,color:#888
    style D fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8
    style F fill:#1a1f2e,stroke:#5b8fff,color:#c8cdd8
    style G fill:#2a1f10,stroke:#ff6b35,color:#c8cdd8
    style H fill:#2a1f10,stroke:#ff6b35,color:#c8cdd8
    style I fill:#2a1f10,stroke:#ff6b35,color:#c8cdd8
    style J fill:#0d2e1a,stroke:#00e5a0,color:#00e5a0
    style Z fill:#2e0d0d,stroke:#ff4444,color:#ff4444

สังเกตที่ Rule 1001: ถ้าไม่มี decoder ทำงาน field status จะไม่ถูกดึงออกมา การตรวจ <field name="status"> จะ fail อย่างเงียบๆ — แม้ว่า raw log จะมี status=failed อยู่ชัดๆ นี่คือสาเหตุที่พบบ่อยที่สุดที่ทำให้ rules ดูเหมือนไม่ทำงาน


7. จะเกิดอะไรขึ้นถ้าไม่มี Decoder?

Rules ของคุณจะยังทำงานได้บางส่วน — แต่เฉพาะ tag ที่ไม่ต้องการ field ที่ดึงออกมาเท่านั้น

Rule Tag ไม่มี Decoder เหตุผล
<match>app=myapp</match> ✅ ทำงานได้ ค้นหา substring ใน raw string ไม่ต้องการ field
<if_sid>1000</if_sid> ✅ ทำงานได้ Rule chaining ไม่ต้องการ field
<field name="status">failed</field> ❌ Fail เงียบๆ Field status ไม่ถูกดึงออกมา
<same_field>user</same_field> ❌ Fail เงียบๆ Field user ไม่ถูกดึงออกมา
<list field="srcip">blocklist</list> ❌ Fail เงียบๆ Field srcip ไม่ถูกดึงออกมา
flowchart LR
    A(["No Decoder"]) --> B["match\nraw string search"]
    A --> C["if_sid\nrule chaining"]
    A --> D["field\nextracted field"]
    A --> E["same_field\nfield correlation"]

    B --> F(["✅ Always works"])
    C --> G(["✅ Always works"])
    D --> H(["❌ Always fails"])
    E --> I(["❌ Always fails"])

    style F fill:#0d2e1a,stroke:#00e5a0,color:#00e5a0
    style G fill:#0d2e1a,stroke:#00e5a0,color:#00e5a0
    style H fill:#2e0d0d,stroke:#ff4444,color:#ff4444
    style I fill:#2e0d0d,stroke:#ff4444,color:#ff4444

⚠️ Wazuh ไม่แจ้งเตือน เมื่อ <field> fail เพราะไม่มี decoder ทำงาน มันแค่ไม่ match เฉยๆ นี่คือเหตุผลที่ rule ที่ดูถูกต้องอาจไม่ทำงานอย่างเงียบๆ


8. เมื่อไหรต้องใช้ Wazuh Decoder?

ใช้ decision tree นี้ทุกครั้งที่เขียน rule ใหม่:

flowchart TD
    Q(["What does your rule need to do?"])
    Q --> A["Detect that a\nstring exists in the log"]
    Q --> B["Match a specific\nfield value precisely"]
    Q --> C["Correlate events\nacross multiple logs"]
    Q --> D["Look up a value\nin a threat-intel list"]
    Q --> E["Parse a structured format\nFortiGate or JSON or CEF"]

    A --> A1(["❌ No decoder needed\nuse match"])
    B --> B1(["✅ Decoder needed\nuse field"])
    C --> C1(["✅ Decoder needed\nuse same_field\nor different_field"])
    D --> D1(["✅ Decoder needed\nuse list field"])
    E --> E1(["✅ Decoder needed\nuse decoded_as"])

    style A1 fill:#0d2e1a,stroke:#00e5a0,color:#c8cdd8
    style B1 fill:#2e0d0d,stroke:#ff4444,color:#c8cdd8
    style C1 fill:#2e0d0d,stroke:#ff4444,color:#c8cdd8
    style D1 fill:#2e0d0d,stroke:#ff4444,color:#c8cdd8
    style E1 fill:#2e0d0d,stroke:#ff4444,color:#c8cdd8

ตัวอย่างจริง:

สิ่งที่ต้องการ detect ต้องการ decoder?
Log line มีคำว่า error ❌ ไม่ต้อง — ใช้ <match>error</match>
SSH login ผิดจาก IP range ที่ระบุ ✅ ต้อง — ต้องการ field srcip
Username เดิม login ผิดจาก 2 IP ต่างกัน ✅ ต้อง — ต้องการ field user และ srcip
Source IP ตรงกับ IP อันตรายใน list ✅ ต้อง — ต้องการ field srcip สำหรับ <list>
FortiGate firewall บล็อก connection ✅ ต้อง — ต้องการ decoder สำหรับ format log FortiGate
Windows EventID 4625 (login ผิด) ❌ ไม่ต้อง — Wazuh มี decoder built-in จัดการอยู่แล้ว

9. ลำดับความสำคัญ Decoder: เมื่อ Built-in Decoders เข้ามาแทนที่

Wazuh มี built-in decoders สำหรับ log source ทั่วไป — SSH, Windows, FortiGate, Apache และอื่นๆ decoder เหล่านี้ทำงานก่อน custom decoders ของคุณเสมอ

เรื่องนี้สำคัญมากเมื่อคุณเขียน custom rule สำหรับ log source ที่ Wazuh รู้จักอยู่แล้ว:

flowchart TD
    A(["Log from a known source\ne.g. FortiGate with date= logid="])
    A --> B{"Does a built-in\ndecoder match?"}

    B -- "Yes" --> C["Built-in decoder fires\ne.g. fortigate-firewall-v6"]
    B -- "No" --> D["Custom decoder checked"]

    C --> E{"Does your custom rule\nchain off the right parent?"}
    E -- "chains off built-in group\nif_group: fortigate" --> F(["✅ Rule fires correctly"])
    E -- "chains off custom rule\nif_sid: your-base-rule" --> G(["❌ Parent never fired\nrule never matches"])

    D --> H(["Custom decoder fires\nnormal flow"])

    style A fill:#1a1f2e,stroke:#5b8fff,color:#c8cdd8
    style B fill:#2a1f10,stroke:#ff6b35,color:#ff6b35
    style C fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8
    style F fill:#0d2e1a,stroke:#00e5a0,color:#00e5a0
    style G fill:#2e0d0d,stroke:#ff4444,color:#ff4444
    style H fill:#1a2e1f,stroke:#00e5a0,color:#c8cdd8

วิธีแก้คือใช้ <if_group> เพื่อ chain ต่อจาก rule group ของ built-in decoder แทนที่จะเป็น base rule ของคุณเอง:

<!-- ❌ ผิด — base rule ของคุณไม่ fire สำหรับ log FortiGate -->
<rule id="200">
  <if_sid>100</if_sid>   <!-- custom base rule ของคุณ -->
  <field name="action">deny</field>
</rule>

<!-- ✅ ถูก — chain ต่อจาก built-in fortigate group -->
<rule id="200">
  <if_group>fortigate</if_group>
  <field name="action">deny</field>
</rule>

10. Cheatsheet: สรุป Decoder & Rule Tags ทั้งหมด

Tag ขั้นตอน ดึง Field ได้? ต้องการ Decoder? ใช้สำหรับ
<prematch> Decoder ❌ ไม่ ตัวกรองด่วนก่อน regex
<regex> + <order> Decoder ✅ ได้ ดึง field ที่มีชื่อจาก log
<match> Rule ❌ ไม่ จับ substring ใน raw log
<field> Rule ✅ ต้อง Match ค่า field ที่ดึงออกมาแล้ว
<decoded_as> Rule ✅ ต้อง ให้ match เฉพาะเมื่อ decoder ที่ระบุทำงาน
<if_sid> Rule ❌ ไม่ Chain ต่อจาก parent rule ด้วย ID
<if_group> Rule ❌ ไม่ Chain ต่อจาก rule group (เช่น built-in fortigate)
<same_field> Rule ✅ ต้อง Correlate event ซ้ำๆ ที่มี field เดียวกัน
<different_field> Rule ✅ ต้อง ตรวจ user เดิม แต่ IP ต่างกัน (impossible travel)
<list field> Rule ✅ ต้อง Threat-intel CDB lookup จาก field ที่ decode แล้ว

สรุป

Pipeline ของ Wazuh นั้นง่ายมากเมื่อเข้าใจโมเดลสองขั้นตอน:

  1. Decoders ทำงานก่อน — แปลง raw log text เป็น named fields โดยใช้ <prematch> (กรอง), <regex> (ดึง) และ <order> (ตั้งชื่อ) มีเพียง capture groups ใน <regex> เท่านั้นที่กลายเป็น field ส่วน <prematch> ไม่ดึงอะไรเลย
  2. Rules ทำงานหลัง — <match> ทำงานกับ raw text โดยไม่ต้องการ decoder; <field>, <same_field> และ <list> จะทำงานได้ก็ต่อเมื่อ decoder ดึง field เหล่านั้นออกมาแล้วเท่านั้น

เมื่อ rule ไม่ทำงานอย่างเงียบๆ สาเหตุมักเป็นหนึ่งในนี้:

  • คุณใช้ <field> แต่ decoder ไม่ได้ดึง field นั้นออกมา
  • Built-in decoder ทำงานก่อน custom ของคุณ ทำให้ <if_sid> chain พัง
  • จำนวนชื่อใน <order> ไม่ตรงกับจำนวน groups ใน <regex>

เริ่มต้นด้วย rule ที่ใช้แค่ <match> เพื่อยืนยันว่า log ถึง Wazuh และ base rules ทำงาน แล้วค่อยเพิ่ม decoder และ <field> rules เมื่อต้องการ match ที่แม่นยำระดับ field


คำถามที่พบบ่อย (FAQ)

Q: <prematch> สร้าง field ที่ใช้ใน rules ได้ไหม?
ไม่. <prematch> เป็นแค่ตัวกรอง performance — ตรวจว่า string มีอยู่ใน log ก่อนรัน regex ไม่ดึงอะไรออกมา Field จะถูกสร้างโดย capture groups ของ <regex> ที่ map ด้วย <order> เท่านั้น

Q: Wazuh rule ทำงานได้ไหมถ้าไม่มี decoder?
ได้ ตราบเท่าที่ใช้แค่ <match> หรือ <if_sid> สอง tag นี้ทำงานกับ raw log string และไม่ต้องการ field ที่ decode แล้ว แต่ tag อย่าง <field>, <decoded_as>, <same_field> และ <list field> จะ fail เงียบๆ โดยไม่มีการแจ้งเตือน

Q: <if_sid> ใช้ทำอะไรใน Wazuh?
<if_sid> เชื่อม child rule เข้ากับ parent rule ด้วย rule ID child จะ fire ก็ต่อเมื่อ parent match ใน event เดียวกันแล้วเท่านั้น นี่คือวิธีที่ Wazuh สร้าง cascading detection — base rule match log source แล้ว child rules ตรวจ condition ที่เฉพาะเจาะจงยิ่งขึ้น

Q: <match> กับ <field> ใน Wazuh rule ต่างกันอย่างไร?
<match> ค้นหา substring ใน raw log line ทั้งบรรทัด — ไม่ต้องการ decoder ส่วน <field name="x"> match กับ field ที่มีชื่อเฉพาะซึ่ง decoder ต้องดึงออกมาก่อน ใช้ <match> สำหรับ detection แบบกว้าง และใช้ <field> เมื่อต้องการความแม่นยำกับค่าที่ระบุ

Q: Wazuh decoder มี capture groups ได้กี่ตัว?
ไม่มีเอกสารระบุขีดจำกัดที่ชัดเจน แต่จำนวน () groups ใน <regex> ต้องตรงกับจำนวนชื่อที่คั่นด้วย comma ใน <order> ถ้าไม่ตรง decoder จะ fail เงียบๆ โดยไม่มีข้อความ error

Q: ทำไม rule ถึงไม่ fire ทั้งๆ ที่ string อยู่ใน log?
สาเหตุที่เป็นไปได้มากที่สุด: (1) คุณใช้ <field> แต่ decoder ไม่ได้ดึง field นั้นออกมา (2) built-in decoder ทำงานก่อนและทำให้ <if_sid> chain พัง หรือ (3) string ใน <prematch> ไม่ปรากฏใน log ใช้ wazuh-logtest เพื่อ trace ว่า decoder และ rule ทำงานยังไงกับ log บรรทัดนั้น

Q: wazuh-logtest คืออะไร และใช้ยังไง?
wazuh-logtest เป็นเครื่องมือ built-in ของ Wazuh ที่ให้คุณวาง raw log line แล้วดูได้ทันทีว่า decoder ไหน match, field อะไรถูกดึงออกมา และ rule ไหน fire นี่คือวิธีที่เร็วที่สุดในการ debug decoder หรือ rule ที่ไม่ทำงานตามที่คาด รันได้จาก Wazuh manager CLI หรือจาก Wazuh web UI ที่ Tools → Logtest


ส่วนหนึ่งของซีรีส์ Detection Engineering พบข้อผิดพลาดหรืออยากแนะนำตัวอย่างเพิ่มเติม? เปิด issue หรือติดต่อมาได้เลย


Get in Touch with us

Chat with Us on LINE

iiitum1984

Speak to Us or Whatsapp

(+66) 83001 0222

Related Posts

Our Products