<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Splunk on Tarragon</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/</link><description>Recent content in Splunk on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 18 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/index.xml" rel="self" type="application/rss+xml"/><item><title>Splunk Risk-Based Alerting：從 alert per rule 到 score-aggregated notable</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/risk-based-alerting/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/risk-based-alerting/</guid><description>&lt;blockquote>
&lt;p>本文是 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/" data-link-title="Splunk" data-link-desc="業界 SIEM 標準、forwarder &amp;#43; indexer &amp;#43; search head 架構、SPL 為核心查詢語言、ingestion-based 計費跟偵測覆蓋率的 trade-off">Splunk&lt;/a> overview 的 implementation-layer deep article。Overview 已說明 Splunk Enterprise Security 在 SIEM / Detection 譜系的定位、本文聚焦 &lt;em>Risk-Based Alerting (RBA)&lt;/em> 的實作層 — 從「per-rule alert」轉到「score 累積 + threshold 觸發 notable」的方法論轉變、跟 tuning / scaling / 整合的具體做法。&lt;/p>&lt;/blockquote>
&lt;h2 id="為什麼-rbaalert-fatigue-是-detection-engineering-的天花板">為什麼 RBA：alert fatigue 是 detection engineering 的天花板&lt;/h2>
&lt;p>Detection engineering 的成熟度上限不是「能寫多少 correlation rule」、是「SOC analyst 能處理多少 alert / day 而不會麻木」。多數 SOC 在 200-500 alert/day 區間就到處理上限、再加 rule 只會推升 false positive、analyst 開始 silent ignore 中低嚴重度 alert。&lt;/p>
&lt;p>RBA 的核心轉折是 &lt;em>把 alert 邏輯從「rule 觸發」拆成「score 累積」&lt;/em>：每個 detection rule 不直接產 alert、而是給 &lt;em>user / asset / process&lt;/em> 加 risk score；多個低嚴重訊號累積到 threshold 才產 notable（高優先 case）。SOC 看的不是「rule X 觸發了」、是「user Y 今天累積 70 分、上週 12 分」。&lt;/p>
&lt;p>RBA 不是 &lt;em>寫 detection rule 的替代&lt;/em>、是 &lt;em>aggregation 跟 prioritization 的新層&lt;/em>。原本 100 條 rule 各自產 alert 變成 100 條 rule 共同貢獻 score、score → notable 是新的 alert 邊界。&lt;/p>
&lt;h2 id="rba-三層-modelmodifierscorenotable">RBA 三層 model：modifier、score、notable&lt;/h2>
&lt;p>Risk 流程的三個 first-class object：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Object&lt;/th>
 &lt;th>責任&lt;/th>
 &lt;th>例&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Risk modifier&lt;/strong>&lt;/td>
 &lt;td>一條 detection rule 產出、提供「給誰加多少分、為什麼、什麼類別」&lt;/td>
 &lt;td>user &lt;code>alice@corp&lt;/code> +25 分、reason &lt;code>unusual_login_geo&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk index&lt;/strong>&lt;/td>
 &lt;td>累積所有 modifier、依時間衰減；query 出「user / asset 當前 score」&lt;/td>
 &lt;td>&lt;code>index=risk earliest=-7d&lt;/code>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Risk notable&lt;/strong>&lt;/td>
 &lt;td>當 score 累積超過 threshold 觸發、進 SOC case management&lt;/td>
 &lt;td>user 累積 50 分 → 開 incident&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>關鍵設計選擇都在 modifier 層：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>加分維度&lt;/strong>：per user / per asset / per process tree / per IP — 維度越細粒度、score 越能對應「個體」、但 query 成本越高&lt;/li>
&lt;li>&lt;strong>加分 weight&lt;/strong>：簡單做法 severity 直接對應（low=5 / med=15 / high=30 / critical=60）；細做要考慮 &lt;em>signal precision&lt;/em>（rule 的歷史 FP rate）&lt;/li>
&lt;li>&lt;strong>MITRE ATT&amp;amp;CK 對應&lt;/strong>：每個 modifier 標 tactic / technique、跟 ATT&amp;amp;CK 對應、用來判斷 &lt;em>kill chain 階段&lt;/em> 是否完整（reconnaissance → exfiltration 全套出現 vs 單一 tactic 重複）&lt;/li>
&lt;/ul>
&lt;h2 id="es-配置-step-by-step">ES 配置 step-by-step&lt;/h2>
&lt;h3 id="risk-modifier-從-correlation-search-產出">Risk modifier 從 correlation search 產出&lt;/h3>





&lt;pre tabindex="0">&lt;code class="language-spl" data-lang="spl">| search index=auth user=* unusual_geo=true
| stats count by user, src_ip, _time
| eval risk_score=25
| eval risk_object_type=&amp;#34;user&amp;#34;
| eval risk_object=user
| eval risk_message=&amp;#34;Unusual login geography&amp;#34;
| eval threat_object=src_ip
| eval threat_object_type=&amp;#34;ip_address&amp;#34;
| eval mitre_technique=&amp;#34;T1078&amp;#34;
| collect index=risk&lt;/code>&lt;/pre>&lt;p>關鍵欄位：&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>本文是 <a href="/blog/backend/07-security-data-protection/vendors/splunk/" data-link-title="Splunk" data-link-desc="業界 SIEM 標準、forwarder &#43; indexer &#43; search head 架構、SPL 為核心查詢語言、ingestion-based 計費跟偵測覆蓋率的 trade-off">Splunk</a> overview 的 implementation-layer deep article。Overview 已說明 Splunk Enterprise Security 在 SIEM / Detection 譜系的定位、本文聚焦 <em>Risk-Based Alerting (RBA)</em> 的實作層 — 從「per-rule alert」轉到「score 累積 + threshold 觸發 notable」的方法論轉變、跟 tuning / scaling / 整合的具體做法。</p></blockquote>
<h2 id="為什麼-rbaalert-fatigue-是-detection-engineering-的天花板">為什麼 RBA：alert fatigue 是 detection engineering 的天花板</h2>
<p>Detection engineering 的成熟度上限不是「能寫多少 correlation rule」、是「SOC analyst 能處理多少 alert / day 而不會麻木」。多數 SOC 在 200-500 alert/day 區間就到處理上限、再加 rule 只會推升 false positive、analyst 開始 silent ignore 中低嚴重度 alert。</p>
<p>RBA 的核心轉折是 <em>把 alert 邏輯從「rule 觸發」拆成「score 累積」</em>：每個 detection rule 不直接產 alert、而是給 <em>user / asset / process</em> 加 risk score；多個低嚴重訊號累積到 threshold 才產 notable（高優先 case）。SOC 看的不是「rule X 觸發了」、是「user Y 今天累積 70 分、上週 12 分」。</p>
<p>RBA 不是 <em>寫 detection rule 的替代</em>、是 <em>aggregation 跟 prioritization 的新層</em>。原本 100 條 rule 各自產 alert 變成 100 條 rule 共同貢獻 score、score → notable 是新的 alert 邊界。</p>
<h2 id="rba-三層-modelmodifierscorenotable">RBA 三層 model：modifier、score、notable</h2>
<p>Risk 流程的三個 first-class object：</p>
<table>
  <thead>
      <tr>
          <th>Object</th>
          <th>責任</th>
          <th>例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Risk modifier</strong></td>
          <td>一條 detection rule 產出、提供「給誰加多少分、為什麼、什麼類別」</td>
          <td>user <code>alice@corp</code> +25 分、reason <code>unusual_login_geo</code></td>
      </tr>
      <tr>
          <td><strong>Risk index</strong></td>
          <td>累積所有 modifier、依時間衰減；query 出「user / asset 當前 score」</td>
          <td><code>index=risk earliest=-7d</code></td>
      </tr>
      <tr>
          <td><strong>Risk notable</strong></td>
          <td>當 score 累積超過 threshold 觸發、進 SOC case management</td>
          <td>user 累積 50 分 → 開 incident</td>
      </tr>
  </tbody>
</table>
<p>關鍵設計選擇都在 modifier 層：</p>
<ul>
<li><strong>加分維度</strong>：per user / per asset / per process tree / per IP — 維度越細粒度、score 越能對應「個體」、但 query 成本越高</li>
<li><strong>加分 weight</strong>：簡單做法 severity 直接對應（low=5 / med=15 / high=30 / critical=60）；細做要考慮 <em>signal precision</em>（rule 的歷史 FP rate）</li>
<li><strong>MITRE ATT&amp;CK 對應</strong>：每個 modifier 標 tactic / technique、跟 ATT&amp;CK 對應、用來判斷 <em>kill chain 階段</em> 是否完整（reconnaissance → exfiltration 全套出現 vs 單一 tactic 重複）</li>
</ul>
<h2 id="es-配置-step-by-step">ES 配置 step-by-step</h2>
<h3 id="risk-modifier-從-correlation-search-產出">Risk modifier 從 correlation search 產出</h3>





<pre tabindex="0"><code class="language-spl" data-lang="spl">| search index=auth user=* unusual_geo=true
| stats count by user, src_ip, _time
| eval risk_score=25
| eval risk_object_type=&#34;user&#34;
| eval risk_object=user
| eval risk_message=&#34;Unusual login geography&#34;
| eval threat_object=src_ip
| eval threat_object_type=&#34;ip_address&#34;
| eval mitre_technique=&#34;T1078&#34;
| collect index=risk</code></pre><p>關鍵欄位：</p>
<ul>
<li><code>risk_object</code> + <code>risk_object_type</code>：誰被加分、預設 user / system / other</li>
<li><code>risk_score</code>：加多少分、考量 signal precision</li>
<li><code>threat_object</code>：對應的 attacker artifact（IP / hash / domain）、用來跨 modifier 關聯</li>
<li><code>mitre_technique</code>：對應 ATT&amp;CK ID、用於 kill chain analysis</li>
</ul>
<p><em>Tuning 提醒</em>：第一次部署別直接 <code>collect index=risk</code>、先 <code>| table</code> 看 output、估算每天會產多少 modifier；超出 indexer 容量規劃前先做 sampling（<code>| where random()/2147483647&lt;0.1</code> 取 10%）。</p>
<h3 id="risk-notablethreshold-aggregation">Risk notable：threshold aggregation</h3>





<pre tabindex="0"><code class="language-spl" data-lang="spl">| tstats summariesonly=t count, sum(All_Risk.calculated_risk_score) as total_risk
  from datamodel=Risk.All_Risk
  where earliest=-24h
  by All_Risk.risk_object, All_Risk.risk_object_type
| where total_risk &gt; 80
| `risk_score_format`</code></pre><p><code>total_risk &gt; 80</code> 是觸發 notable 的 threshold。Tuning 重點：</p>
<ul>
<li><strong>Time window</strong>：-24h 是預設、但要看 <em>attack pattern average duration</em> 調整；APT 用 7-14 day window、commodity attack 用 4-12h</li>
<li><strong>Threshold value</strong>：80 是 <em>當量</em> 不是普世值、依 modifier weight 分佈調整；ES 7.0+ 預設建議 100、實務多在 60-150 區間</li>
<li><strong>Aggregation 維度</strong>：by user 是 default、但 lateral movement scenario 要 by asset、credential abuse 要 by service account</li>
</ul>
<p><em>Tuning 提醒</em>：第一週跑 <em>shadow mode</em> — 觸發 notable 但不 page、SOC 後續 review、調整 threshold 跟 weight；shadow 跑 1-2 週後再啟 production page。</p>
<h3 id="notable-enrichment人類能看的-case">Notable enrichment：人類能看的 case</h3>





<pre tabindex="0"><code class="language-spl" data-lang="spl">| eval description=&#34;User &#34;.risk_object.&#34; accumulated &#34;.total_risk.&#34; risk over 24h&#34;
| eval mitre_techniques=mvjoin(mitre_technique, &#34;, &#34;)
| eval contributing_rules=mvjoin(search_name, &#34;, &#34;)
| sendalert notable</code></pre><p>Notable 進入 ES Incident Review、SOC analyst 看到的不只 score、還有 <em>組成這 80 分的 N 條 rule + ATT&amp;CK 覆蓋的 tactic</em>；這是 RBA 比 per-rule alert 強的核心 — analyst 直接看完整 narrative、不用拼湊。</p>
<h2 id="tuning-playbook四類常見-drift">Tuning playbook：四類常見 drift</h2>
<h3 id="playbook-afalse-positive-累積">Playbook A：False positive 累積</h3>
<p><strong>徵兆</strong>：某 user 連續 N 天觸發 notable、SOC 每次 review 後 close 為 FP；但 modifier 仍持續加分。</p>
<p><strong>根因</strong>：modifier 加分邏輯沒考慮 baseline — 例：DBA 每天用 <code>psql</code> 連 prod 是正常、<code>unusual_command</code> rule 把它當異常加 15 分、累積到 threshold。</p>
<p><strong>修法</strong>：</p>
<ol>
<li>Modifier 端加 <code>whitelist_lookup</code>：DBA / SRE / approved service account 跳過 specific modifier</li>
<li>進階：modifier 加 <code>signal_precision</code> weight、historical FP rate &gt; 30% 的 rule weight 降到 5 分以下</li>
<li>不能輕易加 <code>NOT user IN (...)</code> exclusion、long whitelist 是反模式 — 用 <em>role-based exclusion</em>（query AD group）</li>
</ol>
<h3 id="playbook-bscore-inflation">Playbook B：Score inflation</h3>
<p><strong>徵兆</strong>：threshold 設 80、SOC 收到的 notable 每 day 從 5 個漲到 25 個、但「實際攻擊」沒對應增加。</p>
<p><strong>根因</strong>：新加的 detection rule 沒對齊既有 weight 分佈、新 rule 都給 +30 / +40、global average 抬升、threshold 變相降低。</p>
<p><strong>修法</strong>：</p>
<ol>
<li>每加新 rule 時跑「+1 rule 對 daily notable 數的影響」shadow simulation</li>
<li>重新 calibrate threshold — 不是固定值、是 <em>p95 daily total_risk 的 1.5 倍</em></li>
<li>季度 review：跑 <code>index=risk | stats sum(risk_score) by source</code> 看 modifier 來源分佈、score 集中在少數 rule 是 inflation 訊號</li>
</ol>
<p><em>Tuning 提醒</em>：score inflation 跟 alert fatigue 是同樣症狀的不同根因；前者改 threshold + rule weight calibration、後者改 modifier 維度跟 whitelist。</p>
<h3 id="playbook-cthreshold-drift">Playbook C：Threshold drift</h3>
<p><strong>徵兆</strong>：threshold 設定半年沒動、但 attack landscape / business 行為都變了；要嘛 notable 太多（threshold 低於 baseline）、要嘛 missed detection（threshold 高於實際攻擊累積）。</p>
<p><strong>根因</strong>：threshold 是 <em>static value、但 baseline 是 dynamic</em>；business 流程變動（雲端遷移 / 新部門 / WFH 比例變化）影響 modifier 觸發頻率。</p>
<p><strong>修法</strong>：</p>
<ol>
<li>Quarterly tuning cadence：每季跑 <code>tstats sum(All_Risk.calculated_risk_score) by user | stats p50, p95, p99</code> 看分佈</li>
<li>Adaptive threshold：用 <code>p95 × 1.3</code> 動態計算、寫 macro 自動 update</li>
<li>不要把 threshold drift 當「rule 不準」、是 <em>基準漂移</em>、不是 rule 錯</li>
</ol>
<h3 id="playbook-ddecay-設計">Playbook D：Decay 設計</h3>
<p><strong>徵兆</strong>：user 7 天前的低分異常持續累積在 score 內、threshold 觸發 notable 但實際是 <em>7 天分散事件</em>、不是 <em>當前攻擊 episode</em>。</p>
<p><strong>根因</strong>：default RBA 在 <code>-24h</code> window 內 sum、沒考慮 <em>時間衰減</em>；7 天前的低分跟今天的低分權重一樣。</p>
<p><strong>修法</strong>：加 decay function、modifier weight 隨時間衰減：</p>





<pre tabindex="0"><code class="language-spl" data-lang="spl">| eval age_hours=(now() - _time)/3600
| eval decayed_score = calculated_risk_score * exp(-age_hours / 48)
| stats sum(decayed_score) as total_risk by risk_object</code></pre><p><code>exp(-age/48)</code> 是 48 小時半衰期、24h 前的事件權重剩 60%、48h 剩 37%、7 天前剩 &lt; 3%。half-life 依 attack pattern 調整：commodity attack 12-24h、APT 5-14 day。</p>
<h2 id="capacity-規劃">Capacity 規劃</h2>
<p>RBA 的 capacity 三個面向：</p>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>估算方式</th>
          <th>警戒值</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Risk index event/day</td>
          <td><code>總 detection rule × 平均 trigger 次數/day</code></td>
          <td>中型 SOC ~100K-500K / day</td>
      </tr>
      <tr>
          <td>Risk datamodel size</td>
          <td><code>event/day × 365 day × 1KB avg</code></td>
          <td>100K/day × 365 × 1KB ≈ 36GB / year</td>
      </tr>
      <tr>
          <td>Search head load</td>
          <td>RBA tstats 比 raw search 便宜 ~10x、但 by-user aggregation 在 1M+ user 仍重</td>
          <td>跑 hourly notable trigger search、不是 streaming</td>
      </tr>
      <tr>
          <td>Indexer ingest</td>
          <td>RBA 不大增 ingest（已 ingest 的 log 處理出 modifier）、但 datamodel acceleration 要 CPU</td>
          <td>每 indexer 預留 10-15% CPU 給 datamodel accel</td>
      </tr>
  </tbody>
</table>
<p>實務 sizing：500K modifier/day、用戶 5K、tstats hourly trigger search、需要 <em>3 indexer + 1 search head</em>（含 RBA 之外的工作）。</p>
<blockquote>
<p>注意 <a href="/blog/backend/07-security-data-protection/vendors/splunk/" data-link-title="Splunk" data-link-desc="業界 SIEM 標準、forwarder &#43; indexer &#43; search head 架構、SPL 為核心查詢語言、ingestion-based 計費跟偵測覆蓋率的 trade-off">SC4S / Splunk Cloud</a> ingest pricing — RBA 不增 ingest GB / day、但 datamodel acceleration 算 CPU 工作量、Splunk Cloud 是另外計費的 vCPU；on-prem 自管 indexer 沒這個 cost。</p></blockquote>
<h2 id="整合--下一步">整合 / 下一步</h2>
<h3 id="跟-soar--case-management">跟 SOAR / case management</h3>
<p>Notable 觸發後接 SOAR：</p>
<ul>
<li><strong>enrichment</strong>：自動 query AD / asset DB / threat intel、把 user role / asset criticality / known IoC 補進 case</li>
<li><strong>decision tree</strong>：根據 risk score 區間決定 SOC tier（&lt; 100 tier 1 / 100-200 tier 2 / 200+ tier 3 + page）</li>
<li><strong>playbook automation</strong>：disable user / isolate endpoint / rotate credential 走 SOAR pipeline、不要 SOC analyst 手動 click</li>
</ul>
<h3 id="跟-elastic-security--sentinel-對照">跟 <a href="/blog/backend/07-security-data-protection/vendors/elastic-security/" data-link-title="Elastic Security" data-link-desc="Elastic Stack 上的 SIEM &#43; EDR &#43; Cloud Security 套件、OSS 起源、KQL/EQL/Lucene/ES|QL 多查詢語言、resource-based pricing">Elastic Security</a> / <a href="/blog/backend/07-security-data-protection/vendors/google-security-operations/" data-link-title="Google Security Operations" data-link-desc="Google 雲原生 SIEM &#43; SOAR &#43; Mandiant threat intel 三合一（前 Chronicle）、UDM &#43; YARA-L、fixed-price by data tier、PB-scale 友善">Sentinel</a> 對照</h3>
<p>各家對 RBA 的實作命名不同：Splunk 叫 RBA、Elastic 叫 Risk Engine、Microsoft Sentinel 叫 Fusion + UEBA aggregation、Sumo Logic 叫 Insight Trainer；底層概念相同（score aggregation + threshold notable）、細節差在 <em>modifier 寫法跟 ML 自動化程度</em>。跨平台遷移時 modifier 邏輯多半要重寫、threshold + decay tuning 經驗可以平移。</p>
<h3 id="跟-ueba">跟 UEBA</h3>
<p>RBA 跟 UEBA（user / entity behavior analytics）是 <em>互補不是替代</em> — UEBA 用 ML 算 baseline 偏差、輸出 anomaly score 餵進 RBA 當一個 modifier 來源。實作順序通常是 <em>先靜態 rule + RBA、再加 UEBA 補充</em>；直接從 ML-first 開始通常 tuning 成本爆炸。</p>
<h3 id="下一步議題">下一步議題</h3>
<ul>
<li><strong>Threat object correlation</strong>：跨 modifier 用 threat_object 串相同 attacker artifact、score 跨 user 跨 asset 聚合</li>
<li><strong>Kill chain coverage analysis</strong>：notable 拆成「ATT&amp;CK tactic 覆蓋 N/14」、覆蓋越廣 priority 越高</li>
<li><strong>Risk-based response automation</strong>：score 區間自動觸發不同 SOAR playbook、人工只 review tier 3</li>
</ul>
<h2 id="相關連結">相關連結</h2>
<ul>
<li>上游 vendor 頁：<a href="/blog/backend/07-security-data-protection/vendors/splunk/" data-link-title="Splunk" data-link-desc="業界 SIEM 標準、forwarder &#43; indexer &#43; search head 架構、SPL 為核心查詢語言、ingestion-based 計費跟偵測覆蓋率的 trade-off">Splunk</a></li>
<li>對照案例：<a href="/blog/backend/07-security-data-protection/cases/okta-cross-tenant-impersonation-2023/" data-link-title="7.C6 Okta：Cross-tenant Impersonation 防禦回寫" data-link-desc="跨租戶 impersonation 風險如何轉成身份治理與偵測策略。">Okta Cross-Tenant Impersonation 2023</a>、<a href="/blog/backend/07-security-data-protection/cases/microsoft-storm-0558-signing-key-2023/" data-link-title="7.C4 Microsoft：Storm-0558 簽章金鑰事件" data-link-desc="簽章金鑰事件如何回寫 identity 信任邊界與觀測證據鏈。">Microsoft Storm-0558</a></li>
<li>上游 chapter：<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行 vendor：<a href="/blog/backend/07-security-data-protection/vendors/elastic-security/" data-link-title="Elastic Security" data-link-desc="Elastic Stack 上的 SIEM &#43; EDR &#43; Cloud Security 套件、OSS 起源、KQL/EQL/Lucene/ES|QL 多查詢語言、resource-based pricing">Elastic Security</a> / <a href="/blog/backend/07-security-data-protection/vendors/google-security-operations/" data-link-title="Google Security Operations" data-link-desc="Google 雲原生 SIEM &#43; SOAR &#43; Mandiant threat intel 三合一（前 Chronicle）、UDM &#43; YARA-L、fixed-price by data tier、PB-scale 友善">Google Security Operations</a></li>
<li>平行 deep article：<a href="/blog/backend/07-security-data-protection/vendors/hashicorp-vault/dynamic-credential/" data-link-title="HashiCorp Vault Dynamic Credential：lease 治理跟 application 整合的實作層" data-link-desc="Vault database secrets engine 怎麼配、application 怎麼 renew lease、production 五大踩雷（lease 過期 race、DB max_connections 撞牆、Vault sealed、token expire、scope 過寬）、容量規劃跟 vault-agent injector 整合">Vault Dynamic Credential</a></li>
<li>Methodology：<a href="/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">Vendor 深度技術文章的寫作方法論</a></li>
</ul>
]]></content:encoded></item><item><title>Splunk → Elastic Security Detection Rule Migration：6 段 phased playbook 跟 5 大踩雷</title><link>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/migrate-to-elastic-security/</link><pubDate>Mon, 18 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/migrate-to-elastic-security/</guid><description>&lt;blockquote>
&lt;p>本文是跨 vendor migration playbook、cross-link 到 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/" data-link-title="Splunk" data-link-desc="業界 SIEM 標準、forwarder &amp;#43; indexer &amp;#43; search head 架構、SPL 為核心查詢語言、ingestion-based 計費跟偵測覆蓋率的 trade-off">Splunk&lt;/a>（source）跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/elastic-security/" data-link-title="Elastic Security" data-link-desc="Elastic Stack 上的 SIEM &amp;#43; EDR &amp;#43; Cloud Security 套件、OSS 起源、KQL/EQL/Lucene/ES|QL 多查詢語言、resource-based pricing">Elastic Security&lt;/a>（target）兩個 vendor overview。Migration playbook 跟 &lt;a href="https://tarrragon.github.io/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">vendor deep article methodology&lt;/a> 的 6-section flow 不同 — 是 &lt;em>phased process&lt;/em>（audit → translation → parallel run → cutover → cleanup）、強調 &lt;em>時間軸&lt;/em> 跟 &lt;em>回退邊界&lt;/em>。&lt;/p>&lt;/blockquote>
&lt;h2 id="為什麼遷cost--multi-vendor--cloud-native-三條-driver">為什麼遷：cost / multi-vendor / cloud-native 三條 driver&lt;/h2>
&lt;p>Splunk → Elastic 遷移在 2022+ 變主流選項、driver 通常三條疊加：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>Driver&lt;/th>
 &lt;th>觸發場景&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>Cost&lt;/strong>&lt;/td>
 &lt;td>Splunk per-GB ingest pricing 在 5+ TB/day 規模累積到無法接受、Elastic fixed-tier pricing 可省 50-70%&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Multi-vendor&lt;/strong>&lt;/td>
 &lt;td>想避免 SIEM lock-in、跟 &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/google-security-operations/" data-link-title="Google Security Operations" data-link-desc="Google 雲原生 SIEM &amp;#43; SOAR &amp;#43; Mandiant threat intel 三合一（前 Chronicle）、UDM &amp;#43; YARA-L、fixed-price by data tier、PB-scale 友善">Sentinel&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/datadog-security/" data-link-title="Datadog Security" data-link-desc="Datadog observability platform 上的 security suite：Cloud SIEM &amp;#43; CSPM &amp;#43; CWS &amp;#43; AAP &amp;#43; Sensitive Data Scanner、跟 observability 同 plane">Datadog Security&lt;/a> 同時跑形成 portfolio&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>Cloud-native&lt;/strong>&lt;/td>
 &lt;td>已用 Elasticsearch / Kibana 做 application observability、想統一 stack 走 Elastic Cloud / ECK&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>反向 driver（Elastic → Splunk）也存在但少數 — 主要是 &lt;em>合規 / 政府客戶要 Splunk Cloud GovCloud&lt;/em>、或 &lt;em>Splunk Premium ES 的 RBA + UEBA 成熟度仍領先&lt;/em>。本文聚焦 Splunk → Elastic、反向流程結構相同但 &lt;em>schema 對位方向相反&lt;/em>。&lt;/p>
&lt;h2 id="結構phased-migration-不是-6-section-deep-article">結構：phased migration 不是 6-section deep article&lt;/h2>
&lt;p>跟 single-feature deep article（&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/vendors/splunk/risk-based-alerting/" data-link-title="Splunk Risk-Based Alerting：從 alert per rule 到 score-aggregated notable" data-link-desc="Splunk Enterprise Security 的 RBA 方法論：risk score / modifier / notable 三層 model、ES 配置 step-by-step、tuning playbook（false positive / score inflation / threshold drift / decay）、capacity 成本、跟 SOAR &amp;#43; case management 整合">Splunk RBA&lt;/a>、Vault dynamic credential）不同、migration playbook 的核心是 &lt;em>time-sequenced phase&lt;/em> + &lt;em>回退邊界&lt;/em>。6 段 phase：&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>本文是跨 vendor migration playbook、cross-link 到 <a href="/blog/backend/07-security-data-protection/vendors/splunk/" data-link-title="Splunk" data-link-desc="業界 SIEM 標準、forwarder &#43; indexer &#43; search head 架構、SPL 為核心查詢語言、ingestion-based 計費跟偵測覆蓋率的 trade-off">Splunk</a>（source）跟 <a href="/blog/backend/07-security-data-protection/vendors/elastic-security/" data-link-title="Elastic Security" data-link-desc="Elastic Stack 上的 SIEM &#43; EDR &#43; Cloud Security 套件、OSS 起源、KQL/EQL/Lucene/ES|QL 多查詢語言、resource-based pricing">Elastic Security</a>（target）兩個 vendor overview。Migration playbook 跟 <a href="/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">vendor deep article methodology</a> 的 6-section flow 不同 — 是 <em>phased process</em>（audit → translation → parallel run → cutover → cleanup）、強調 <em>時間軸</em> 跟 <em>回退邊界</em>。</p></blockquote>
<h2 id="為什麼遷cost--multi-vendor--cloud-native-三條-driver">為什麼遷：cost / multi-vendor / cloud-native 三條 driver</h2>
<p>Splunk → Elastic 遷移在 2022+ 變主流選項、driver 通常三條疊加：</p>
<table>
  <thead>
      <tr>
          <th>Driver</th>
          <th>觸發場景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Cost</strong></td>
          <td>Splunk per-GB ingest pricing 在 5+ TB/day 規模累積到無法接受、Elastic fixed-tier pricing 可省 50-70%</td>
      </tr>
      <tr>
          <td><strong>Multi-vendor</strong></td>
          <td>想避免 SIEM lock-in、跟 <a href="/blog/backend/07-security-data-protection/vendors/google-security-operations/" data-link-title="Google Security Operations" data-link-desc="Google 雲原生 SIEM &#43; SOAR &#43; Mandiant threat intel 三合一（前 Chronicle）、UDM &#43; YARA-L、fixed-price by data tier、PB-scale 友善">Sentinel</a> / <a href="/blog/backend/07-security-data-protection/vendors/datadog-security/" data-link-title="Datadog Security" data-link-desc="Datadog observability platform 上的 security suite：Cloud SIEM &#43; CSPM &#43; CWS &#43; AAP &#43; Sensitive Data Scanner、跟 observability 同 plane">Datadog Security</a> 同時跑形成 portfolio</td>
      </tr>
      <tr>
          <td><strong>Cloud-native</strong></td>
          <td>已用 Elasticsearch / Kibana 做 application observability、想統一 stack 走 Elastic Cloud / ECK</td>
      </tr>
  </tbody>
</table>
<p>反向 driver（Elastic → Splunk）也存在但少數 — 主要是 <em>合規 / 政府客戶要 Splunk Cloud GovCloud</em>、或 <em>Splunk Premium ES 的 RBA + UEBA 成熟度仍領先</em>。本文聚焦 Splunk → Elastic、反向流程結構相同但 <em>schema 對位方向相反</em>。</p>
<h2 id="結構phased-migration-不是-6-section-deep-article">結構：phased migration 不是 6-section deep article</h2>
<p>跟 single-feature deep article（<a href="/blog/backend/07-security-data-protection/vendors/splunk/risk-based-alerting/" data-link-title="Splunk Risk-Based Alerting：從 alert per rule 到 score-aggregated notable" data-link-desc="Splunk Enterprise Security 的 RBA 方法論：risk score / modifier / notable 三層 model、ES 配置 step-by-step、tuning playbook（false positive / score inflation / threshold drift / decay）、capacity 成本、跟 SOAR &#43; case management 整合">Splunk RBA</a>、Vault dynamic credential）不同、migration playbook 的核心是 <em>time-sequenced phase</em> + <em>回退邊界</em>。6 段 phase：</p>
<table>
  <thead>
      <tr>
          <th>Phase</th>
          <th>內容</th>
          <th>預估時長</th>
          <th>回退邊界</th>
          <th></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Phase 0：rule audit</strong></td>
          <td>盤點 Splunk 端 rule、量化 precision / FP rate / alert volume</td>
          <td>1-2 週</td>
          <td>不影響 production</td>
          <td></td>
      </tr>
      <tr>
          <td><strong>Phase 1：schema 對位</strong></td>
          <td>SPL ↔ KQL / ES</td>
          <td>QL、CIM ↔ ECS、index ↔ data view 對應規格</td>
          <td>1-2 週</td>
          <td>不影響 production</td>
      </tr>
      <tr>
          <td><strong>Phase 2：translation</strong></td>
          <td>rule 一條條轉、AI-assisted + 人工 verify</td>
          <td>4-12 週</td>
          <td>翻譯失敗的 rule 退回 manual / 標 deferred</td>
          <td></td>
      </tr>
      <tr>
          <td><strong>Phase 3：parallel run</strong></td>
          <td>兩 SIEM 同時跑、alert 兩邊產出、累積 confidence</td>
          <td>4-8 週</td>
          <td>切回單 Splunk、Elastic 端關 alert</td>
          <td></td>
      </tr>
      <tr>
          <td><strong>Phase 4：cutover</strong></td>
          <td>alert routing 切到 Elastic、Splunk 仍 ingest 但不送 alert</td>
          <td>1 週</td>
          <td>routing 切回 Splunk、半小時內可逆</td>
          <td></td>
      </tr>
      <tr>
          <td><strong>Phase 5：cleanup</strong></td>
          <td>Splunk ingest 停、歷史資料 archive 到 S3、license decommission</td>
          <td>2-4 週</td>
          <td><strong>不可逆</strong> — 過早走會失去歷史查詢能力</td>
          <td></td>
      </tr>
  </tbody>
</table>
<p>整個遷移週期 4-9 個月、跟 single deep article 1-2 小時完全不同 scale。</p>
<h2 id="phase-0rule-audit-建-baseline">Phase 0：rule audit 建 baseline</h2>
<p>遷移前必須先知道 <em>current state</em>：</p>





<pre tabindex="0"><code class="language-spl" data-lang="spl">-- Splunk rule 盤點
| rest /servicesNS/-/-/saved/searches
  splunk_server=local search=&#34;alert&#34;
| where disabled=0
| eval rule_age=now()-strptime(updated, &#34;%Y-%m-%dT%H:%M:%S&#34;)
| stats count, avg(rule_age) by app, owner</code></pre><p>每條 rule 量化四個指標：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>怎麼算</th>
          <th>用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Alert volume / day</td>
          <td><code>index=_audit action=alert_fired rule_name=X</code> 過 30 天</td>
          <td>高 volume 先翻、cutover 期間影響大</td>
      </tr>
      <tr>
          <td>Precision (TP / total)</td>
          <td>SOC review 過去 30 天 alert、標 TP / FP / unknown</td>
          <td>低 precision 先翻（藉機 fix、不是直接複製問題）</td>
      </tr>
      <tr>
          <td>Detection coverage</td>
          <td>對應 MITRE ATT&amp;CK technique</td>
          <td>確認 Elastic 端有對應 coverage、不能漏 tactic</td>
      </tr>
      <tr>
          <td>Owner / 維護狀態</td>
          <td>rule 的 owner team + 最後 update 時間</td>
          <td>Owner 失聯的 rule 翻譯成本爆、考慮直接退役</td>
      </tr>
  </tbody>
</table>
<p><strong>Audit 階段的關鍵決策：哪些 rule 不翻譯</strong> — production 通常 30-50% rule 是 legacy / dead code / 已 deprecated；遷移是 <em>清理機會</em>、不是「全部複製過去」。</p>
<h2 id="phase-1schema-對位">Phase 1：Schema 對位</h2>
<p>Splunk 跟 Elastic 的 data model 沒有 1:1 mapping、必須先建對位 spec：</p>
<table>
  <thead>
      <tr>
          <th>Splunk concept</th>
          <th>Elastic 對應</th>
          <th>對位難度</th>
          <th></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>SPL search language</td>
          <td>KQL（簡單）/ ES</td>
          <td>QL（複雜 query、PG 14+ piped）</td>
          <td>中、語法差距大但概念對齊</td>
      </tr>
      <tr>
          <td>Index</td>
          <td>Data view（read）/ data stream（write）</td>
          <td>低、概念相同</td>
          <td></td>
      </tr>
      <tr>
          <td>CIM data model</td>
          <td>Elastic Common Schema (ECS)</td>
          <td>中、欄位命名差、有對照表（CIM→ECS open source）</td>
          <td></td>
      </tr>
      <tr>
          <td>Macros</td>
          <td>Runtime fields / transforms / ingest pipeline</td>
          <td>高、Splunk macro 是 SPL fragment、Elastic 沒對等概念</td>
          <td></td>
      </tr>
      <tr>
          <td>Lookups</td>
          <td>Enrich processors / lookup index</td>
          <td>中、邏輯對等但 lifecycle 管法不同</td>
          <td></td>
      </tr>
      <tr>
          <td>Correlation search</td>
          <td>Detection rule（KQL / EQL / Threshold / ML）</td>
          <td>中、Splunk 一條 search、Elastic 拆 rule type</td>
          <td></td>
      </tr>
      <tr>
          <td>Summary index</td>
          <td>Transform / rollup</td>
          <td>高、Splunk <code>tstats</code> summary index 概念複雜</td>
          <td></td>
      </tr>
      <tr>
          <td>Notable event</td>
          <td>Alert + signal（Security app）</td>
          <td>低、Elastic 7.x+ 已成熟</td>
          <td></td>
      </tr>
      <tr>
          <td>Saved search</td>
          <td>Saved query</td>
          <td>低</td>
          <td></td>
      </tr>
      <tr>
          <td>Dashboard</td>
          <td>Kibana dashboard</td>
          <td>中、Splunk XML/SimpleXML 跟 Kibana JSON 不可直接轉</td>
          <td></td>
      </tr>
  </tbody>
</table>
<p><strong>Field mapping 是最大坑</strong>：Splunk 自由 schema（<code>extract</code> runtime）vs Elastic 強 type ECS。Splunk 端 <code>src_ip</code> 可能是 string；Elastic 端必須 <code>source.ip</code> 是 <code>ip</code> type — 任何 ingest pipeline 都要先把 raw event 轉成 ECS 結構。</p>
<h2 id="phase-2translation-pipeline">Phase 2：Translation pipeline</h2>
<p>實務 translation 用 <em>3-tier hybrid</em>：</p>
<h3 id="tier-1-vendor-toolcover-30-50">Tier 1: vendor tool（cover 30-50%）</h3>
<p>Elastic 官方提供 <code>splunk-to-elastic</code> migration assistant（SaaS / on-prem）— 對 <em>簡單 SPL search</em> 自動轉 KQL；cover ratio 視 SPL 複雜度而定。</p>
<h3 id="tier-2-llm-assistedcover-30-40">Tier 2: LLM-assisted（cover 30-40%）</h3>
<p>對 <em>中等複雜</em> SPL（含 stats / eval / where）、用 Claude / GPT 翻譯：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">prompt template:
</span></span><span class="line"><span class="ln">2</span><span class="cl">&#34;Convert this Splunk SPL to Elastic ES|QL. Preserve detection logic. List any
</span></span><span class="line"><span class="ln">3</span><span class="cl">unmappable functions.
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">SPL:
</span></span><span class="line"><span class="ln">6</span><span class="cl">index=auth action=login user=* | bucket _time span=5m
</span></span><span class="line"><span class="ln">7</span><span class="cl">| stats count by user, src_ip, _time | where count &gt; 10&#34;</span></span></code></pre></div><p>LLM output 必須 <em>人工 verify</em>：</p>
<ul>
<li>對相同樣本資料跑 SPL vs ES|QL、output 對齊</li>
<li>FP rate 不能 <em>惡化</em></li>
<li>Threshold / window 對等（5m window 跟 5m window 對應）</li>
</ul>
<h3 id="tier-3-manualcover-10-30">Tier 3: manual（cover 10-30%）</h3>
<p>剩下的是：</p>
<ul>
<li>含 macro 跨 SPL fragment 的 rule（macro 必須先展開或 inline）</li>
<li>含 summary index 跟 tstats 的高效能 rule</li>
<li>用 <code>transaction</code> / <code>streamstats</code> 的 stateful query</li>
</ul>
<p>這類 rule 翻譯成 KQL 邏輯後、通常 <em>效能差 5-20x</em>（Splunk summary index 是 precomputed、KQL 是 runtime）；要評估 <em>改用 Elastic transform</em> 或 <em>接受效能下降</em>。</p>
<h2 id="phase-3parallel-run">Phase 3：Parallel run</h2>
<p>雙 SIEM 同時跑是 <em>最重要的 confidence-building 階段</em>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">                 ┌─→ Splunk ──→ alert ──┐
</span></span><span class="line"><span class="ln">2</span><span class="cl">data source ─┤                          ├─→ alert dedup ──→ SOAR / SOC
</span></span><span class="line"><span class="ln">3</span><span class="cl">                 └─→ Elastic ──→ alert ─┘</span></span></code></pre></div><p>Dedup 策略：</p>
<ul>
<li><strong>Key</strong>：<code>rule_name + event_id + timestamp_5min_bucket</code></li>
<li><strong>Window</strong>：5-10 分鐘（兩端有不同處理 latency）</li>
<li><strong>Routing</strong>：dedup 後送 SOAR、SOC 看「來自哪個 SIEM」標籤</li>
</ul>
<p>跑 4-8 週累積：</p>
<table>
  <thead>
      <tr>
          <th>指標</th>
          <th>期望</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Alert coverage 一致性</td>
          <td>Elastic 抓到 Splunk 的 95%+ 對應 alert</td>
      </tr>
      <tr>
          <td>FP rate 不惡化</td>
          <td>Elastic FP / Splunk FP ≤ 1.2（允許 20% 浮動）</td>
      </tr>
      <tr>
          <td>Detection latency 對等</td>
          <td>Elastic 端 alert 時間在 Splunk 端 ± 5 分鐘內</td>
      </tr>
      <tr>
          <td>Volume / day</td>
          <td>Alert 總數兩端對齊（10% 內）</td>
      </tr>
  </tbody>
</table>
<p>不對齊的 rule 退回 Phase 2 重新 translation；累積到 95%+ 對齊才能進 Phase 4。</p>
<h2 id="phase-4cutover--routing-切換">Phase 4：Cutover — routing 切換</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Before cutover:
</span></span><span class="line"><span class="ln">2</span><span class="cl">  Splunk → SOAR (active routing)
</span></span><span class="line"><span class="ln">3</span><span class="cl">  Elastic → SOAR (parallel, marked test)
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl">After cutover:
</span></span><span class="line"><span class="ln">6</span><span class="cl">  Splunk → ingest 持續 / alert disabled
</span></span><span class="line"><span class="ln">7</span><span class="cl">  Elastic → SOAR (active routing)</span></span></code></pre></div><p>Cutover 期間：</p>
<ol>
<li>PagerDuty / Opsgenie 端 <em>先建 Elastic integration</em>、不立刻 disable Splunk</li>
<li>切換 dedup key 的 routing priority — 同一 alert 優先取 Elastic 那條</li>
<li><strong>保留 Splunk ingest</strong> — 不立刻停、提供 fallback 半小時</li>
<li>SOC 24h 監視、無異常進入 Phase 5</li>
</ol>
<p>回退邊界：cutover 失敗（Elastic 端 alert 大量遺漏 / 延遲）→ routing 切回 Splunk、Elastic 端 alert 再標 test、回 Phase 3。回退時間 30 分鐘內。</p>
<h2 id="phase-5cleanup--不可逆階段">Phase 5：Cleanup — 不可逆階段</h2>
<p>Splunk ingest 停、license decommission、歷史資料 archive：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 1. 歷史 archive 到 S3（Splunk DDAS / Smart Store / 第三方）</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">splunk <span class="nb">export</span> ... <span class="p">|</span> aws s3 cp - s3://splunk-archive/
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 2. 確認 archive 可查（cold storage retrieve test）</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="c1"># 3. Splunk indexer disable / Splunk Cloud subscription downgrade</span></span></span></code></pre></div><p><strong>不可逆邊界</strong>：Splunk license 退掉、historical query 必須走 S3 + 重 ingest 才能跑、SLA 從即時變天級。決策關鍵：</p>
<ul>
<li>法規 retention（GDPR / SOX / HIPAA）多久</li>
<li>Incident response 需要 historical query 的頻率</li>
<li>翻譯後的歷史資料 indexable in Elastic？多數情況 ECS 跟 CIM 結構差太大、historical 不直接可查</li>
</ul>
<p>實務 default：Splunk Cloud 保留最低 tier 1 年、Elastic 接新資料；1 年後再評估 archive 策略。</p>
<h2 id="production-故障演練">Production 故障演練</h2>
<h3 id="case-1macro-跨-spl-沒對應-kql-function">Case 1：Macro 跨 SPL 沒對應 KQL function</h3>
<p><strong>徵兆</strong>：translation tool 把 macro <code>\</code>my_internal_lookup(&hellip;)`` 標 unmappable、人工翻譯後發現 macro 含 3 個巢狀 macro、共 80 行 SPL 邏輯；KQL 端拆成 5 個 runtime field + 2 個 ingest processor 才對等。</p>
<p><strong>修法</strong>：</p>
<ol>
<li><strong>Audit 階段</strong> 用 <code>splunk btool savedsearches list | grep &lt;macro&gt;</code> 找所有 macro 使用點、估翻譯成本</li>
<li><strong>Inline 策略</strong>：macro 在 5 處以下、直接 inline 到 detection rule、不重建 KQL macro</li>
<li><strong>Ingest processor 策略</strong>：macro 是 <em>資料轉換</em> 邏輯、放 Elastic ingest pipeline、不放 detection rule</li>
<li><strong>退役策略</strong>：macro 已 deprecated、不翻譯、把使用的 rule 一起退役</li>
</ol>
<h3 id="case-2time-zone-parsing-差異">Case 2：Time zone parsing 差異</h3>
<p><strong>徵兆</strong>：parallel run 階段、Splunk 跟 Elastic 對同一個 raw event 解出的 <code>_time</code> 差 8 小時；dedup key 沒對齊、雙 alert 都觸發。</p>
<p><strong>根因</strong>：Splunk <code>_time</code> 是 epoch、time zone 由 <code>props.conf</code> 端決定；Elastic ingest pipeline 用 <code>date</code> processor、time zone 預設 UTC。raw event 有 <code>Asia/Taipei</code> timestamp、Splunk 解 UTC、Elastic 解 local。</p>
<p><strong>修法</strong>：</p>
<ol>
<li><strong>Ingest pipeline 統一</strong>：所有 raw event 在 ingest 時轉 UTC、不依賴 source-side time zone</li>
<li><strong>dedup 容忍 window</strong>：dedup window 拉到 30 分鐘、cover time zone 漂移</li>
<li><strong>schema 對位 spec 明示時區處理</strong>：Phase 1 spec 要列「所有時間戳統一 UTC」</li>
</ol>
<h3 id="case-3summary-index-翻譯效能爆">Case 3：Summary index 翻譯效能爆</h3>
<p><strong>徵兆</strong>：Splunk 端 <code>tstats count from datamodel=Authentication where _time&gt;=-7d</code> 跑 2 秒、翻譯成 KQL 後 Elastic 跑 45 秒；SOC dashboard 端 timeout。</p>
<p><strong>根因</strong>：Splunk summary index 是 <em>precomputed</em>（小時 / 天聚合預先算好）、<code>tstats</code> 直接讀 summary；KQL 直接跑 search 是 <em>raw event scan</em>、效能差數量級。</p>
<p><strong>修法</strong>：</p>
<ol>
<li><strong>Elastic Transform</strong>：Elastic 端建 <em>continuous transform</em>、把 raw event 預先 aggregate 到 transform index、KQL 查 transform index、效能對等</li>
<li><strong>Rollup index</strong>（Elastic legacy）：給 metric-style data 用、deprecated 但仍可</li>
<li><strong>接受 latency</strong>：dashboard query 可接受 30s、不必精準對等 Splunk</li>
</ol>
<h3 id="case-4cutover-期間-pagerduty-dedup-key-衝突">Case 4：Cutover 期間 PagerDuty dedup key 衝突</h3>
<p><strong>徵兆</strong>：cutover 後 24h、SOC 收到雙倍 alert；PagerDuty 兩條 incident 各標 <code>splunk</code> 跟 <code>elastic</code> source、實際是同一事件。</p>
<p><strong>根因</strong>：PagerDuty 的 dedup key 用 <code>rule_name + alert_id</code>、Splunk alert_id 跟 Elastic signal_id 命名空間不同、PagerDuty 視為兩個獨立 incident。</p>
<p><strong>修法</strong>：</p>
<ol>
<li><strong>預先設計 dedup key</strong>：用 <code>rule_name + event_hash</code>、不用 SIEM 內部 ID</li>
<li><strong>PagerDuty routing rule</strong>：cutover 期間 disable Splunk source routing、不要靠 dedup</li>
<li><strong>Phase 3 parallel run 期間就測試 dedup</strong>：不要拖到 cutover 才發現</li>
</ol>
<h3 id="case-5過早-decommission-splunk歷史-incident-無法回溯">Case 5：過早 decommission Splunk、歷史 incident 無法回溯</h3>
<p><strong>徵兆</strong>：cutover 後 6 個月、發生 incident、需要回查 12 個月前的 auth log；Splunk 已 decom、Elastic 端歷史資料缺、S3 archive 無索引、4 小時找不到 evidence。</p>
<p><strong>根因</strong>：Cleanup phase 過早走、沒先做 <em>historical query rehearsal</em>；S3 archive 沒可用的索引層。</p>
<p><strong>修法</strong>：</p>
<ol>
<li><strong>預防</strong>：Phase 5 前跑 <em>5 個 historical query drill</em>、驗證 incident response 時能用</li>
<li><strong>架構</strong>：S3 archive 配 Elastic frozen tier（searchable snapshot）、6 個月 retrieve latency 接受</li>
<li><strong>法規對齊</strong>：Cleanup 時間表必須跟 compliance retention requirement 對齊、不只是 cost-driven</li>
</ol>
<h2 id="capacity--cost-對照">Capacity / cost 對照</h2>
<table>
  <thead>
      <tr>
          <th>維度</th>
          <th>Splunk Enterprise / Cloud</th>
          <th>Elastic Security</th>
          <th>取捨</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Pricing model</td>
          <td>per-GB ingest（昂貴 in scale）</td>
          <td>fixed tier / data tier / per-resource</td>
          <td>Elastic 5+ TB/day 規模便宜 50-70%</td>
      </tr>
      <tr>
          <td>Ingest performance</td>
          <td>強、Splunk forwarder 成熟</td>
          <td>強、Elastic Agent / Filebeat</td>
          <td>略接近、Splunk 對 unstructured raw 略優</td>
      </tr>
      <tr>
          <td>Search performance</td>
          <td>強、SPL + summary index</td>
          <td>中、KQL runtime + transform</td>
          <td>Splunk 對複雜 query 仍領先</td>
      </tr>
      <tr>
          <td>Detection content</td>
          <td>ES content + SOC content</td>
          <td>Elastic Security 内建 detection rule + 開源</td>
          <td>兩端都有、Elastic 對 cloud-native 較強</td>
      </tr>
      <tr>
          <td>UEBA / ML</td>
          <td>ES Premium UEBA、成熟</td>
          <td>Elastic ML + 7.x+ rule type</td>
          <td>Splunk 領先、Elastic 追趕中</td>
      </tr>
      <tr>
          <td>Cloud-native</td>
          <td>Splunk Cloud（managed but proprietary）</td>
          <td>Elastic Cloud / ECK on K8s</td>
          <td>Elastic 更 K8s-friendly</td>
      </tr>
      <tr>
          <td>Lock-in</td>
          <td>高（SPL / 自家 forwarder / ES app）</td>
          <td>中（open-source core + commercial extension）</td>
          <td>Elastic 較易遷出（理論上）</td>
      </tr>
      <tr>
          <td>Total cost (5y, 10TB/day)</td>
          <td>$5-15M USD</td>
          <td>$1.5-5M USD</td>
          <td>5-3 倍差</td>
      </tr>
  </tbody>
</table>
<h2 id="整合--下一步">整合 / 下一步</h2>
<h3 id="跟-soar-整合">跟 SOAR 整合</h3>
<p><a href="/blog/backend/08-incident-response/vendors/pagerduty/" data-link-title="PagerDuty" data-link-desc="On-call / alerting 主流 SaaS、IR 平台演化">PagerDuty</a> / Tines / Splunk SOAR：</p>
<ul>
<li>cutover 期間 SOAR playbook 仍用 Splunk-shaped event、Phase 5 後改 Elastic-shaped</li>
<li>Playbook 內 SPL query 必須改寫 KQL / ES|QL、可 hybrid（短期保留 SOAR 端原 SPL 邏輯）</li>
</ul>
<h3 id="跟-case-management-整合">跟 case management 整合</h3>
<p>Jira / ServiceNow / Elastic Cases：</p>
<ul>
<li>Splunk notable → Jira ticket 用 link field 帶 <code>splunk_url</code></li>
<li>Elastic alert → Jira 用 <code>elastic_url</code></li>
<li>兩個 URL field 期間同時存在、Phase 5 後 archive</li>
</ul>
<h3 id="反向遷移elastic--splunk">反向遷移（Elastic → Splunk）</h3>
<p>結構 mirror 對稱、phase 仍 6 段、但 schema 對位方向相反：</p>
<ul>
<li>KQL → SPL 翻譯（vendor tool 對等度低、ES|QL → SPL 更困難）</li>
<li>ECS → CIM 對位</li>
<li>多數企業 <em>不會</em> 反向遷、reverse migration 多半是合規驅動（特定客戶要 Splunk）</li>
</ul>
<h3 id="下一步議題">下一步議題</h3>
<ul>
<li><strong>Multi-vendor SIEM portfolio</strong>：不選一家、Splunk + Elastic + Sentinel 同時跑、routing 邏輯按 cost / use case 切</li>
<li><strong>AI-native detection</strong>：兩家都在發展、translation 流程可能再次重來</li>
<li><strong>Compliance migration constraints</strong>：金融 / 政府客戶 SIEM migration 需通過 audit、phase 時間表會被拉長</li>
</ul>
<h2 id="相關連結">相關連結</h2>
<ul>
<li>Source vendor：<a href="/blog/backend/07-security-data-protection/vendors/splunk/" data-link-title="Splunk" data-link-desc="業界 SIEM 標準、forwarder &#43; indexer &#43; search head 架構、SPL 為核心查詢語言、ingestion-based 計費跟偵測覆蓋率的 trade-off">Splunk</a></li>
<li>Target vendor：<a href="/blog/backend/07-security-data-protection/vendors/elastic-security/" data-link-title="Elastic Security" data-link-desc="Elastic Stack 上的 SIEM &#43; EDR &#43; Cloud Security 套件、OSS 起源、KQL/EQL/Lucene/ES|QL 多查詢語言、resource-based pricing">Elastic Security</a></li>
<li>上游 chapter：<a href="/blog/backend/07-security-data-protection/detection-coverage-and-signal-governance/" data-link-title="7.13 偵測覆蓋率與訊號治理" data-link-desc="定義偵測覆蓋、訊號品質與誤報成本的治理問題">7.13 偵測覆蓋率與訊號治理</a></li>
<li>平行 deep article：<a href="/blog/backend/07-security-data-protection/vendors/splunk/risk-based-alerting/" data-link-title="Splunk Risk-Based Alerting：從 alert per rule 到 score-aggregated notable" data-link-desc="Splunk Enterprise Security 的 RBA 方法論：risk score / modifier / notable 三層 model、ES 配置 step-by-step、tuning playbook（false positive / score inflation / threshold drift / decay）、capacity 成本、跟 SOAR &#43; case management 整合">Splunk RBA</a></li>
<li>Methodology：<a href="/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">Vendor 深度技術文章的寫作方法論</a></li>
</ul>
]]></content:encoded></item></channel></rss>