audit 구성 블록
audit 구성 블록 (Audit Configuration Block)
이 페이지는 Nomad 에이전트 구성의 audit 블록에서 감사 로깅 동작을 구성하는 방법에 대한 참조 정보를 제공해요. 감사 로그를 활성화하고, 감사 로그를 스트리밍할 싱크(sink)를 정의하며, 이벤트를 감사 로그에서 제외하도록 필터 규칙을 변경해요.
Enterprise — 이 기능은 Nomad Enterprise에서 사용할 수 있어요.
출처: 문서
본문
audit {
enabled = true
}
활성화되면 nomad 에이전트(클라이언트 또는 서버)에 대한 각 HTTP 요청은 두 개의 감사 로그 항목을 생성해요. 이 두 항목은 OperationReceived와 OperationComplete라는 단계(stage)에 해당해요. 감사 로깅은 요청이 처리되기 전에 OperationReceived 이벤트를 생성해요. OperationComplete 이벤트는 요청이 처리된 후, 그러나 응답 본문이 최종 사용자에게 반환되기 전에 전송돼요.
기본적으로 최소 구성의 audit 블록( audit { enabled = true } )을 사용하면 필터 없이 다음 기본 싱크가 추가돼요.
audit {
enabled = true
sink "audit" {
type = "file"
delivery_guarantee = "enforced"
format = "json"
path = "/[data_dir]/audit/audit.log"
}
}
이 싱크는 정의된 data_dir 디렉터리 안의 audit 디렉터리 내에 audit.log 파일을 생성해요. delivery_guarantee는 "enforced"로 설정돼 HTTP 요청이 성공적으로 완료되려면 모든 요청이 싱크에 성공적으로 기록되어야 함을 의미해요.
audit 매개변수 (Parameters)
enabled(bool: false)— 감사 로깅을 활성화할지 여부를 지정해요. 활성화되면 필터로 필터링되지 않는 한 모든 요청에 대해 감사 로깅이 발생해요.sink(sink: default)— 감사 로그가 전송될 싱크를 구성해요.filter(array<filter>: [])— 일치하는 이벤트가 감사 로깅 싱크로 전송되는 것을 제외하도록 필터를 구성해요.
sink 블록 (sink Block)
sink 블록은 이벤트가 전송될 감사 로깅 싱크를 만드는 데 사용돼요. 현재 단일 싱크만 지원돼요.
블록의 키는 로깅 목적으로 사용되는 싱크의 이름에 해당해요.
audit {
enabled = true
sink "audit" {
type = "file"
delivery_guarantee = "enforced"
format = "json"
path = "/var/lib/nomad/audit/audit.log"
rotate_bytes = 100
rotate_duration = "24h"
rotate_max_files = 10
mode = "0600"
}
}
sink 매개변수 (Parameters)
type(string: "file", required)— 생성할 싱크의 유형을 지정해요. 현재 "file" 유형만 지원돼요.delivery_guarantee(string: "enforced", required)— 각 감사 로그 항목에 대해 제공될 전달 보장을 지정해요. 사용 가능한 옵션은 "enforced"와 "best-effort"예요. "enforced"는 감사 로그 이벤트가 싱크에 기록되지 못하면 요청 실행을 중지해요. "best-effort"는 요청 실행을 중지하지 않으며, 요청이 잠재적으로 감사되지 않을 수 있어요.format(string: "json", required)— 싱크로 전송할 출력 형식을 지정해요. 현재 "json" 형식만 지원돼요.mode(string: "0600")— 감사 로그 파일의 권한 모드를 8진수 표기로 지정해요.path(string: "[data_dir]/audit/audit.log")— 감사 로그에 사용할 경로와 파일 이름을 지정해요. 기본적으로 Nomad는 구성된 data_dir을 사용해 /data_dir/audit/audit.log 결합 경로를 만들어요. rotate_bytes나 rotate_duration이 설정되면 파일 회전이 발생해요. 이 경우 파일 이름 끝에 타임스탬프 "filename-{timestamp}.log"가 붙어요.rotate_bytes(int: 0)— 회전되기 전에 감사 로그에 기록되어야 하는 바이트 수를 지정해요. 지정하지 않으면 로그 파일에 기록할 수 있는 바이트 수에 제한이 없어요.rotate_duration(duration: "24h")— 회전되기 전에 감사 로그가 기록되어야 하는 최대 기간을 지정해요.30s같은 duration 값이어야 해요.rotate_max_files(int: 0)— 보관할 이전 감사 로그 파일 아카이브의 최대 수를 지정해요. 0이면 어떤 파일도 삭제되지 않아요.
filter 블록 (filter Block)
filter 블록은 일치하는 이벤트가 감사 로그에 기록되는 것을 걸러내는 필터를 만드는 데 사용돼요. 기본적으로 모든 이벤트는 모든 단계(OperationReceived와 OperationComplete)에 대해 감사 로그로 전송돼요. 필터는 감사 로깅의 성능 영향을 제한하고 생성되는 이벤트 양을 줄이려는 운영자에게 유용해요.
endpoints, stages, operations는 globbed 패턴 일치를 지원해요.
필터를 평가할 때 쿼리 매개변수는 무시돼요.
audit {
enabled = true
# Filter out all requests and all stages for /v1/metrics
filter "default" {
type = "HTTPEvent"
endpoints = ["/v1/metrics"]
stages = ["*"]
operations = ["*"]
}
# Filter out requests where endpoint matches globbed pattern
filter "globbed example" {
type = "HTTPEvent"
endpoints = ["/v1/evaluation/*/allocations"]
stages = ["*"]
operations = ["*"]
}
# Filter out OperationReceived GET requests for all endpoints
filter "OperationReceived GETs" {
type = "HTTPEvent"
endpoints = ["*"]
stages = ["OperationReceived"]
operations = ["GET"]
}
}
filter 매개변수 (Parameters)
type(string: "HTTPEvent", required)— 생성할 필터의 유형을 지정해요. 현재 HTTPEvent만 지원돼요.endpoints(array<string>: [])— 필터를 적용할 엔드포인트 목록을 지정해요.stages(array<string>: [])— 일치하는 엔드포인트에 대해 필터를 적용할 단계( "OperationReceived", "OperationComplete", "*" ) 목록을 지정해요.operations(array<string>: [])— 일치하는 엔드포인트에 대해 필터를 적용할 작업 목록을 지정해요. HTTPEvent 유형의 경우 이것은 HTTP 동사(GET, PUT, POST, DELETE...)에 해당해요.
감사 로그 예시 (Example audit logs)
다음 감사 로그 항목들은 /v1/job/web/summary 에 대한 요청에 대한 것이에요. 첫 번째 항목은 OperationReceived 단계용이에요. 두 번째 항목은 OperationComplete 단계용이며 OperationReceived 단계의 내용에 response 키를 더한 것을 포함해요.
{
"created_at": "2020-03-24T13:09:35.703869927-04:00",
"event_type": "audit",
"payload": {
"id": "8b826146-b264-af15-6526-29cb905145aa",
"stage": "OperationReceived",
"type": "audit",
"timestamp": "2020-03-24T13:09:35.703865005-04:00",
"version": 1,
"auth": {
"accessor_id": "a162f017-bcf7-900c-e22a-a2a8cbbcef53",
"name": "Bootstrap Token",
"global": true,
"create_time": "2020-03-24T17:08:35.086591881Z"
},
"request": {
"id": "02f0ac35-c7e8-0871-5a58-ee9dbc0a70ea",
"operation": "GET",
"endpoint": "/v1/job/web/summary",
"namespace": {
"id": "default"
},
"request_meta": {
"remote_address": "127.0.0.1:33648",
"user_agent": "Go-http-client/1.1"
},
"node_meta": {
"ip": "127.0.0.1:4646"
}
}
}
}
{
"created_at": "2020-03-24T13:09:35.704224536-04:00",
"event_type": "audit",
"payload": {
"id": "8b826146-b264-af15-6526-29cb905145aa",
"stage": "OperationComplete",
"type": "audit",
"timestamp": "2020-03-24T13:09:35.703865005-04:00",
"version": 1,
"auth": {
"accessor_id": "a162f017-bcf7-900c-e22a-a2a8cbbcef53",
"name": "Bootstrap Token",
"global": true,
"create_time": "2020-03-24T17:08:35.086591881Z"
},
"request": {
"id": "02f0ac35-c7e8-0871-5a58-ee9dbc0a70ea",
"operation": "GET",
"endpoint": "/v1/job/web/summary",
"namespace": {
"id": "default"
},
"request_meta": {
"remote_address": "127.0.0.1:33648",
"user_agent": "Go-http-client/1.1"
},
"node_meta": {
"ip": "127.0.0.1:4646"
}
},
"response": {
"status_code": 200
}
}
}
요청이 오류를 반환하면 감사 로그는 오류 메시지를 반영해요.
{
"created_at": "2020-03-24T13:18:36.121978648-04:00",
"event_type": "audit",
"payload": {
"id": "21c6f97a-fbfb-1090-1e34-34d1ece57cc2",
"stage": "OperationComplete",
"type": "audit",
"timestamp": "2020-03-24T13:18:36.121428628-04:00",
"version": 1,
"auth": {
"accessor_id": "anonymous",
"name": "Anonymous Token",
"policies": ["anonymous"],
"create_time": "0001-01-01T00:00:00Z"
},
"request": {
"id": "c696cc9e-962e-18b3-4097-e0a09070f89e",
"operation": "GET",
"endpoint": "/v1/jobs?prefix=web",
"namespace": {
"id": "default"
},
"request_meta": {
"remote_address": "127.0.0.1:33874",
"user_agent": "Go-http-client/1.1"
},
"node_meta": {
"ip": "127.0.0.1:4646"
}
},
"response": {
"status_code": 403,
"error": "Permission denied"
}
}
}