Cloudflare 로그 수집
이 문서에서는 Webhook (HTTP 대상) 또는 Google Cloud Storage를 사용하여 Cloudflare 로그를 Google Security Operations에 수집하는 방법을 설명합니다. Cloudflare는 DNS, HTTP, 감사, 제로 트러스트, CASB에 대한 로그 형식으로 운영 데이터를 생성합니다. 이 통합을 사용하면 분석 및 모니터링을 위해 이러한 로그를 Google SecOps로 전송할 수 있습니다. 파서는 먼저 빈 필드 집합을 초기화한 다음 JSON 형식의 Cloudflare 로그를 파싱하여 유효한 JSON이 아닌 메시지를 삭제합니다. 그런 다음 코드는 특정 필드의 존재 여부와 값을 기반으로 조건부 로직을 사용하여 Cloudflare 제품과 이벤트 유형을 결정하고 이에 따라 통합 데이터 모델 (UDM) 필드를 채웁니다.
시작하기 전에
다음 기본 요건이 충족되었는지 확인합니다.
- Google SecOps 인스턴스
- LogPush가 사용 설정된 Cloudflare Enterprise 계정
- Webhook 메서드의 경우: Google Cloud 콘솔에 대한 권한 있는 액세스
- Google Cloud Storage 방법: Google Cloud Storage에 대한 액세스 권한
방법 1: 웹훅 (HTTP 대상)을 사용하여 Cloudflare 로그 내보내기 구성
이 방법을 사용하면 중간 저장소 없이 Cloudflare 로그를 Google SecOps로 직접 스트리밍할 수 있습니다.
Google SecOps에서 웹훅 피드 구성
- SIEM 설정> 피드로 이동합니다.
- 새로 추가를 클릭합니다.
- 피드 이름 필드에 피드 이름을 입력합니다 (예:
Cloudflare Webhook
). - 소스 유형으로 웹훅을 선택합니다.
- 로그 유형으로 Cloudflare를 선택합니다.
- 다음을 클릭합니다.
- 다음 입력 파라미터의 값을 지정합니다.
- 분할 구분 기호:
\n
. - 애셋 네임스페이스: 애셋 네임스페이스입니다.
- 수집 라벨: 이 피드의 이벤트에 적용할 라벨입니다.
- 분할 구분 기호:
- 다음을 클릭합니다.
- 확정 화면에서 새 피드 구성을 검토한 다음 제출을 클릭합니다.
- 보안 비밀 키 생성을 클릭하여 이 피드를 인증하기 위한 보안 비밀 키를 생성합니다.
- 이 보안 비밀을 다시 볼 수 없으므로 보안 비밀 키를 복사하여 저장합니다.
- 세부정보 탭으로 이동합니다.
- 엔드포인트 정보 필드에서 피드 엔드포인트 URL을 복사합니다.
- 완료를 클릭합니다.
웹훅 피드에 대한 API 키 만들기
- Google Cloud 콘솔 > API 및 서비스 > 사용자 인증 정보로 이동합니다.
- 사용자 인증 정보 만들기를 클릭한 후 API 키를 선택합니다.
- API 키 수정을 클릭합니다.
- API 제한사항에서 키 제한을 선택합니다.
- 목록에서 Google SecOps API를 선택합니다.
- 저장을 클릭합니다.
- API 키 값을 복사합니다.
Cloudflare LogPush HTTP 대상 구성
- Cloudflare 대시보드에 로그인합니다.
- LogPush와 함께 사용할 엔터프라이즈 계정 또는 도메인을 선택합니다.
- 분석 및 로그 > Logpush로 이동합니다.
- Logpush 작업 만들기를 클릭합니다.
- 도착 페이지 선택에서 HTTP 도착 페이지를 선택합니다.
인증 매개변수가 포함된 HTTP 엔드포인트 URL을 입력합니다.
<ENDPOINT_URL>?header_X-goog-api-key=<API_KEY>&header_X-Webhook-Access-Key=<SECRET_KEY>
다음을 바꿉니다.
<ENDPOINT_URL>
: Google SecOps의 피드 엔드포인트 URL입니다.<API_KEY>
: Google Cloud 콘솔의 API 키 (특수 문자가 포함된 경우 URL 인코딩됨)<SECRET_KEY>
: 웹훅 피드의 보안 비밀 키입니다 (특수 문자가 포함된 경우 URL 인코딩됨).
계속을 클릭합니다.
푸시할 데이터 세트를 선택합니다 (예: HTTP 요청, DNS, 감사, 제로 트러스트, CASB).
logpush 작업을 구성합니다.
- 작업 이름을 입력합니다.
- 선택사항: 로그가 일치하는 경우에서 필터를 구성합니다.
- 다음 필드 보내기에서 포함할 필드를 선택합니다.
- 타임스탬프 형식을 선택합니다 (RFC3 339 권장).
- 필요한 경우 샘플링 레이트를 구성합니다.
제출을 클릭하여 logpush 작업을 만듭니다.
웹훅 통합 확인
구성 후 몇 분 이내에 로그가 Google SecOps에 표시됩니다. 확인 방법은 다음과 같습니다.
- 조사 > SIEM 검색으로 이동합니다.
- 구성된 수집 라벨로 로그를 검색합니다.
- Cloudflare 로그가 올바르게 파싱되고 있는지 확인합니다.
방법 2: Google Cloud Storage를 사용하여 Cloudflare 로그 내보내기 구성
Cloudflare에 로그를 푸시하도록 구성합니다. 여기에는 Cloudflare에 필요한 권한을 부여하는 작업이 포함됩니다.
Google Cloud 버킷 만들기
- Google Cloud 콘솔에 로그인합니다.
- Cloud Storage 버킷 페이지로 이동합니다.
- 만들기를 클릭합니다.
- 버킷 만들기 페이지에서 버킷 정보를 입력합니다.
- 이름: 버킷 이름 요구사항을 충족하는 고유한 이름을 입력합니다 (예:
cloudflare-data
). - 위치 유형: 위치 유형과 지역을 선택합니다.
- 계층적 네임스페이스를 사용 설정하려면 펼치기 화살표를 클릭하여 파일 지향 및 데이터 집약적인 워크로드에 최적화를 펼친 다음 이 버킷에서 계층적 네임스페이스 사용 설정을 선택합니다.
- 이름: 버킷 이름 요구사항을 충족하는 고유한 이름을 입력합니다 (예:
- 만들기를 클릭합니다.
버킷에 권한 부여
- Cloud Storage 콘솔에서 이전에 만든 버킷을 선택합니다.
- 권한 탭을 클릭합니다.
- 액세스 권한 부여를 클릭합니다.
- 스토리지 객체 관리자 권한이 있는 계정
logpush@cloudflare-data.iam.gserviceaccount.com
를 추가합니다. - 저장을 클릭합니다.
Google Cloud Storage에 Cloudflare LogPush 구성
- Cloudflare 대시보드에 로그인합니다.
- LogPush와 함께 사용할 엔터프라이즈 계정 또는 도메인을 선택합니다.
- 분석 및 로그 > Logpush로 이동합니다.
- Logpush 작업 만들기를 클릭합니다.
- 대상 선택에서 Google Cloud Storage를 선택합니다.
- Google Cloud Storage 버킷 경로 (예:
gs://cloudflare-data/logs/
)를 입력합니다. 계속을 클릭합니다.
소유권 토큰을 입력하고 계속을 클릭합니다.
스토리지에 푸시할 데이터 세트를 선택합니다.
logpush 작업을 구성합니다.
- 작업 이름을 입력합니다.
- 로그가 일치하는 경우에서 로그에 포함하거나 제외할 이벤트를 선택할 수 있습니다.
- 다음 필드 보내기에서 푸시할 로그를 선택합니다.
- 타임스탬프 형식을 선택합니다 (RFC 339 권장).
- 필요한 경우 샘플링 레이트를 구성합니다.
제출을 클릭합니다.
Google Cloud Storage에서 Cloudflare 로그를 수집하도록 Google SecOps에서 피드 구성
- SIEM 설정 > 피드로 이동합니다.
- 새로 추가를 클릭합니다.
- 피드 이름 필드에 피드 이름을 입력합니다 (예:
Cloudflare GCS Logs
). - 소스 유형으로 Google Cloud Storage V2를 선택합니다.
- 로그 유형으로 Cloudflare를 선택합니다.
- 서비스 계정 가져오기를 클릭합니다.
- 다음을 클릭합니다.
다음 입력 매개변수의 값을 지정합니다.
- 스토리지 버킷 URI:
gs://my-bucket/<value>/
형식의 Google Cloud 버킷 URL입니다. 이 URL은 후행 슬래시 (/)로 끝나야 합니다. - 소스 삭제 옵션: 환경설정에 따라 삭제 옵션을 선택합니다.
- 최대 파일 기간: 지난 일수 동안 수정된 파일을 포함합니다. 기본값은 180일입니다.
- 애셋 네임스페이스: 애셋 네임스페이스입니다.
- 수집 라벨: 이 피드의 이벤트에 적용할 라벨입니다.
- 스토리지 버킷 URI:
다음을 클릭합니다.
확정 화면에서 새 피드 구성을 검토한 다음 제출을 클릭합니다.
UDM 매핑 테이블
로그 필드 | UDM 매핑 | 논리 |
---|---|---|
ClientIP | read_only_udm.principal.asset.ip read_only_udm.principal.ip |
값은 ClientIP 필드에서 가져옵니다. |
ClientRequestHost | read_only_udm.target.asset.hostname read_only_udm.target.hostname |
값은 ClientRequestHost 필드에서 가져옵니다. |
ClientRequestMethod | read_only_udm.network.http.method | 값은 ClientRequestMethod 필드에서 가져옵니다. |
ClientRequestURI | read_only_udm.target.url | 값은 ClientRequestURI 필드에서 가져옵니다. ClientRequestHost 필드가 비어 있지 않으면 값이 ClientRequestHost 필드와 연결됩니다. |
ClientSrcPort | read_only_udm.principal.port | 값은 ClientSrcPort 필드에서 가져옵니다. |
ClientRequestUserAgent | read_only_udm.network.http.user_agent | 값은 ClientRequestUserAgent 필드에서 가져옵니다. |
ClientSSLCipher | read_only_udm.network.tls.cipher | 값은 ClientSSLCipher 필드에서 가져옵니다. |
ClientSSLProtocol | read_only_udm.network.tls.version | 값은 ClientSSLProtocol 필드에서 가져옵니다. |
국가 | read_only_udm.target.location.country_or_region | 값은 국가 필드에서 가져옵니다. |
CreatedAt | read_only_udm.metadata.event_timestamp | 값은 CreatedAt 필드에서 가져옵니다. |
날짜/시간 | read_only_udm.metadata.event_timestamp | 값은 Datetime 필드에서 가져옵니다. |
DestinationIP | read_only_udm.target.asset.ip read_only_udm.target.ip |
값은 DestinationIP 필드에서 가져옵니다. |
DestinationPort | read_only_udm.target.port | 값은 DestinationPort 필드에서 가져옵니다. |
DeviceID | read_only_udm.principal.asset_id | 값은 DeviceID 필드에서 가져오며 'Cloudflare:'가 앞에 붙습니다. |
DeviceName | read_only_udm.principal.asset.hostname read_only_udm.principal.hostname |
값은 DeviceName 필드에서 가져옵니다. |
DstIP | read_only_udm.target.asset.ip read_only_udm.target.ip |
값은 DstIP 필드에서 가져옵니다. |
DstPort | read_only_udm.target.port | 값은 DstPort 필드에서 가져옵니다. |
EdgeResponseBytes | read_only_udm.network.received_bytes | 값은 EdgeResponseBytes 필드에서 가져옵니다. |
EdgeResponseStatus | read_only_udm.network.http.response_code | 값은 EdgeResponseStatus 필드에서 가져옵니다. |
EdgeServerIP | read_only_udm.target.asset.ip read_only_udm.target.ip |
값은 EdgeServerIP 필드에서 가져옵니다. |
이메일 | read_only_udm.principal.user.email_addresses read_only_udm.target.user.email_addresses |
값은 이메일 필드에서 가져옵니다. |
FirewallMatchesActions | read_only_udm.security_result.action | FirewallMatchesAction 필드가 'allow', 'Allow', 'ALLOW', 'skip', 'SKIP' 또는 'Skip'인 경우 값은 'ALLOW'로 설정되고, FirewallMatchesAction 필드가 'challengeSolved' 또는 'jschallengeSolved'인 경우 'ALLOW_WITH_MODIFICATION'으로 설정되며, FirewallMatchesAction 필드가 'drop' 또는 'block'인 경우 'BLOCK'으로 설정되고, FirewallMatchesAction 필드가 비어 있지 않은 경우 'UNKNOWN_ACTION'으로 설정됩니다. |
FirewallMatchesRuleIDs | read_only_udm.security_result.rule_id | 값은 FirewallMatchesRuleIDs 필드에서 가져옵니다. |
FirewallMatchesSources | read_only_udm.security_result.rule_name | 값은 FirewallMatchesSources 필드에서 가져옵니다. |
HTTPMethod | read_only_udm.network.http.method | 값은 HTTPMethod 필드에서 가져옵니다. |
HTTPHost | read_only_udm.target.hostname | 값은 HTTPHost 필드에서 가져옵니다. |
HTTPVersion | read_only_udm.network.application_protocol | 값은 HTTPVersion 필드에서 가져옵니다. 값에 'HTTP'가 포함된 경우 'HTTP'로 대체됩니다. |
IPAddress | read_only_udm.target.asset.ip read_only_udm.target.ip |
값은 IPAddress 필드에서 가져옵니다. |
IsIsolated | read_only_udm.about.labels read_only_udm.security_result.about.resource.attribute.labels |
값은 IsIsolated 필드에서 가져오며 문자열로 변환됩니다. |
위치 | read_only_udm.principal.location.name | 값은 위치 필드에서 가져옵니다. |
OriginIP | read_only_udm.intermediary.ip read_only_udm.target.asset.ip read_only_udm.target.ip |
값은 OriginIP 필드에서 가져옵니다. |
OriginPort | read_only_udm.target.port | 값은 OriginPort 필드에서 가져옵니다. |
OwnerID | read_only_udm.target.user.product_object_id | 값은 OwnerID 필드에서 가져옵니다. |
정책 | read_only_udm.security_result.rule_name | 값은 정책 필드에서 가져옵니다. |
PolicyID | read_only_udm.security_result.rule_id | 값은 PolicyID 필드에서 가져옵니다. |
PolicyName | read_only_udm.security_result.rule_name | 값은 PolicyName 필드에서 가져옵니다. |
프로토콜 | read_only_udm.network.ip_protocol | 값은 프로토콜 필드에서 가져오며 대문자로 변환됩니다. |
QueryCategoryIDs | read_only_udm.security_result.about.labels read_only_udm.security_result.about.resource.attribute.labels |
값은 QueryCategoryIDs 필드에서 가져옵니다. |
QueryName | read_only_udm.network.dns.questions.name | 값은 QueryName 필드에서 가져옵니다. |
QueryNameReversed | read_only_udm.network.dns.questions.name | 값은 QueryNameReversed 필드에서 가져옵니다. |
QuerySize | read_only_udm.network.sent_bytes | 값은 QuerySize 필드에서 가져옵니다. |
QueryType | read_only_udm.network.dns.questions.type | 값은 QueryType 필드에서 가져옵니다. 값이 알려진 DNS 레코드 유형 중 하나인 경우 해당 숫자 값에 매핑됩니다. 그렇지 않으면 값이 문자열로 변환됩니다. |
RData | read_only_udm.network.dns.answers | 값은 RData 필드에서 가져옵니다. type 필드가 부호 없는 정수로 변환됩니다. |
RayID | read_only_udm.metadata.product_log_id | 값은 RayID 필드에서 가져옵니다. |
리퍼러 | read_only_udm.network.http.referral_url | 값은 Referer 필드에서 가져옵니다. |
RequestID | read_only_udm.metadata.product_log_id | 값은 RequestID 필드에서 가져옵니다. |
ResolverDecision | read_only_udm.security_result.summary | 값은 ResolverDecision 필드에서 가져옵니다. |
ResourceID | read_only_udm.target.resource.id read_only_udm.target.resource.product_object_id |
값은 ResourceID 필드에서 가져옵니다. |
ResourceType | read_only_udm.target.resource.resource_subtype | 값은 ResourceType 필드에서 가져옵니다. |
SNI | read_only_udm.network.tls.client.server_name | 값은 SNI 필드에서 가져옵니다. |
SecurityAction | read_only_udm.security_result.action | SecurityAction 필드가 비어 있거나 sec_action 필드가 비어 있으면 값이 'ALLOW'로 설정되고, SecurityAction 필드가 'challengeSolved' 또는 'jschallengeSolved'이면 'ALLOW_WITH_MODIFICATION'으로 설정되고, SecurityAction 필드가 'drop' 또는 'block'이면 'BLOCK'으로 설정됩니다. |
SecurityLevel | read_only_udm.security_result.severity | 이 값은 SecurityLevel 필드에서 가져오며 해당 UDM 심각도 값에 매핑됩니다. |
SessionID | read_only_udm.network.session_id | 값은 SessionID 필드에서 가져옵니다. |
SessionStartTime | read_only_udm.metadata.event_timestamp | 값은 SessionStartTime 필드에서 가져옵니다. |
SourceIP | read_only_udm.principal.asset.ip read_only_udm.principal.ip read_only_udm.src.asset.ip read_only_udm.src.ip |
값은 SourceIP 필드에서 가져옵니다. |
SourcePort | read_only_udm.principal.port read_only_udm.src.port |
값은 SourcePort 필드에서 가져옵니다. |
SrcIP | read_only_udm.principal.asset.ip read_only_udm.principal.ip |
값은 SrcIP 필드에서 가져옵니다. |
SrcPort | read_only_udm.principal.port | 값은 SrcPort 필드에서 가져옵니다. |
TemporaryAccessDuration | read_only_udm.network.session_duration.seconds | 값은 TemporaryAccessDuration 필드에서 가져옵니다. |
타임스탬프 | read_only_udm.metadata.event_timestamp | 값은 타임스탬프 필드에서 가져옵니다. |
전송 | read_only_udm.network.ip_protocol | 값은 전송 필드에서 가져오고 대문자로 변환됩니다. |
URL | read_only_udm.target.url | 값은 URL 필드에서 가져옵니다. |
UserAgent | read_only_udm.network.http.user_agent | 값은 UserAgent 필드에서 가져옵니다. |
UserID | read_only_udm.principal.user.product_object_id | 값은 UserID 필드에서 가져옵니다. |
UserUID | read_only_udm.target.user.product_object_id | 값은 UserUID 필드에서 가져옵니다. |
VirtualNetworkID | read_only_udm.principal.resource.product_object_id | 값은 VirtualNetworkID 필드에서 가져옵니다. |
WAFAction | read_only_udm.security_result.about.labels read_only_udm.security_result.about.resource.attribute.labels |
값은 WAFAction 필드에서 가져옵니다. |
WAFAttackScore | read_only_udm.security_result.about.resource.attribute.labels | 값은 WAFAttackScore 필드에서 가져옵니다. |
WAFFlags | read_only_udm.security_result.about.resource.attribute.labels | 값은 WAFFlags 필드에서 가져옵니다. |
WAFProfile | read_only_udm.security_result.about.labels read_only_udm.security_result.about.resource.attribute.labels |
값은 WAFProfile 필드에서 가져옵니다. |
WAFRCEAttackScore | read_only_udm.security_result.about.resource.attribute.labels | 값은 WAFRCEAttackScore 필드에서 가져옵니다. |
WAFRuleID | read_only_udm.security_result.about.labels read_only_udm.security_result.about.resource.attribute.labels read_only_udm.security_result.threat_id |
값은 WAFRuleID 필드에서 가져옵니다. |
WAFRuleMessage | read_only_udm.security_result.rule_name read_only_udm.security_result.threat_name |
값은 WAFRuleMessage 필드에서 가져옵니다. |
WAFSQLiAttackScore | read_only_udm.security_result.about.resource.attribute.labels | 값은 WAFSQLiAttackScore 필드에서 가져옵니다. |
WAFXSSAttackScore | read_only_udm.security_result.about.resource.attribute.labels | 값은 WAFXSSAttackScore 필드에서 가져옵니다. |
ZoneID | read_only_udm.additional.fields | 값은 ZoneID 필드에서 가져옵니다. |
read_only_udm.metadata.log_type | 값은 'CLOUDFLARE'로 설정됩니다. | |
read_only_udm.metadata.product_name | 로그가 DNS 로그인 경우 값은 'Cloudflare Gateway DNS'로 설정되고, 로그가 게이트웨이 HTTP 로그인 경우 'Cloudflare Gateway HTTP'로 설정되고, 로그가 감사 로그인 경우 'Cloudflare Audit'로 설정되고, 그 외의 경우 'Web Application Firewall'로 설정됩니다. | |
read_only_udm.metadata.vendor_name | 값은 'Cloudflare'로 설정됩니다. | |
read_only_udm.network.application_protocol | 로그가 DNS 로그인 경우 값은 'DNS'로 설정되고, HTTPVersion 필드에 'HTTP'가 포함된 경우 'HTTP'로 설정되며, Protocol 필드가 비어 있지 않고 'tls' 또는 'TLS'가 아닌 경우 Protocol 필드의 값이 대문자로 변환됩니다. | |
read_only_udm.network.direction | EgressIP 필드가 비어 있지 않으면 값이 'OUTBOUND'로 설정됩니다. | |
read_only_udm.network.http.parsed_user_agent | 값은 UserAgent 또는 ClientRequestUserAgent 필드에서 가져오며 parseduseragent 필터를 사용하여 파싱됩니다. | |
read_only_udm.extensions.auth.type | 작업 필드가 'login' 또는 'logout'인 경우 값은 'MACHINE'으로 설정됩니다. | |
read_only_udm.metadata.event_type | 로그가 DNS 로그인 경우 값은 'NETWORK_DNS', 로그가 게이트웨이 HTTP 로그인 경우 'NETWORK_CONNECTION', 로그가 감사 로그이고 ActorIP 및 ActorEmail 필드가 비어 있는 경우 'USER_RESOURCE_ACCESS', 로그가 감사 로그이고 ResourceType 및 newvalue 필드가 비어 있지 않은 경우 'USER_RESOURCE_UPDATE_CONTENT', Action 필드가 'login'인 경우 'USER_LOGIN', Action 필드가 'logout'인 경우 'USER_LOGOUT', Email 필드가 비어 있지 않고 이메일 주소 형식과 일치하는 경우 'USER_RESOURCE_ACCESS', EgressIP 및 SourceIP 필드가 비어 있지 않거나 OriginIP 및 SourceIP 필드가 비어 있지 않은 경우 'NETWORK_CONNECTION'으로 설정됩니다. | |
read_only_udm.target.file.mime_type | 값은 EdgeResponseContentType 필드에서 가져옵니다. | |
read_only_udm.target.location.country_or_region | 값은 국가 필드에서 가져옵니다. | |
read_only_udm.target.resource.id | 값은 AccountID 필드 또는 ResourceID 필드에서 가져옵니다. | |
read_only_udm.target.resource.product_object_id | 값은 AccountID 필드, AppUUID 필드 또는 ResourceID 필드에서 가져옵니다. | |
read_only_udm.target.user.product_object_id | 값은 OwnerID 필드 또는 UserUID 필드에서 가져옵니다. |
도움이 더 필요하신가요? 커뮤니티 회원 및 Google SecOps 전문가로부터 답변을 받으세요.