Standalone audit logging
출처: 문서
본문
독립형 감사 로깅
목차
{: .text-delta } - TOC {:toc}독립형(standalone) 감사 로깅은 세분화된 액세스 제어(fine-grained access control, FGAC)를 사용하지 않는 OpenSearch 클러스터에 대해 감사 로깅을 활성화해요. 여기에는 SSL 전용 모드(plugins.security.ssl_only: true)로 실행 중인 클러스터나 보안이 비활성화된(plugins.security.disabled: true) 클러스터가 포함돼요.
이 맥락에서 *독립형(standalone)*은 세분화된 액세스 제어와 독립적으로 동작하는 감사 로깅을 의미해요. 독립형 감사 로깅은 Security 플러그인 내부에서 실행되며 표준 모드와 동일한 감사 인프라(싱크, 라우팅, 비동기 스레드 풀)를 사용하지만, 이벤트를 생성하는 데 인증이나 권한 부여에 의존하지 않아요.
인증이나 권한 부여가 필요하지 않은 클러스터라도 SOC 2, HIPAA, PCI DSS, GDPR 같은 컴플라이언스 프레임워크를 위해 감사 추적이 필요할 수 있어요. 독립형 감사 로깅은 이런 클러스터에서 각 요청의 출발지, 동작, 시간을 기록해요.
요구 사항
독립형 감사 로깅을 활성화하려면 각 노드의 opensearch.yml에 다음 두 설정을 모두 추가하세요:
plugins.security.audit.enable_standalone: true
plugins.security.audit.type: log4j
{% include copy.html %}
두 설정 모두 필수예요:
plugins.security.audit.enable_standalone: true는 독립형 감사 서브시스템을 활성화해요.plugins.security.audit.type: <sink>는 감사 이벤트의 목적지인 감사 싱크를 지정해요.
이 설정들을 추가한 후에는 각 노드를 재시작해서 독립형 감사 로깅을 활성화하세요.
다음 카테고리들은 인증이나 권한 부여 결정이 발생하지 않기 때문에 독립형 모드에서는 절대 이벤트를 생성하지 않아요: FAILED_LOGIN, AUTHENTICATED, GRANTED_PRIVILEGES, MISSING_PRIVILEGES, OPENDISTRO_SECURITY_INDEX_ATTEMPT, API_TOKEN_WRITE, RESOURCE_ACCESS_GRANTED, RESOURCE_ACCESS_DENIED, RESOURCE_SHARING_CHANGED. 다른 설정에 의해 이미 비활성화되어 있지 않은 카테고리가 있다면 시작 시 경고가 기록돼요. AUTHENTICATED와 GRANTED_PRIVILEGES는 기본적으로 비활성화되어 있기 때문에 기본 시작 경고에는 이들이 언급되지 않아요.
{: .warning }
지원되는 감사 싱크
독립형 감사 로깅은 표준 모드와 동일한 싱크를 지원해요. 다음 표에서 사용 가능한 싱크 타입을 설명해요.
| 싱크 타입 | 설명 |
|---|---|
internal_opensearch |
현재 OpenSearch 클러스터의 인덱스에 감사 이벤트를 기록해요. |
log4j |
Log4j 로거에 이벤트를 기록해요. 어떤 Log4j 앱렌더(file, SNMP, JDBC, Kafka)든 사용할 수 있어요. |
webhook |
이벤트를 JSON으로 임의의 HTTP 엔드포인트에 전송해요. |
external_opensearch |
원격 OpenSearch 클러스터의 감사 인덱스에 기록해요. |
debug |
이벤트를 stdout에 출력해요. 개발 및 문제 해결 용도로만 사용하세요. |
싱크별 설정 옵션은 감사 로그 저장 타입을 참고하세요.
추적되는 이벤트
독립형 감사 로깅은 인증이 없는 클러스터를 위해 두 가지 요청 추적 카테고리를 추가해요. 다음 표에서 이 카테고리들을 설명해요.
| 카테고리 | 출처 | 설명 |
|---|---|---|
REQUEST_AUDIT |
REST | 출발지 IP, 대상 인덱스, 요청 본문, HTTP 헤더를 포함해 REST에서 발생한 요청을 캡처해요. 독립형 모드의 핵심 이벤트예요. |
TRANSPORT_AUDIT |
Transport | 샤드 수준 연산(bulk[s][p], search[phase/query]), 레플리카 쓰기, 전달된 요청을 포함해 노드 간 transport에서 발생한 요청을 캡처해요. |
REQUEST_AUDIT은 REST(audit_request_origin: REST)에서 발생하지만 이벤트 자체는 audit_request_layer: TRANSPORT로 기록돼요. 그 결과 disabled_categories, disabled_transport_categories, disabled_rest_categories 중 무엇으로든 억제될 수 있어요 --- 이 설정 중 하나에 REQUEST_AUDIT을 추가하기만 해도 이벤트가 억제돼요.
{: .note}
이 카테고리들은 인증이나 권한 부여와 관련된 어떤 의미도 내포하지 않아요. 요청이 수신되고 처리됐다는 사실을 기록할 뿐이에요.
이 요청 추적 카테고리 외에도, 컴플라이언스 추적이 활성화되면 독립형 감사 로깅은 표준 문서 수준 컴플라이언스 카테고리를 내보내요. 다음 표에서 이 카테고리들을 설명해요.
| 카테고리 | 설명 |
|---|---|
COMPLIANCE_DOC_WRITE |
감시 대상 인덱스에 문서가 기록됐을 때 발생해요. 자세한 내용은 문서 쓰기 추적을 참고하세요. |
COMPLIANCE_DOC_READ |
감시 대상 인덱스에서 감시 대상 필드가 읽혔을 때 발생해요. 자세한 내용은 문서 읽기 추적을 참고하세요. |
컴플라이언스 이벤트는 컴플라이언스 설정(compliance.enabled과 감시 대상 인덱스 및 필드)의 영향만 받아요. REQUEST_AUDIT, TRANSPORT_AUDIT 같은 모든 REST 및 transport 레이어 카테고리에 적용되는 disabled_categories에는 영향을 받지 않아요.
이벤트 필드
각 REQUEST_AUDIT 이벤트에는 다음이 포함돼요:
@timestamp--- 이벤트가 발생한 시각audit_cluster_name,audit_node_name,audit_node_id--- 클러스터 및 노드 식별 정보audit_request_privilege--- 감사 대상인 transport 액션(예:indices:data/write/index)audit_request_body--- 요청 본문(설정 가능)audit_request_remote_address--- 클라이언트 출발지 IPaudit_trace_indices--- 대상 인덱스(원본 패턴)audit_trace_resolved_indices--- 해석된 구체적 인덱스(resolve_indices: true인 경우)audit_transport_request_type--- transport 요청 클래스(예:IndexRequest또는SearchRequest)audit_request_layer---REQUEST_AUDIT이벤트의 경우TRANSPORTaudit_rest_request_headers--- HTTP 헤더(민감한 헤더는 제외)
독립형 모드에서의 식별 정보
감사 이벤트에 캡처되는 식별 정보는 보안 모드에 따라 달라져요. 다음 표에서 각 모드에서 캡처되는 식별 정보를 설명해요.
| 보안 모드 | 캡처되는 식별 정보 |
|---|---|
| mTLS를 사용하는 SSL 전용 | 클라이언트 인증서의 subject distinguished name(DN)으로, audit_request_effective_user로 기록돼요(예: CN=my-app,OU=engineering,O=myorg). |
| mTLS를 사용하지 않는 SSL 전용 | 출발지 IP 주소만 기록돼요. |
| 보안 비활성화 | 출발지 IP 주소만 기록돼요. |
설정
초기 독립형 감사 설정은 opensearch.yml에서 구성해요. 동적 설정은 Cluster Settings API를 사용해 런타임에 업데이트할 수 있어요. enable_standalone, action_groups.<NAME>, 싱크 연결 설정을 포함한 정적 설정은 노드 재시작이 필요해요. 보안 인덱스는 필요하지 않아요.
독립형 모드는 Audit log APIs나 audit.yml을 사용하지 않아요. 이 둘은 보안 인덱스를 관리하며 세분화된 액세스 제어를 필요로 해요. 독립형 모드에서는 대신 Cluster Settings API를 사용하세요.
동적 설정
대부분의 필터 및 컴플라이언스 설정은 클러스터를 재시작하지 않고도 런타임에 변경할 수 있어요. 설정을 변경하려면 PUT _cluster/settings 요청을 보내세요:
PUT _cluster/settings
{
"persistent": {
"plugins.security.audit.config.log_request_body": false
}
}
{% include copy.html %}
동적 설정은 opensearch.yml의 값을 재정의하며, 클러스터를 재시작해도 유지돼요.
동적으로 업데이트할 수 없는 설정을 변경하는 PUT _cluster/settings 요청은 성공하고 새 값을 저장하지만, 그 값은 절대 적용되지 않고 업데이트가 아무 효과가 없었다는 오류도 표시되지 않아요.
{: .warning}
동적 설정 참조
다음 설정들은 동적 클러스터 설정으로 등록되어 있어요. 타입은 플레이스홀더로 표시돼요:
# Global toggle
plugins.security.audit.enabled: <bool>
# Filter settings
plugins.security.audit.config.log_request_body: <bool>
plugins.security.audit.config.resolve_indices: <bool>
plugins.security.audit.config.resolve_bulk_requests: <bool>
plugins.security.audit.config.exclude_sensitive_headers: <bool>
plugins.security.audit.config.enable_rest: <bool>
plugins.security.audit.config.enable_transport: <bool>
plugins.security.audit.config.disabled_categories: <list[string]>
plugins.security.audit.config.disabled_rest_categories: <list[string]>
plugins.security.audit.config.disabled_transport_categories: <list[string]>
plugins.security.audit.config.ignore_users: <list[string]>
plugins.security.audit.config.ignore_requests: <list[string]>
plugins.security.audit.config.ignore_headers: <list[string]>
plugins.security.audit.config.body_logging_exclusions: <list[string]>
# Compliance settings
plugins.security.audit.compliance.enabled: <bool>
plugins.security.audit.compliance.write_metadata_only: <bool>
plugins.security.audit.compliance.write_log_diffs: <bool>
plugins.security.audit.compliance.write_watched_indices: <list[string]>
plugins.security.audit.compliance.write_ignore_users: <list[string]>
plugins.security.audit.compliance.read_metadata_only: <bool>
plugins.security.audit.compliance.read_watched_fields: <list[string]>
plugins.security.audit.compliance.read_ignore_users: <list[string]>
plugins.security.audit.compliance.external_config: <bool>
plugins.security.audit.compliance.internal_config: <bool>
{% include copy.html %}
이 설정들을 지정할 수 있는 위치와 관련해서 다음 사항에 유의하세요:
plugins.security.audit.enabled설정은 런타임 전용이에요.opensearch.yml에 설정해도 아무 효과가 없어요. 독립형 모드에서는PUT _cluster/settings를 사용해 변경하세요.- 컴플라이언스 설정은
opensearch.yml에서PUT _cluster/settings와 다른 키 이름을 사용해요.plugins.security.audit.compliance.enabled만 양쪽에서 같은 이름을 사용해요. 나머지 컴플라이언스 설정의 경우opensearch.yml에서는 레거시opendistro_security.compliance.history.*키만 유효해요. 다음 표는 각 컴플라이언스 클러스터 설정을opensearch.yml의 해당 키와 매핑해요.
| 클러스터 설정 | opensearch.yml의 키 |
|---|---|
plugins.security.audit.compliance.enabled |
plugins.security.audit.compliance.enabled |
plugins.security.audit.compliance.write_metadata_only |
opendistro_security.compliance.history.write.metadata_only |
plugins.security.audit.compliance.read_metadata_only |
opendistro_security.compliance.history.read.metadata_only |
plugins.security.audit.compliance.write_log_diffs |
opendistro_security.compliance.history.write.log_diffs |
plugins.security.audit.compliance.write_watched_indices |
opendistro_security.compliance.history.write.watched_indices |
plugins.security.audit.compliance.read_watched_fields |
opendistro_security.compliance.history.read.watched_fields |
plugins.security.audit.compliance.write_ignore_users |
opendistro_security.compliance.history.write.ignore_users |
plugins.security.audit.compliance.read_ignore_users |
opendistro_security.compliance.history.read.ignore_users |
plugins.security.audit.compliance.external_config |
opendistro_security.compliance.history.external_config_enabled |
plugins.security.audit.compliance.internal_config |
opendistro_security.compliance.history.internal_config_enabled |
정적 설정(enable_standalone, action_groups.<NAME>, log4j.enable_mdc_routing, 싱크 연결 설정, 스레드 풀 설정)은 노드 재시작이 필요하며 Cluster Settings API로 변경할 수 없어요.
사용 가능한 필터 설정
다음 표는 로깅되는 내용을 제어하는 설정들을 설명해요. 동적으로 업데이트 가능한 설정은 Cluster Settings API를 사용해 런타임에 변경할 수 있어요. 나머지 설정은 opensearch.yml에 설정하세요.
| 설정 | 기본값 | 동적 업데이트 가능 | 설명 |
|---|---|---|---|
plugins.security.audit.config.enable_rest |
true |
예 | REST 레이어 감사 이벤트를 활성화해요. |
plugins.security.audit.config.enable_transport |
true |
예 | transport 레이어 감사 이벤트를 활성화해요. |
plugins.security.audit.config.log_request_body |
true |
예 | 감사 이벤트에 요청 본문을 포함해요. |
plugins.security.audit.config.resolve_indices |
true |
예 | 와일드카드 인덱스 패턴을 구체적인 인덱스로 해석해요. |
plugins.security.audit.config.resolve_bulk_requests |
false |
예 | bulk 요청의 개별 하위 연산을 기록해요. |
plugins.security.audit.config.exclude_sensitive_headers |
true |
예 | 민감한 헤더(예: Authorization)를 감사 이벤트에서 제외해요. |
plugins.security.audit.config.disabled_categories |
[] |
예 | 비활성화할 요청 추적 카테고리(예: ["REQUEST_AUDIT"]). COMPLIANCE_* 카테고리에는 영향을 주지 않아요. |
plugins.security.audit.config.disabled_rest_categories |
["AUTHENTICATED", "GRANTED_PRIVILEGES", "RESOURCE_ACCESS_GRANTED", "RESOURCE_ACCESS_DENIED", "RESOURCE_SHARING_CHANGED"] |
예 | 비활성화할 REST 레이어 카테고리. 더 이상 권장되지 않아요. 대신 disabled_categories를 사용하세요. |
plugins.security.audit.config.disabled_transport_categories |
["AUTHENTICATED", "GRANTED_PRIVILEGES", "RESOURCE_ACCESS_GRANTED", "RESOURCE_ACCESS_DENIED", "RESOURCE_SHARING_CHANGED", "CLUSTER_SETTINGS_CHANGED", "INDEX_SETTINGS_CHANGED"] |
예 | 비활성화할 transport 레이어 카테고리. 더 이상 권장되지 않아요. 대신 disabled_categories를 사용하세요. |
plugins.security.audit.config.ignore_users |
["kibanaserver"] |
예 | 요청이 기록되지 않는 사용자. |
plugins.security.audit.config.ignore_requests |
[] |
예 | 제외할 액션 패턴 또는 REST 경로(예: ["cluster:monitor/*"]). |
plugins.security.audit.config.ignore_headers |
[] |
아니요 | 감사 이벤트에서 제외할 HTTP 헤더. |
disabled_rest_categories나 disabled_transport_categories를 설정하면 기존 목록에 추가되는 게 아니라 기본 목록 전체가 대체돼요. 둘 중 하나를 커스텀 목록으로 설정한다면, 앞선 표에 나온 카테고리 중 계속 비활성화하려는 항목을 포함하세요. 생략한 카테고리는 경고 없이 다시 활성화돼요.
{: .warning }
런타임에 감사 로깅 활성화 및 비활성화
클러스터를 재시작하지 않고도 감사 로깅을 활성화하거나 비활성화할 수 있어요:
PUT _cluster/settings
{
"persistent": {
"plugins.security.audit.enabled": false
}
}
{% include copy.html %}
감사 로깅을 다시 활성화하려면 값을 true로 설정하세요.
컴플라이언스 추적
문서 수준 컴플라이언스 추적은 스탠드얼론 모드에서 읽기와 쓰기 모두에 대해 동작해요.
문서 쓰기 추적
특정 인덱스에 대한 쓰기를 추적하려면 감시할 인덱스를 설정해요:
plugins.security.audit.compliance.enabled: true
opendistro_security.compliance.history.write.watched_indices:
- "sensitive-data-*"
- "financial-records"
{% include copy.html %}
쓰기 이벤트는 COMPLIANCE_DOC_WRITE 카테고리로 기록되며, 문서 ID, 인덱스 이름, 샤드 ID가 포함돼요. write_log_diffs: true로 설정하면 이벤트에 이전 문서 내용과 현재 문서 내용 간의 diff가 포함돼요.
문서 읽기 추적
특정 인덱스의 특정 필드에 대한 읽기를 추적하려면 read_watched_fields를 설정해요. 클러스터 설정으로서 이 값은 문자열 리스트예요---각 항목은 쉼표로 구분된 문자열이고, 첫 번째 토큰은 인덱스 패턴, 나머지 토큰은 필드 패턴이에요. 인덱스에 필드 패턴이 지정되지 않으면 모든 필드(*)가 감시돼요:
plugins.security.audit.compliance.enabled: true
opendistro_security.compliance.history.read.watched_fields:
- "sensitive-data-*,ssn,credit_card"
- "hr-records,salary,performance_rating"
{% include copy.html %}
읽기 이벤트는 COMPLIANCE_DOC_READ 카테고리로 기록되며, 접근된 필드 값이 포함돼요.
컴플라이언스 설정
다음 표는 컴플라이언스 설정을 설명해요. 동적으로 업데이트 가능한 설정은 클러스터 설정 API를 사용해 런타임에 변경할 수 있어요. 나머지 설정은 opensearch.yml에서 설정해요.
| 설정 | 기본값 | 동적 업데이트 가능 | 설명 |
|---|---|---|---|
plugins.security.audit.compliance.enabled |
true |
예 | 컴플라이언스 추적을 활성화해요. 컴플라이언스 이벤트는 감시 설정에 구성된 인덱스와 필드에 대해서만 생성돼요. |
plugins.security.audit.compliance.write_metadata_only |
false |
예 | 쓰기 이벤트에 대해 메타데이터만 기록해요 (문서 내용은 제외). |
plugins.security.audit.compliance.read_metadata_only |
false |
예 | 읽기 이벤트에 대해 메타데이터만 기록해요 (필드 값은 제외). |
plugins.security.audit.compliance.write_log_diffs |
false |
예 | 이전 문서 내용과 새 문서 내용 간의 diff를 포함해요. |
plugins.security.audit.compliance.write_watched_indices |
[] |
예 | 쓰기 컴플라이언스 이벤트를 감시할 인덱스 패턴이에요. |
plugins.security.audit.compliance.read_watched_fields |
[] |
예 | 읽기 컴플라이언스 이벤트를 감시할 인덱스-필드 패턴이에요. 각 항목은 쉼표로 구분된 문자열이에요: <index-pattern>,<field-pattern>,.... |
plugins.security.audit.compliance.write_ignore_users |
["kibanaserver"] |
아니요 | 문서 쓰기가 컴플라이언스 추적에서 제외되는 사용자들이에요. |
plugins.security.audit.compliance.read_ignore_users |
["kibanaserver"] |
아니요 | 문서 읽기가 컴플라이언스 추적에서 제외되는 사용자들이에요. |
plugins.security.audit.compliance.external_config |
false |
아니요 | 시작 시 외부 설정(opensearch.yml과 환경)을 한 번 기록해요. |
plugins.security.audit.compliance.internal_config |
false |
아니요 | 내부 보안 설정에 대한 변경 사항을 기록해요. |
예제 설정
다음 예제는 SSL 전용 모드와 보안 비활성화 모드에서 스탠드얼론 감사 로깅을 설정해요.
Log4j 싱크를 사용하는 SSL 전용 모드
이 설정은 SSL 전용 클러스터에서 감사 로깅을 활성화하고, 이벤트를 Log4j 로거에 기록해요:
plugins.security.ssl_only: true
# TLS configuration
plugins.security.ssl.transport.pemcert_filepath: node-cert.pem
plugins.security.ssl.transport.pemkey_filepath: node-key.pem
plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
plugins.security.ssl.http.enabled: true
plugins.security.ssl.http.pemcert_filepath: node-cert.pem
plugins.security.ssl.http.pemkey_filepath: node-key.pem
plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
# Standalone audit logging
plugins.security.audit.enable_standalone: true
plugins.security.audit.type: log4j
# Audit filter settings
plugins.security.audit.config.log_request_body: true
plugins.security.audit.config.resolve_indices: true
plugins.security.audit.config.exclude_sensitive_headers: true
plugins.security.audit.config.ignore_requests:
- "cluster:monitor/*"
- "indices:monitor/*"
{% include copy.html %}
내부 인덱스 싱크를 사용하는 보안 비활성화 모드
이 설정은 보안이 비활성화된 클러스터에서 감사 로깅을 활성화하고, 이벤트를 내부 OpenSearch 인덱스에 저장해요:
plugins.security.disabled: true
# Standalone audit logging
plugins.security.audit.enable_standalone: true
plugins.security.audit.type: internal_opensearch
# Audit filter settings
plugins.security.audit.config.log_request_body: true
plugins.security.audit.config.resolve_indices: true
plugins.security.audit.config.resolve_bulk_requests: true
# Compliance tracking
plugins.security.audit.compliance.enabled: true
opendistro_security.compliance.history.write.watched_indices:
- "financial-*"
- "pii-*"
{% include copy.html %}
이 설정에서는 감사 이벤트가 기본적으로 security-auditlog-YYYY.MM.dd라는 이름의 일일 롤링 인덱스에 기록돼요.