WordPress CMS 로그 수집
개요
이 파서는 JSON 또는 일반 텍스트 형식 메시지에서 WordPress CMS 로그를 추출합니다. JSON 형식 로그와 비JSON 형식 로그를 모두 처리하여 관련 필드를 파싱하고 사용자 세부정보, 네트워크 정보, 리소스 속성, 보안 결과 세부정보를 포함하여 UDM에 매핑합니다. 또한 파서는 데이터 유형 변환, 필드 병합, Kubernetes 및 기타 리소스의 특정 로그 패턴 처리와 같은 여러 데이터 변환을 실행합니다.
시작하기 전에
- Google SecOps 인스턴스가 있는지 확인합니다.
- WordPress 웹사이트에 대한 권한이 있는지 확인합니다.
- 웹훅 기능을 사용 설정하는 플러그인 (예: WP Webhooks)
WordPress 로그를 수집하도록 Google SecOps에서 피드 구성
- SIEM 설정 > 피드로 이동합니다.
- 새로 추가를 클릭합니다.
- 피드 이름 필드에 피드 이름을 입력합니다 (예: Wordpress Logs).
- 소스 유형으로 Webhook을 선택합니다.
- 로그 유형으로 Wordpress를 선택합니다.
- 다음을 클릭합니다.
- 선택사항: 다음 입력 매개변수의 값을 지정합니다.
- 분할 구분 기호: 로그 줄을 구분하는 데 사용되는 구분 기호입니다(예:
\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
: 피드를 인증하기 위해 생성한 보안 비밀 키입니다.
WordPress 웹훅 구성
- WordPress 플러그인 디렉터리를 통해 WP Webhooks 플러그인 (또는 선택한 webhook 플러그인)을 설치하고 활성화합니다.
- WordPress 관리자 메뉴(일반적으로 설정 아래에 있음)의 WP Webhooks 하위 메뉴로 이동합니다.
- 상단 메뉴에서 데이터 보내기를 클릭합니다.
- 웹훅을 트리거할 WordPress 작업을 선택합니다. 일반적인 예로는 publish_post (새 게시물이 게시될 때), user_register (신규 사용자가 등록할 때), comment_post (새 댓글이 게시될 때)가 있습니다. 이는 선택하여 Google SecOps로 전송하는 데이터에 따라 다릅니다.
- 웹훅 URL 추가를 클릭합니다.
- 웹훅을 구성합니다.
- 이름: 웹훅에 설명이 포함된 이름을 지정합니다 (예: Google SecOps 피드).
- 웹훅 URL: Google SecOps 엔드포인트 URL을 붙여넣습니다.
- Save Webhook(웹훅 저장)을 클릭합니다.
UDM 매핑 표
로그 필드 | UDM 매핑 | 논리 |
---|---|---|
ClientIP |
principal.ip |
클라이언트의 IP 주소는 원시 로그의 ClientIP 필드에서 추출됩니다. |
Code |
target.resource.attribute.labels.key |
'Code' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
Code |
target.resource.attribute.labels.value |
원시 로그의 Code 필드 값이 target.resource.attribute.labels 객체의 값으로 할당됩니다. |
CurrentUserID |
target.user.userid |
원시 로그의 CurrentUserID 가 문자열로 변환되고 target.user.userid 필드에 매핑됩니다. |
EditUserLink |
target.url |
원시 로그의 EditUserLink 가 target.url 필드에 매핑됩니다. |
EventType |
metadata.product_event_type |
원시 로그의 EventType 가 metadata.product_event_type 필드에 매핑됩니다. |
FirstName |
target.user.first_name |
원시 로그의 FirstName 가 target.user.first_name 필드에 매핑됩니다. |
insertId |
metadata.product_log_id |
원시 로그의 insertId 가 metadata.product_log_id 필드에 매핑됩니다. |
labels.compute.googleapis.com/resource_name |
additional.fields.key |
'Resource Name' 값이 additional.fields 객체에 키로 할당됩니다. |
labels.compute.googleapis.com/resource_name |
additional.fields.value.string_value |
원시 로그의 labels.compute.googleapis.com/resource_name 값은 additional.fields 객체에 문자열 값으로 할당됩니다. |
labels.k8s-pod/app_kubernetes_io/instance |
target.resource.attribute.labels.key |
'Kubernetes IO Instance' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
labels.k8s-pod/app_kubernetes_io/instance |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/app_kubernetes_io/instance 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
labels.k8s-pod/app_kubernetes_io/managed-by |
target.resource.attribute.labels.key |
'Kubernetes IO Instance Manager' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
labels.k8s-pod/app_kubernetes_io/managed-by |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/app_kubernetes_io/managed-by 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
labels.k8s-pod/app_kubernetes_io/name |
target.resource.attribute.labels.key |
'Kubernetes IO 인스턴스 이름' 값이 target.resource.attribute.labels 객체에 키로 할당됩니다. |
labels.k8s-pod/app_kubernetes_io/name |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/app_kubernetes_io/name 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
labels.k8s-pod/controller-revision-hash |
target.resource.attribute.labels.key |
'Controller Revision Hash' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
labels.k8s-pod/controller-revision-hash |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/controller-revision-hash 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
labels.k8s-pod/helm_sh/chart |
target.resource.attribute.labels.key |
'Kubernetes IO Instance Manager SH' 값이 target.resource.attribute.labels 객체에 키로 할당됩니다. |
labels.k8s-pod/helm_sh/chart |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/helm_sh/chart 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
labels.k8s-pod/k8s-app |
target.resource.attribute.labels.key |
'Application' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
labels.k8s-pod/k8s-app |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/k8s-app 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
labels.k8s-pod/pod-template-generation |
target.resource.attribute.labels.key |
'Pod 템플릿 생성' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
labels.k8s-pod/pod-template-generation |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/pod-template-generation 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
labels.k8s-pod/pod-template-hash |
target.resource.attribute.labels.key |
'Pod 템플릿 해시' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
labels.k8s-pod/pod-template-hash |
target.resource.attribute.labels.value |
원시 로그의 labels.k8s-pod/pod-template-hash 값이 target.resource.attribute.labels 객체에 값으로 할당됩니다. |
LastName |
target.user.last_name |
원시 로그의 LastName 가 target.user.last_name 필드에 매핑됩니다. |
logName |
target.resource.attribute.labels.key |
'Log Name' 값이 target.resource.attribute.labels 객체의 키로 할당됩니다. |
logName |
target.resource.attribute.labels.value |
원시 로그의 logName 필드 값이 target.resource.attribute.labels 객체의 값으로 할당됩니다. |
receiveTimestamp |
metadata.event_timestamp |
원시 로그의 receiveTimestamp 가 파싱되어 metadata.event_timestamp 필드에 매핑됩니다. |
resource.labels.cluster_name |
additional.fields.key |
'Cluster Name' 값이 additional.fields 객체의 키로 할당됩니다. |
resource.labels.cluster_name |
additional.fields.value.string_value |
원시 로그의 resource.labels.cluster_name 값은 additional.fields 객체에 문자열 값으로 할당됩니다. |
resource.labels.cluster_name |
target.resource.resource_type |
resource.labels.cluster_name 이 있으면 값 'CLUSTER'가 target.resource.resource_type 에 할당됩니다. |
resource.labels.container_name |
metadata.product_event_type |
resource.type 이 'k8s_container'인 경우 resource.labels.namespace_name 와 함께 resource.labels.container_name 의 값이 metadata.product_event_type 을 구성하는 데 사용됩니다. |
resource.labels.container_name |
target.resource.name |
원시 로그의 resource.labels.container_name 값이 target.resource.name 필드에 할당됩니다. |
resource.labels.location |
target.location.country_or_region |
원시 로그의 resource.labels.location 값이 target.location.country_or_region 필드에 할당됩니다. |
resource.labels.namespace_name |
additional.fields.key |
'네임스페이스 이름' 값이 additional.fields 객체에 키로 할당됩니다. |
resource.labels.namespace_name |
additional.fields.value.string_value |
원시 로그의 resource.labels.namespace_name 값은 additional.fields 객체에 문자열 값으로 할당됩니다. |
resource.labels.namespace_name |
metadata.product_event_type |
resource.type 이 'k8s_container'인 경우 resource.labels.container_name 와 함께 resource.labels.namespace_name 의 값이 metadata.product_event_type 을 구성하는 데 사용됩니다. |
resource.labels.node_name |
metadata.product_event_type |
resource.type 이 'k8s_node'인 경우 resource.labels.node_name 값이 metadata.product_event_type 를 생성하는 데 사용됩니다. |
resource.labels.pod_name |
additional.fields.key |
'Pod Name' 값이 additional.fields 객체의 키로 할당됩니다. |
resource.labels.pod_name |
additional.fields.value.string_value |
원시 로그의 resource.labels.pod_name 값은 additional.fields 객체에 문자열 값으로 할당됩니다. |
resource.labels.project_id |
additional.fields.key |
'Project Id' 값이 additional.fields 객체의 키로 할당됩니다. |
resource.labels.project_id |
additional.fields.value.string_value |
원시 로그의 resource.labels.project_id 값은 additional.fields 객체에 문자열 값으로 할당됩니다. |
resource.type |
target.resource.resource_subtype |
원시 로그의 resource.type 값이 target.resource.resource_subtype 필드에 할당됩니다. |
Roles |
target.user.user_role |
원시 로그의 Roles 필드가 대문자로 변환되고 target.user.user_role 필드에 매핑됩니다. |
SessionID |
network.session_id |
원시 로그의 SessionID 가 network.session_id 필드에 매핑됩니다. |
sev |
security_result.severity |
sev 필드의 값에 따라 security_result.severity 의 값이 결정됩니다. 'INFO' 또는 'NOTICE'는 'INFORMATIONAL'에 매핑되고, 'WARN'은 'MEDIUM'에 매핑되며, 'ERR'은 'ERROR'에 매핑됩니다. |
TargetUsername |
target.user.user_display_name |
원시 로그의 TargetUsername 가 target.user.user_display_name 필드에 매핑됩니다. |
textPayload |
metadata.description |
resource.type 가 'k8s_node'인 경우 textPayload 값이 metadata.description 필드에 매핑됩니다. |
textPayload |
network.application_protocol |
프로토콜 (예: HTTP)은 grok 패턴을 사용하여 textPayload 필드에서 추출됩니다. |
textPayload |
network.http.method |
HTTP 메서드 (예: GET, POST)는 grok 패턴을 사용하여 textPayload 필드에서 추출됩니다. |
textPayload |
network.http.referral_url |
URL은 grok 패턴을 사용하여 textPayload 필드에서 추출됩니다. |
textPayload |
network.http.response_code |
HTTP 응답 코드는 grok 패턴을 사용하여 textPayload 필드에서 추출되고 정수로 변환됩니다. |
textPayload |
network.received_bytes |
수신된 바이트는 grok 패턴을 사용하여 textPayload 필드에서 추출되고 부호 없는 정수로 변환됩니다. |
textPayload |
principal.ip |
소스 IP 주소는 grok 패턴을 사용하여 textPayload 필드에서 추출됩니다. |
textPayload |
security_result.description |
설명은 grok 패턴을 사용하여 textPayload 필드에서 추출됩니다. |
textPayload |
target.file.full_path |
경로는 grok 패턴을 사용하여 textPayload 필드에서 추출됩니다. |
UserAgent |
network.http.user_agent |
원시 로그의 UserAgent 가 network.http.user_agent 필드에 매핑됩니다. 'USER_RESOURCE_ACCESS' 값이 metadata.event_type 에 할당됩니다. |
변경사항
2024-05-07
- 버그 수정:
- 파싱되지 않고 삭제된 로그를 파싱하도록 파서 로직을 변경했습니다.
2023-05-25
- 파서를 새로 만들었습니다.