收集 Fastly WAF 記錄
總覽
這個剖析器會從 Fastly WAF JSON 記錄中擷取欄位、轉換及重新命名,然後對應至 UDM。這項服務會處理各種資料類型、轉換嚴重程度,並根據可用的 IP 和主機名稱資訊將事件分類。此外,這項服務還會處理可能的剖析失敗情形,並捨棄格式錯誤的記錄項目。
事前準備
請確認您已完成下列事前準備事項:
- Google SecOps 執行個體。
- 可設定 WAF 設定的 Fastly 帳戶。
設定動態饋給
在 Google SecOps 平台中,有兩種不同的進入點可設定動態饋給:
- 「SIEM 設定」>「動態消息」
- 內容中心 > 內容包
依序前往「SIEM 設定」>「動態饋給」,設定動態饋給
如要設定動態消息,請按照下列步驟操作:
- 依序前往「SIEM 設定」>「動態消息」。
- 按一下「新增動態消息」。
- 在下一個頁面中,按一下「設定單一動態饋給」。
- 在「Feed name」(動態饋給名稱) 欄位中,輸入動態饋給的名稱 (例如「Fastly WAF Logs」)。
- 選取「Webhook」做為「來源類型」。
- 選取「Fastly WAF」做為「記錄類型」。
- 點選「下一步」。
- 選用:指定下列輸入參數的值:
- 分割分隔符號:用於分隔記錄行的分隔符號,例如
\n
。
- 分割分隔符號:用於分隔記錄行的分隔符號,例如
- 點選「下一步」。
- 在「Finalize」畫面中檢查動態饋給設定,然後按一下「Submit」。
- 按一下「產生密鑰」,產生驗證這個動態消息的密鑰。
- 複製並儲存密鑰。您無法再次查看這個密鑰。如有需要,您可以重新產生新的密鑰,但這項操作會使先前的密鑰失效。
- 在「詳細資料」分頁中,從「端點資訊」欄位複製動態消息端點網址。您需要在用戶端應用程式中指定這個端點網址。
- 按一下 [完成]。
從內容中心設定動態饋給
為下列欄位指定值:
- 分割分隔符號:用於分隔記錄行的分隔符號,例如
\n
。
進階選項
- 動態饋給名稱:系統預先填入的值,用於識別動態饋給。
- 來源類型:將記錄收集到 Google SecOps 的方法。
- 資產命名空間:與動態饋給相關聯的命名空間。
擷取標籤:套用至這個動態饋給所有事件的標籤。
按一下「產生密鑰」,產生驗證這個動態消息的密鑰。
複製並儲存密鑰。您無法再次查看這個密鑰。如有需要,您可以重新產生新的密鑰,但這項操作會使先前的密鑰失效。
在「詳細資料」分頁中,從「端點資訊」欄位複製動態消息端點網址。您需要在用戶端應用程式中指定這個端點網址。
為 Webhook 資訊提供建立 API 金鑰
前往 Google Cloud 控制台 > 憑證。
按一下 [Create credentials] (建立憑證),然後選取 [API key] (API 金鑰)。
將 API 金鑰存取權限制在 Google Security Operations API。
指定端點網址
- 在用戶端應用程式中,指定 webhook 動態饋給中提供的 HTTPS 端點網址。
如要啟用驗證,請在自訂標頭中指定 API 金鑰和私密金鑰,格式如下:
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
建議:請將 API 金鑰指定為標頭,而非在網址中指定。
如果 Webhook 用戶端不支援自訂標頭,您可以使用查詢參數指定 API 金鑰和密鑰,格式如下:
ENDPOINT_URL?key=API_KEY&secret=SECRET
更改下列內容:
ENDPOINT_URL
:動態消息端點網址。API_KEY
:用於向 Google Security Operations 進行驗證的 API 金鑰。SECRET
:您產生的密鑰,用於驗證動態饋給。
在 Fastly 中設定 Webhook
- 登入 Fastly。
- 選用:在「網站」選單中選取網站 (如有多個網站)。
- 依序選取「管理」>「網站整合」。
- 按一下「新增網站整合」。
- 選取「Generic Webhook」。
- Webhook 網址:輸入 Google SecOps ENDPOINT_URL,然後輸入 API_KEY 和 SECRET。
- 快訊位置:選取「所有活動」或「特定活動」。
- 選用:如果選取「特定活動」,請前往「活動」選單,然後選取要透過 Webhook 傳送的活動類型。
- 按一下「建立網站整合」。
UDM 對應表
記錄欄位 | UDM 對應 | 邏輯 |
---|---|---|
anomaly_score |
security_result.detection_fields[].key : "anomaly"security_result.detection_fields[].value : anomaly_score |
如果 waf.score.anomaly 為 0 或空白,且 anomaly_score 不為空白或 0,系統會使用 anomaly_score 值填入 security_result.detection_fields 陣列,並將鍵設為「anomaly」,值設為 anomaly_score 欄位。 |
cache_status |
additional.fields[].key : "cache_status"additional.fields[].value.string_value : cache_status |
cache_status 值會用於填入 additional.fields 陣列,其中包含「cache_status」鍵和 cache_status 欄位的值。 |
client_ip |
principal.ip :client_ip |
「client_ip 」欄位已對應至「principal.ip 」。 |
connection.fastly_is_edge |
additional.fields[].key : "fastly_is_edge"additional.fields[].value.bool_value : connection.fastly_is_edge |
connection.fastly_is_edge 值會用於填入 additional.fields 陣列,其中包含「fastly_is_edge」鍵和 connection.fastly_is_edge 欄位的值。 |
connection.fastly_is_shield |
additional.fields[].key : "fastly_is_shield"additional.fields[].value.bool_value : connection.fastly_is_shield |
connection.fastly_is_shield 值會用於填入 additional.fields 陣列,其中包含「fastly_is_shield」的鍵和 connection.fastly_is_shield 欄位的值。 |
connection.request_tls_version |
network.tls.version :connection.request_tls_version |
「connection.request_tls_version 」欄位已對應至「network.tls.version 」。 |
fastly.server |
target.hostname :fastly.server |
「fastly.server 」欄位已對應至「target.hostname 」。 |
fastly.service_id |
additional.fields[].key : "service_id"additional.fields[].value.string_value : fastly.service_id |
fastly.service_id 值會用於填入 additional.fields 陣列,並以「service_id」做為鍵,以及 fastly.service_id 欄位的值。 |
geo.city |
principal.location.city :geo.city |
「geo.city 」欄位已對應至「principal.location.city 」。 |
geo.country |
principal.location.country_or_region :geo.country |
「geo.country 」欄位已對應至「principal.location.country_or_region 」。 |
geo.location |
principal.location.region_latitude :從 geo.location principal.location.region_longitude 中擷取:從 geo.location 中擷取 |
系統會使用規則運算式從 geo.location 欄位擷取經緯度,並分別對應至 principal.location.region_latitude 和 principal.location.region_longitude 。 |
geo.region |
principal.location.state :geo.region |
「geo.region 」欄位已對應至「principal.location.state 」。 |
host |
principal.hostname :host |
「host 」欄位已對應至「principal.hostname 」。 |
request_headers.accept_charset |
additional.fields[].key : "accept_charset"additional.fields[].value.string_value : request_headers.accept_charset |
request_headers.accept_charset 值會用於在 additional.fields 陣列中填入「accept_charset」鍵和 request_headers.accept_charset 欄位的值。 |
request_headers.accept_language |
additional.fields[].key : "accept_language"additional.fields[].value.string_value : request_headers.accept_language |
request_headers.accept_language 值會用於填入 additional.fields 陣列,其中包含「accept_language」的鍵和 request_headers.accept_language 欄位的值。 |
request_headers.referer |
network.http.referral_url :request_headers.referer |
「request_headers.referer 」欄位已對應至「network.http.referral_url 」。 |
request_headers.user_agent |
network.http.user_agent :request_headers.user_agent |
「request_headers.user_agent 」欄位已對應至「network.http.user_agent 」。 |
request_id |
metadata.product_log_id :request_id |
「request_id 」欄位已對應至「metadata.product_log_id 」。 |
request_method |
network.http.method :request_method |
「request_method 」欄位已對應至「network.http.method 」。 |
response_headers.cache_control |
additional.fields[].key : "cache_control"additional.fields[].value.string_value : response_headers.cache_control |
response_headers.cache_control 值會用於填入 additional.fields 陣列,其中包含「cache_control」鍵和 response_headers.cache_control 欄位的值。 |
response_headers.content_type |
additional.fields[].key : "content_type"additional.fields[].value.string_value : response_headers.content_type |
response_headers.content_type 值會用於在 additional.fields 陣列中填入「content_type」鍵和 response_headers.content_type 欄位的值。 |
response_state |
additional.fields[].key : "response_state"additional.fields[].value.string_value : response_state |
response_state 值會用於填入 additional.fields 陣列,其中包含「response_state」鍵和 response_state 欄位的值。 |
response_status |
network.http.response_code :response_status |
如果 status 欄位空白,系統會將 response_status 欄位對應至 network.http.response_code 。 |
rule_id |
security_result.rule_id :rule_id |
如果 waf.rule_id 為空,系統會使用 rule_id 值填入 security_result.rule_id 。 |
severity |
waf.severity :severity |
severity 欄位值會複製到 waf.severity 。 |
size_bytes.request_header |
network.sent_bytes :size_bytes.request_header |
「size_bytes.request_header 」欄位已對應至「network.sent_bytes 」。 |
size_bytes.response_header |
network.received_bytes :size_bytes.response_header |
「size_bytes.response_header 」欄位已對應至「network.received_bytes 」。 |
status |
network.http.response_code :status |
「status 」欄位已對應至「network.http.response_code 」。 |
timestamp |
metadata.event_timestamp :timestamp |
系統會剖析 timestamp 欄位,並對應至 metadata.event_timestamp 。 |
url |
target.url :url |
「url 」欄位已對應至「target.url 」。 |
waf.blocked |
security_result.action :衍生 |
如果 waf.blocked 為 false,security_result.action 會設為「ALLOW」。如果 waf.blocked 為 true,security_result.action 會設為「BLOCK」。 |
waf.executed |
security_result.detection_fields[].key : "executed"security_result.detection_fields[].value : waf.executed |
waf.executed 值會用於在 security_result.detection_fields 陣列中填入「executed」鍵和 waf.executed 欄位的值。 |
waf.failures |
security_result.detection_fields[].key : "failures"security_result.detection_fields[].value : waf.failures |
waf.failures 值會用於填入 security_result.detection_fields 陣列,並以「failures」做為鍵,以及 waf.failures 欄位的值做為值。 |
waf.logged |
security_result.detection_fields[].key : "logged"security_result.detection_fields[].value : waf.logged |
waf.logged 值會用於在 security_result.detection_fields 陣列中填入「logged」鍵和 waf.logged 欄位的值。 |
waf.message |
metadata.description :waf.message |
如果 waf.message 不為空白,則會對應至 metadata.description 。 |
waf.rule_id |
security_result.rule_id :waf.rule_id |
如果 waf.rule_id 不為空白,則會對應至 security_result.rule_id 。 |
waf.score.anomaly |
security_result.detection_fields[].key : "anomaly"security_result.detection_fields[].value : waf.score.anomaly |
如果 waf.score.anomaly 不是 0 且不是空白,系統會使用該值填入 security_result.detection_fields 陣列,並將「anomaly」做為鍵,waf.score.anomaly 欄位的值做為值。 |
waf.score.http_violation |
security_result.detection_fields[].key : "http_violation"security_result.detection_fields[].value : waf.score.http_violation |
如果 waf.score.http_violation 不是 0 且不為空白,系統會使用該值填入 security_result.detection_fields 陣列。 |
waf.score.lfi |
security_result.detection_fields[].key : "lfi"security_result.detection_fields[].value : waf.score.lfi |
與 waf.score.http_violation 類似的邏輯。 |
waf.score.php_injection |
security_result.detection_fields[].key : "php_injection"security_result.detection_fields[].value : waf.score.php_injection |
與 waf.score.http_violation 類似的邏輯。 |
waf.score.rce |
security_result.detection_fields[].key : "rce"security_result.detection_fields[].value : waf.score.rce |
與 waf.score.http_violation 類似的邏輯。 |
waf.score.rfi |
security_result.detection_fields[].key :「rfi」security_result.detection_fields[].value :waf.score.rfi |
與 waf.score.http_violation 類似的邏輯。 |
waf.score.session_fixation |
security_result.detection_fields[].key : "session_fixation"security_result.detection_fields[].value : waf.score.session_fixation |
與 waf.score.http_violation 類似的邏輯。 |
waf.score.sql_injection |
security_result.detection_fields[].key : "sql_injection"security_result.detection_fields[].value : waf.score.sql_injection |
與 waf.score.http_violation 類似的邏輯。 |
waf.score.xss |
security_result.detection_fields[].key : "xss"security_result.detection_fields[].value : waf.score.xss |
與 waf.score.http_violation 類似的邏輯。 |
waf.severity |
security_result.severity :衍生security_result.severity_details :waf.severity |
如果 waf.severity 不為空白,系統會根據範圍判斷 security_result.severity 的值 (<=3:HIGH、>3 且 <=6:MEDIUM、>6 且 <=8:LOW,否則為 UNKNOWN_SEVERITY)。原始 waf.severity 值也會對應至 security_result.severity_details 。 |
waf_message |
metadata.description :waf_message |
如果 waf.message 為空值,但 waf_message 不為空值,則會對應至 metadata.description 。如果 client_ip 或 host 和 fastly.server 不為空白,metadata.event_type 會設為「NETWORK_HTTP」。否則,如果 client_ip 或 host 不是空白,metadata.event_type 會設為「STATUS_UPDATE」。否則會設為「GENERIC_EVENT」。硬式編碼值。硬式編碼值。硬式編碼值。 |
還有其他問題嗎?向社群成員和 Google SecOps 專業人員尋求答案。