Duo 사용자 컨텍스트 로그 수집
파서 버전: 1.0
다음에서 지원:
Google SecOps
SIEM
이 문서에서는 API를 사용하여 Duo 사용자 컨텍스트 로그를 Google Security Operations로 수집하는 방법을 설명합니다. 파서는 JSON 데이터를 처리하여 사용자 정보(사용자 이름의 별칭을 이메일 주소, 그룹, 전화번호, 기기 세부정보로 지정하는 것 포함)를 UDM에 매핑하고 사용자 계정 상태를 캡처합니다. 또한 중첩된 데이터 구조를 처리하고 여러 데이터 변환 및 병합을 수행하여 최종 UDM 이벤트를 만듭니다.
시작하기 전에
다음 기본 요건이 충족되었는지 확인합니다.
- Google SecOps 인스턴스
- Duo 관리 패널에 대한 권한 있는 액세스
Admin API 애플리케이션 구성 및 키 가져오기
- 관리자로 Duo 관리 패널에 로그인합니다.
- 왼쪽 사이드바에서 Applications(애플리케이션) > Manage Applications(애플리케이션 관리)를 클릭합니다.
- Add Application(애플리케이션 추가) 버튼을 누릅니다.
- 검색창에 Admin API를 입력하고 Duo Admin API 옆에 있는 추가를 클릭합니다.
- 다음 화면에 다음 정보가 표시됩니다.
- 통합 키:(
DIYYYYYYYYYYYYYY와 같은 문자열) - 보안 비밀 키: 40자(영문 기준) 문자열입니다.
- API 호스트 이름: 예를 들면
api-abcd1234.duosecurity.com입니다.
- 통합 키:(
- Integration Key(통합 키), Secret Key(보안 비밀 키), API hostname(API 호스트 이름)을 복사하여 안전한 위치에 저장합니다.
- 설정으로 스크롤하고 권한을 리소스 읽기 권한 부여로 설정합니다.
- 변경사항 저장을 클릭합니다.
피드 설정
- 설정 > 데이터 관리 > 피드로 이동합니다. SIEM 전용 플랫폼을 사용하는 경우 설정 > 피드로 이동합니다.
- + 새 피드 추가를 클릭합니다.
- 피드 이름 필드에 피드 이름을 입력합니다(예:
Duo Users Logs). - 소스 유형으로 서드 파티 API를 선택합니다.
- Duo 사용자 컨텍스트 로그 유형을 선택합니다.
- 다음을 클릭합니다.
- 다음 입력 파라미터의 값을 지정합니다.
- 사용자 이름: 이전에 복사한 통합 키를 입력합니다.
- 보안 비밀: 이전에 복사한 보안 비밀 키를 입력합니다.
- API 호스트 이름: Duo API 서버 URL을 입력합니다(예:
api-abcd1234.duosecurity.com). - 애셋 네임스페이스: 애셋 네임스페이스입니다.
- 수집 라벨: 이 피드의 이벤트에 적용되는 라벨입니다.
- 다음을 클릭합니다.
- 확정 화면에서 피드 구성을 검토한 다음 제출을 클릭합니다.
UDM 매핑 테이블
| 로그 필드 | UDM 매핑 | 로직 |
|---|---|---|
access_device.browser |
event.idm.entity.entity.resource.attribute.labels.value |
값은 access_device.browser 필드에서 직접 가져오거나, 비어 있는 경우 surfaced_auth.access_device.browser에서 가져옵니다. 키가 'access_device browser'로 설정됩니다. |
access_device.browser_version |
event.idm.entity.entity.resource.attribute.labels.value |
값은 access_device.browser_version 필드에서 직접 가져오거나, 비어 있는 경우 surfaced_auth.access_device.browser_version에서 가져옵니다. 키는 'access_device browser_version'으로 설정됩니다. |
access_device.ip.address |
event.idm.entity.entity.ip |
값은 access_device.ip.address 필드에서 직접 가져오거나, 비어 있는 경우 surfaced_auth.access_device.ip에서 가져옵니다. |
access_device.location.city |
event.idm.entity.entity.location.city |
값은 access_device.location.city 필드에서 직접 가져오거나, 비어 있는 경우 surfaced_auth.access_device.location.city에서 가져옵니다. |
access_device.location.country |
event.idm.entity.entity.location.country_or_region |
값은 access_device.location.country 필드에서 직접 가져오거나, 비어 있는 경우 surfaced_auth.access_device.location.country에서 가져옵니다. |
access_device.location.state |
event.idm.entity.entity.location.state |
값은 access_device.location.state 필드에서 직접 가져오거나, 비어 있는 경우 surfaced_auth.access_device.location.state에서 가져옵니다. |
access_device.os |
event.idm.entity.entity.asset.platform_software.platform |
값은 access_device.os 필드에서 파생되거나, 비어 있는 경우 surfaced_auth.access_device.os에서 파생됩니다. 값(대소문자를 구분하지 않음)이 'ios' 또는 'mac'과 일치하면 UDM 필드가 'MAC'으로 설정됩니다. 'windows'와 일치하면 UDM 필드가 'WINDOWS'로 설정됩니다. 'linux'와 일치하면 UDM 필드가 'LINUX'로 설정됩니다. |
access_device.os_version |
event.idm.entity.entity.asset.platform_software.platform_version |
값은 access_device.os_version 필드에서 직접 가져오거나, 비어 있는 경우 surfaced_auth.access_device.os_version에서 가져옵니다. |
action.details |
event.idm.entity.sec_result.action_details |
action가 비어 있으면 이 필드에서 값을 가져옵니다. |
action.name |
event.idm.entity.sec_result.detection_fields.value |
값은 필드에서 직접 가져옵니다. 키가 'action_name'으로 설정됩니다. |
activity_id |
event.idm.entity.sec_result.detection_fields.value |
값은 필드에서 직접 가져옵니다. 키가 'activity_id'로 설정됩니다. |
actor.details.created |
event.idm.entity.entity.user.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'created'로 설정됩니다. |
actor.details.email |
event.idm.entity.entity.user.email_addresses |
값은 필드에서 직접 가져옵니다. |
actor.details.groups.key |
event.idm.entity.entity.user.group_identifiers |
값은 필드에서 직접 가져옵니다. |
actor.details.groups.name |
event.idm.entity.entity.user.group_identifiers |
값은 필드에서 직접 가져옵니다. |
actor.details.last_login |
event.idm.entity.entity.user.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'last_login'으로 설정됩니다. |
actor.details.status |
event.idm.entity.entity.user.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'status'로 설정됩니다. |
actor.key |
event.idm.entity.entity.resource.product_object_id |
값은 필드에서 직접 가져옵니다. |
actor.name |
event.idm.entity.entity.user.user_display_name |
값은 필드에서 직접 가져오거나 필드가 비어 있는 경우 surfaced_auth.user.name에서 가져옵니다. |
actor.type |
event.idm.entity.entity.user.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'actor type'으로 설정됩니다. |
akey |
event.idm.entity.metadata.product_entity_id |
값은 필드에서 직접 가져오거나 akey가 비어 있는 경우 sekey입니다. |
application |
event.idm.entity.entity.application |
값은 필드에서 직접 가져옵니다. |
collection_time.seconds, create_time.seconds |
event.idm.entity.metadata.collected_timestamp.seconds, event.timestamp.seconds |
collection_time.seconds 및 create_time.seconds 중 더 큰 값이 collected_timestamp.seconds 및 최상위 timestamp.seconds 모두에 사용됩니다. |
collection_time.nanos, create_time.nanos |
event.idm.entity.metadata.collected_timestamp.nanos, event.timestamp.nanos |
collection_time.seconds 및 create_time.seconds 중 더 큰 값에 해당하는 나노초 값이 collected_timestamp.nanos 및 최상위 timestamp.nanos 모두에 사용됩니다. |
email |
event.idm.entity.entity.user.email_addresses |
값은 필드에서 직접 가져옵니다. |
explanations |
event.idm.entity.entity.resource.attribute.labels |
explanations 배열의 각 객체 내에 있는 키-값 쌍은 라벨로 변환됩니다. 각 라벨의 키 앞에는 'explanation'이 추가됩니다. |
firstname |
event.idm.entity.entity.user.first_name |
값은 필드에서 직접 가져옵니다. |
from_common_netblock |
event.idm.entity.entity.resource.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키는 'from_common_netblock'으로 설정됩니다. |
from_new_user |
event.idm.entity.entity.resource.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키는 'from_new_user'로 설정됩니다. |
groups.N.name (N=0..10) |
event.idm.entity.entity.user.group_identifiers |
값은 필드에서 직접 가져옵니다. |
lastname |
event.idm.entity.entity.user.last_name |
값은 필드에서 직접 가져옵니다. |
low_risk_ip |
event.idm.entity.entity.resource.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'low_risk_ip'로 설정됩니다. |
phones.0.model |
event.idm.entity.relations.entity.asset.hardware.model |
값은 필드에서 직접 가져옵니다. |
phones.0.number |
event.idm.entity.entity.user.phone_numbers |
값은 필드에서 직접 가져옵니다. |
phones.0.phone_id |
event.idm.entity.relations.entity.asset.product_object_id |
값은 필드에서 직접 가져옵니다. |
phones.0.platform |
event.idm.entity.relations.entity.asset.hardware.manufacturer |
값은 필드에서 직접 가져옵니다. |
priority_event |
event.idm.entity.entity.resource.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키는 'priority_event'로 설정됩니다. |
realname |
event.idm.entity.entity.user.user_display_name |
값은 필드에서 직접 가져옵니다. |
sekey |
event.idm.entity.metadata.product_entity_id |
akey가 비어 있으면 필드에서 직접 값을 가져옵니다. |
state |
event.idm.entity.entity.resource.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'state'로 설정됩니다. |
status |
event.idm.entity.entity.user.attribute.labels.value, event.idm.entity.entity.user.user_authentication_status |
값은 필드에서 직접 가져옵니다. 라벨의 키는 'status'로 설정됩니다. 이 값은 user_authentication_status를 결정하는 데도 사용됩니다. 'active' 및 'bypass'는 'ACTIVE'에 매핑되고, 'disabled' 및 'pending deletion'은 'SUSPENDED'에 매핑되며, 'locked out'은 'NO_ACTIVE_CREDENTIALS'에 매핑됩니다. |
surfaced_auth.access_device.browser |
event.idm.entity.entity.resource.attribute.labels.value |
access_device.browser가 비어 있으면 이 필드에서 값을 가져옵니다. 키가 'surfaced_auth access_device browser'로 설정됩니다. |
surfaced_auth.access_device.browser_version |
event.idm.entity.entity.resource.attribute.labels.value |
access_device.browser_version가 비어 있으면 이 필드에서 값을 가져옵니다. 키가 'surfaced_auth access_device browser_version'으로 설정됩니다. |
surfaced_auth.access_device.ip |
event.idm.entity.entity.ip |
access_device.ip.address가 비어 있으면 이 필드에서 값을 가져옵니다. |
surfaced_auth.access_device.location.city |
event.idm.entity.entity.location.city |
access_device.location.city가 비어 있으면 이 필드에서 값을 가져옵니다. |
surfaced_auth.access_device.location.country |
event.idm.entity.entity.location.country_or_region |
access_device.location.country가 비어 있으면 이 필드에서 값을 가져옵니다. |
surfaced_auth.access_device.location.state |
event.idm.entity.entity.location.state |
access_device.location.state가 비어 있으면 이 필드에서 값을 가져옵니다. |
surfaced_auth.access_device.os |
event.idm.entity.entity.asset.platform_software.platform |
access_device.os가 비어 있으면 이 필드에서 값을 가져옵니다. UDM 필드에 매핑하는 로직은 access_device.os와 동일합니다. |
surfaced_auth.access_device.os_version |
event.idm.entity.entity.asset.platform_software.platform_version |
access_device.os_version가 비어 있으면 이 필드에서 값을 가져옵니다. |
surfaced_auth.user.key |
event.idm.entity.entity.user.userid |
username가 비어 있으면 이 필드에서 값을 가져옵니다. |
surfaced_auth.user.name |
event.idm.entity.entity.user.user_display_name |
actor.name가 비어 있으면 이 필드에서 값을 가져옵니다. |
target.details.biometrics_status |
event.idm.entity.entity.asset.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'biometrics_status'로 설정되어 있습니다. |
target.details.country_code |
event.idm.entity.entity.asset.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'country_code'로 설정됩니다. |
target.details.extension |
event.idm.entity.entity.asset.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'extension'으로 설정됩니다. |
target.details.manufacturer |
event.idm.entity.entity.asset.hardware.manufacturer |
값은 필드에서 직접 가져옵니다. |
target.details.model |
event.idm.entity.entity.asset.hardware.model |
값은 필드에서 직접 가져옵니다. |
target.details.number |
event.idm.entity.entity.user.phone_numbers |
값은 필드에서 직접 가져옵니다. |
target.details.os |
event.idm.entity.entity.asset.software.name |
값은 필드에서 직접 가져옵니다. |
target.details.os_version |
event.idm.entity.entity.asset.software.version |
값은 필드에서 직접 가져옵니다. |
target.details.passcode_status |
event.idm.entity.entity.asset.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'passcode_status'로 설정됩니다. |
target.details.tampered_status |
event.idm.entity.entity.asset.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'tampered_status'로 설정됩니다. |
target.key |
event.idm.entity.entity.asset.asset_id |
값은 필드에서 직접 가져옵니다. |
target.name |
event.idm.entity.entity.asset.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키는 'name'으로 설정됩니다. |
target.type |
event.idm.entity.entity.asset.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'type'으로 설정됩니다. |
triage_event_uri |
event.idm.entity.entity.url |
값은 필드에서 직접 가져옵니다. |
triaged_as_interesting |
event.idm.entity.entity.resource.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'triaged_as_interesting'으로 설정됩니다. |
ts |
event.timestamp.seconds, event.idm.entity.metadata.collected_timestamp.seconds |
타임스탬프는 이 필드가 있는 경우 ISO8601 또는 RFC 3339 형식을 사용하여 이 필드에서 파싱됩니다. 추출된 초 및 나노초는 최상위 timestamp 및 collected_timestamp 모두에 사용됩니다. |
type |
event.idm.entity.entity.resource.attribute.labels.value |
값은 필드에서 직접 가져옵니다. 키가 'type'으로 설정됩니다. |
user_id |
event.idm.entity.metadata.product_entity_id |
값은 필드에서 직접 가져옵니다. |
username |
event.idm.entity.entity.user.userid |
값은 필드에서 직접 가져오거나 username가 비어 있는 경우 surfaced_auth.user.key입니다. |
| (파서 로직) | event.idm.entity.metadata.vendor_name |
'Duo'로 하드코딩됩니다. |
| (파서 로직) | event.idm.entity.metadata.product_name |
'Duo User Context'로 하드코딩됩니다. |
| (파서 로직) | event.idm.entity.metadata.entity_type |
다른 필드의 존재 여부에 따라 결정됩니다. user_present가 true이면 'USER'로 설정됩니다. asset_mid_present가 true이면 'ASSET'으로 설정됩니다. ip_present가 true이면 'IP_ADDRESS'로 설정됩니다. resource_present가 true이면 'RESOURCE'로 설정됩니다. 그렇지 않으면 'UNKNOWN_ENTITYTYPE'으로 설정됩니다. |
| (파서 로직) | event.idm.entity.relations.entity_type |
phones[0]가 비어 있지 않으면 'ASSET'으로 설정합니다. |
| (파서 로직) | event.idm.entity.relations.relationship |
phones[0]가 비어 있지 않으면 'OWNS'로 설정됩니다. |
| (파서 로직) | event.idm.entity.relations.entity.asset.type |
phones[0]가 비어 있지 않으면 'MOBILE'로 설정됩니다. |
변경 로그
도움이 더 필요하신가요? 커뮤니티 회원 및 Google SecOps 전문가에게 문의하여 답변을 받으세요.