Fastly WAF 로그 수집
개요
이 파서는 Fastly WAF JSON 로그에서 필드를 추출하고, 변환하고, 이름을 바꾸고, UDM에 매핑합니다. 다양한 데이터 유형을 처리하고, 심각도 수준을 변환하며, 사용 가능한 IP 및 호스트 이름 정보를 기반으로 이벤트를 분류합니다. 또한 잠재적인 파싱 실패를 처리하고 형식이 잘못된 로그 항목을 삭제합니다.
시작하기 전에
다음 기본 요건이 충족되었는지 확인합니다.
- Google SecOps 인스턴스
- WAF 설정을 구성할 수 있는 액세스 권한이 있는 Fastly 계정
피드 설정
피드를 구성하려면 다음 단계를 따르세요.
- SIEM 설정 > 피드로 이동합니다.
- 새 피드 추가를 클릭합니다.
- 다음 페이지에서 단일 피드 구성을 클릭합니다.
- 피드 이름 필드에 피드 이름을 입력합니다 (예: Fastly WAF 로그).
- 소스 유형으로 웹훅을 선택합니다.
- 로그 유형으로 Fastly WAF를 선택합니다.
- 다음을 클릭합니다.
- 선택사항: 다음 입력 파라미터의 값을 지정합니다.
- 분할 구분 기호: 로그 줄을 구분하는 데 사용되는 구분 기호입니다(예:
\n
).
- 분할 구분 기호: 로그 줄을 구분하는 데 사용되는 구분 기호입니다(예:
- 다음을 클릭합니다.
- 확정 화면에서 피드 구성을 검토한 다음 제출을 클릭합니다.
- 보안 비밀 키 생성을 클릭하여 이 피드를 인증하기 위한 보안 비밀 키를 생성합니다.
- 비밀 키를 복사하여 저장합니다. 이 보안 비밀 키는 다시 볼 수 없습니다. 필요한 경우 새 보안 비밀 키를 재생성할 수 있지만 이 작업으로 인해 이전 보안 비밀 키는 더 이상 사용할 수 없게 됩니다.
- 세부정보 탭의 엔드포인트 정보 필드에서 피드 엔드포인트 URL을 복사합니다. 클라이언트 애플리케이션에서 이 엔드포인트 URL을 지정해야 합니다.
- 완료를 클릭합니다.
웹훅 피드에 대한 API 키 만들기
Google Cloud 콘솔 > 사용자 인증 정보로 이동합니다.
사용자 인증 정보 만들기를 클릭한 후 API 키를 선택합니다.
Google Security Operations API에 대한 API 키 액세스를 제한합니다.
엔드포인트 URL 지정
- 클라이언트 애플리케이션에서 웹훅 피드에 제공된 HTTPS 엔드포인트 URL을 지정합니다.
다음 형식의 커스텀 헤더의 일부로 API 키와 보안 비밀 키를 지정하여 인증을 사용 설정합니다.
X-goog-api-key = API_KEY X-Webhook-Access-Key = SECRET
권장사항: URL에 지정하는 대신 API 키를 헤더로 지정하세요.
웹훅 클라이언트가 커스텀 헤더를 지원하지 않는 경우 쿼리 파라미터를 다음 형식으로 사용하여 API 키와 보안 비밀 키를 지정할 수 있습니다.
ENDPOINT_URL?key=API_KEY&secret=SECRET
다음을 바꿉니다.
ENDPOINT_URL
: 피드 엔드포인트 URL입니다.API_KEY
: Google Security Operations에 인증하기 위한 API 키입니다.SECRET
: 피드를 인증하기 위해 생성한 보안 비밀 키입니다.
Fastly에서 웹훅 구성
- Fastly에 로그인합니다.
- 선택사항: 사이트 메뉴에서 사이트를 선택합니다 (사이트가 두 개 이상인 경우).
- 관리 > 사이트 통합을 선택합니다.
- 사이트 통합 추가를 클릭합니다.
- 일반 웹훅을 선택합니다.
- 웹훅 URL: Google SecOps ENDPOINT_URL을 입력한 다음 API_KEY와 SECRET을 입력합니다.
- 알림 배치: 모든 활동 또는 특정 활동을 선택합니다.
- 선택사항: 특정 활동을 선택한 경우 활동 메뉴로 이동하여 웹훅이 전송할 활동 유형을 선택합니다.
- 사이트 통합 만들기를 클릭합니다.
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 값이 'anomaly' 키와 anomaly_score 필드 값으로 security_result.detection_fields 배열을 채우는 데 사용됩니다. |
cache_status |
additional.fields[].key : "cache_status"additional.fields[].value.string_value : cache_status |
cache_status 값은 'cache_status' 키와 cache_status 필드 값으로 additional.fields 배열을 채우는 데 사용됩니다. |
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 값은 'fastly_is_edge' 키와 connection.fastly_is_edge 필드 값으로 additional.fields 배열을 채우는 데 사용됩니다. |
connection.fastly_is_shield |
additional.fields[].key : "fastly_is_shield"additional.fields[].value.bool_value : connection.fastly_is_shield |
connection.fastly_is_shield 값은 키가 'fastly_is_shield'이고 값이 connection.fastly_is_shield 필드인 additional.fields 배열을 채우는 데 사용됩니다. |
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 값은 'service_id' 키와 fastly.service_id 필드 값으로 additional.fields 배열을 채우는 데 사용됩니다. |
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 값은 키가 'accept_charset'이고 값이 request_headers.accept_charset 필드인 additional.fields 배열을 채우는 데 사용됩니다. |
request_headers.accept_language |
additional.fields[].key : "accept_language"additional.fields[].value.string_value : request_headers.accept_language |
request_headers.accept_language 값은 'accept_language' 키와 request_headers.accept_language 필드 값으로 additional.fields 배열을 채우는 데 사용됩니다. |
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 값은 키가 'cache_control'이고 값이 response_headers.cache_control 필드인 additional.fields 배열을 채우는 데 사용됩니다. |
response_headers.content_type |
additional.fields[].key : "content_type"additional.fields[].value.string_value : response_headers.content_type |
response_headers.content_type 값은 'content_type' 키와 response_headers.content_type 필드 값으로 additional.fields 배열을 채우는 데 사용됩니다. |
response_state |
additional.fields[].key : "response_state"additional.fields[].value.string_value : response_state |
response_state 값은 'response_state' 키와 response_state 필드 값으로 additional.fields 배열을 채우는 데 사용됩니다. |
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 값은 'executed' 키와 waf.executed 필드 값으로 security_result.detection_fields 배열을 채우는 데 사용됩니다. |
waf.failures |
security_result.detection_fields[].key : 'failures'security_result.detection_fields[].value : waf.failures |
waf.failures 값은 'failures' 키와 waf.failures 필드 값으로 security_result.detection_fields 배열을 채우는 데 사용됩니다. |
waf.logged |
security_result.detection_fields[].key : "logged"security_result.detection_fields[].value : waf.logged |
waf.logged 값은 'logged' 키와 waf.logged 필드 값으로 security_result.detection_fields 배열을 채우는 데 사용됩니다. |
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이 아니고 비어 있지 않으면 이 값을 사용하여 키가 'anomaly'이고 값이 waf.score.anomaly 필드인 security_result.detection_fields 배열을 채웁니다. |
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 : derivedsecurity_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 전문가로부터 답변을 받으세요.