Tổng quan cấu hình
Agent (blackhole-agt) đọc cấu hình từ một file YAML. Trong file đó bạn khai báo các source (thu thập dữ liệu), sink (gửi đi) và các section cấu hình chung (logging, inventory, hot-reload, registry...).
Mọi ví dụ YAML trên trang này đều có thể copy trực tiếp vào file cấu hình. Khi một trường có giá trị mặc định, bạn chỉ cần viết nó khi muốn đổi giá trị đó.
Phạm vi của Agent:
- Agent là tiến trình send-only: trong mọi cấu hình, Agent không mở cổng nghe TCP/UDP nào.
- Source hợp lệ:
file,apm,sca,windows_event. - Sink hợp lệ:
grpc,kafka,mqtt,blackhole(OpenSearch),file,alert. - Không có source
mqtt,kafka,grpc,rsyslog,snmptrong Agent — các source đó thuộc Forwarder. File cấu hình dùngtype: mqtt(hoặckafka,grpc,rsyslog,snmp) dướisources:sẽ lỗi parse trên Agent. - Các section server nhúng (
rsyslog_server,snmp_server,mqtt_server,grpc_server,proxy_server) không thuộc cấu hình của Agent — Agent không mở port lắng nghe, các section đó thuộc Forwarder, xem cấu hình Forwarder. - Section
transforms:vẫn được Agent chấp nhận (không bị lỗi parse), nhưng Agent không phải nơi dùng transform. Danh sách transform và tham số chi tiết nằm ở cấu hình Forwarder.
Vị trí file cấu hình
| Phương thức | Hành vi |
|---|---|
blackhole-agt (không chỉ định gì) | Đọc blackhole-agt.yml trong thư mục làm việc; nếu không có thì thử ./config.yml, rồi ./config.yaml, cuối cùng dùng cấu hình rỗng built-in (không source, không sink) |
-c, --config <PATH> | Chỉ định chính xác file cấu hình phải dùng |
--config-dir <DIR> | Ưu tiên hơn --config: tìm config.yml hoặc config.yaml trong DIR, rồi merge mọi file *.blh.yml / *.blh.yaml nằm bên trong DIR (kể cả thư mục con) |
Nếu --config-dir chỉ định thư mục mà không có config.yml lẫn config.yaml, tiến trình báo lỗi:
No config file (config.yml or config.yaml) found in directory: <DIR>Failed to read file for hashing: blackhole-agt.ymlHãy tạo file tại chính xác đường dẫn bạn truyền cho --config (hoặc tạo config.yml/config.yaml trong thư mục mà --config-dir trỏ tới) trước khi chạy start.
Các section cấp cao nhất
| Section | Vai trò | Chi tiết |
|---|---|---|
logging | File log, mức log, xoay vòng | Cấu hình logging |
channel_buffers | Bộ đệm kênh giữa pipeline | Channel buffers |
inventory | Hàng đợi tin nhắn bền vững, retry, backpressure | Inventory |
hot_reload | Tự nạp lại cấu hình khi file đổi | Hot-reload |
resources_threshold | Ngưỡng CPU/RAM/đĩa để tạm dừng pipeline | Ngưỡng tài nguyên |
registry | Kết nối Registry (kéo/đẩy cấu hình, xác thực) | Registry |
sources | Các nguồn dữ liệu (map đặt tên) | Sources |
sinks | Các đích gửi dữ liệu (map đặt tên) | Sinks |
Tất cả section đều tùy chọn — thiếu section thì dùng giá trị mặc định (hoặc, với registry, nghĩa là Agent chạy độc lập không gắn Registry).
Lệnh CLI liên quan tới cấu hình
blackhole-agt [-c|--config <PATH>] [--config-dir <DIR>] [-v|--verbose] [--service]
[--service-name <N>] [-V|--version] [-h] [COMMAND]
(không có COMMAND) In banner
configure | config [-f|--force] [--output <PATH>] <ACTION>
pull Đọc cấu hình từ Registry, lưu ra file local
(--output: tùy chọn, dump YAML ra file khác)
push Đẩy file --config lên Registry
schema Viết file config.jsonschema cạnh file --config
service [-f|--force] [--service-name <N>] <install|uninstall|start|stop|status>
auth -k|--key <KEY>
start [-s|--service]Ví dụ:
# Kéo cấu hình từ Registry về file local
blackhole-agt -c config.yml configure pull
# Kéo và đồng thời dump YAML đã merge ra một file khác
blackhole-agt -c config.yml configure pull --output resolved.yml
# Đẩy file cấu hình local lên Registry
blackhole-agt -c config.yml configure push
# Sinh JSON schema cạnh file cấu hình
blackhole-agt -c config.yml configure schema- Không có
--log-level. Muốn log debug, dùng cờ toàn cục-v/--verbose(đặtlogging.levelthànhdebug) hoặc khai báologging.leveltrong YAML. -c/--configvà--config-dirlà cờ toàn cục, đặt trước tên subcommand.--outputchỉ có ý nghĩa vớiconfigure pull.auth --key <KEY>dùng để khai báo API key; key không bao giờ được ghi vào log hay file cấu hình.- Không có lệnh
restartcho service: dùngservice stoprồiservice start.
Cấu hình logging
Toàn bộ section này là tùy chọn — thiếu section logging thì mọi trường dùng giá trị mặc định.
Cú pháp
logging:
level: "info"
dir: "./logs"
file: "default.log"
error_file: "default-error.log"
max_size_mb: 10Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
level | String | Không | "info" | Mức log: trace, debug, info, warn, error. Cũng chấp nhận chỉ định theo target kiểu collectors=trace |
dir | String (đường dẫn) | Không | "./logs" | Thư mục chứa file log, tính tương đối so với thư mục làm việc |
file | String | Không | "default.log" | Tên file log chính |
error_file | String | Không | "default-error.log" | Tên file log riêng cho lỗi |
max_size_mb | Int (MB) | Không | 10 | Tổng dung lượng file log được phép trước khi xoay vòng (xem Lưu ý) |
Ví dụ
Cơ bản:
logging:
level: "info"Nâng cao (log chi tiết cho một module, đổi thư mục và tăng ngân sách dung lượng):
logging:
level: "supervisor=debug"
dir: "/var/log/blackhole-agt"
file: "default.log"
error_file: "default-error.log"
max_size_mb: 50Lưu ý
- Xoay vòng luôn bật. Không có cờ bật/tắt.
max_size_mblà tổng dung lượng cho phép cho file log chính, không phải ngưỡng của từng file:- File log chính (
file): xoay thành 5 file cũ, mỗi file bị cắt ởmax_size_mb / 5. - File log lỗi (
error_file): xoay thành 10 file cũ, mỗi file cắt ởmax_size_mb— tức dung lượng tối đa của nhóm file lỗi có thể lên tới ~10 lần giá trị bạn đặt.
- File log chính (
- File log thực tế là
<dir>/<file>(mặc định./logs/default.log), file lỗi là<dir>/<error_file>(mặc định./logs/default-error.log). File lỗi chỉ nhận mứcerror. dirlà tương đối so với thư mục làm việc của tiến trình, không phải/var/log/...(xem Vị trí file cấu hình). Muốn ghi vào/var/log, hãy khai báo đường dẫn tuyệt đối chodir.- Ở chế độ service, stdout bị tắt — file log là nguồn output duy nhất.
-v/--verbosetrên dòng lệnh sẽ đặtlogging.levelthànhdebug.
Channel buffers
Điều chỉnh độ sâu của các kênh nội bộ giữa source và sink. Tùy chọn toàn bộ.
Cú pháp
channel_buffers:
orchestrator_capacity: 100000
shipper_capacity: 100000
router_max_in_flight_routes: 4Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
orchestrator_capacity | Int | Không | 100000 | Số sự kiện tối đa xếp hàng giữa source và orchestrator |
shipper_capacity | Int | Không | 100000 | Số sự kiện tối đa xếp hàng giữa orchestrator và từng sink |
router_max_in_flight_routes | Int | Không | 4 | Số tuyến định tuyến chạy song song tối đa khi phát sự kiện sang nhiều sink |
Ví dụ
Cơ bản:
channel_buffers:
orchestrator_capacity: 100000
shipper_capacity: 100000Nâng cao (dự phòng burst lớn hơn, CPU cao hơn):
channel_buffers:
orchestrator_capacity: 500000
shipper_capacity: 500000
router_max_in_flight_routes: 8Lưu ý
- Buffer chiếm bộ nhớ theo quy mô: chỉ tăng khi pipeline thực sự cần dự phòng burst.
router_max_in_flight_routescàng cao thì throughput khi fan-out sang nhiều sink càng tốt, nhưng tốn CPU hơn.
Inventory (hàng đợi tin nhắn)
Inventory là hàng đợi tin nhắn bền vững (persistent queue): khi sink tạm thời không gửi được, sự kiện được giữ lại ở đây để gửi lại sau.
Cú pháp
inventory:
max_messages: 100000
max_bytes: 268435456
backpressure_on_limit: false
per_shipper:
file:
ttl: 3600
max_retries: 10
flush_interval_secs: 10
mqtt:
ttl: 86400
max_retries: 20
flush_interval_secs: 5Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
max_messages | Int hoặc null | Có (khi viết section) | 100000 | Số message tối đa trong hàng đợi; null = không giới hạn |
max_bytes | Int hoặc null | Có (khi viết section) | 268435456 (256 MB) | Dung lượng tối đa của hàng đợi; null = không giới hạn |
backpressure_on_limit | Bool | Có (khi viết section) | false | true: chặn nhận thêm khi đạt giới hạn (giữ dữ liệu); false: bỏ message cũ nhất (giữ luồng chạy) |
per_shipper | Map | Có (khi viết section) | — | Chính sách retry/TTL cho từng loại sink; key hợp lệ: file, mqtt, kafka, grpc, blackhole, alert |
Mỗi entry trong per_shipper có ba trường, đều bắt buộc:
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
ttl | Int (giây) | Có | — | Thời gian sống tối đa của message trong hàng đợi; quá hạn bị loại bỏ |
max_retries | Int | Có | — | Số lần gửi lại tối đa; hết số lần thì message bị bỏ |
flush_interval_secs | Int (giây) | Có | — | Chu kỳ nền cố gắng gửi lại hàng đợi |
Ví dụ
Cơ bản (giữ nguyên hành vi mặc định, chỉ giới hạn hàng đợi):
inventory:
max_messages: 100000
max_bytes: 268435456
backpressure_on_limit: false
per_shipper:
blackhole:
ttl: 86400
max_retries: 20
flush_interval_secs: 5Nâng cao (không giới hạn số message, bật backpressure, chính sách riêng cho từng sink):
inventory:
max_messages: null
max_bytes: null
backpressure_on_limit: true
per_shipper:
file:
ttl: 3600
max_retries: 10
flush_interval_secs: 10
mqtt:
ttl: 86400
max_retries: 20
flush_interval_secs: 5
kafka:
ttl: 3600
max_retries: 10
flush_interval_secs: 10
grpc:
ttl: 3600
max_retries: 10
flush_interval_secs: 10
blackhole:
ttl: 7200
max_retries: 15
flush_interval_secs: 5
alert:
ttl: 600
max_retries: 5
flush_interval_secs: 5Lưu ý
- Bỏ trọn section
inventorybạn vẫn có hàng đợi hoạt động với:max_messages: 100000,max_bytes: 268435456,backpressure_on_limit: false, vàper_shippermặc định chomqtt,kafka,grpc,blackhole(mỗi loại:ttl86400,max_retries20,flush_interval_secs5). - Sink không có entry trong
per_shipper(theo mặc định làfilevàalert) dùng chính sách fallback:ttl: 3600,max_retries: 10,flush_interval_secs: 10. max_messages/max_bytesđặtnullnghĩa là không giới hạn — chỉ an toàn khi bạn kiểm soát được lưu lượng đầu vào.backpressure_on_limit: truebảo toàn dữ liệu nhưng có thể làm chậm pipeline khi backend chặn.
Hot-reload
Agent kiểm tra file cấu hình theo chu kỳ và nạp lại khi file thay đổi. Toàn bộ section là tùy chọn.
Cú pháp
hot_reload:
enabled: true
poll_interval_ms: 5000
debounce_ms: 1000Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
enabled | Bool | Không | true | Bật/tắt hot-reload |
poll_interval_ms | Int (ms) | Không | 5000 | Chu kỳ kiểm tra thay đổi của file cấu hình |
debounce_ms | Int (ms) | Không | 1000 | Thời gian chờ ổn định sau khi phát hiện thay đổi, tránh nạp lại liên tục |
Ví dụ
Cơ bản:
hot_reload:
enabled: trueNâng cao (phát hiện nhanh hơn, chờ ổn định lâu hơn):
hot_reload:
enabled: true
poll_interval_ms: 2000
debounce_ms: 3000Tắt hot-reload:
hot_reload:
enabled: falseLưu ý
- Cơ chế là polling SHA-256: cứ mỗi
poll_interval_ms, Agent tính lại hash của file cấu hình chính và mọi file*.blh.yml/*.blh.yamltrong thư mục cấu hình; khi phát hiện hash đổi thì chờdebounce_msrồi mới nạp lại. Không có inotify, không có tín hiệu SIGHUP. - Bỏ trọn section thì hot-reload vẫn bật với các giá trị mặc định ở trên.
- Cấu hình được đọc lại vào bộ nhớ và file snapshot
.blackhole-resolved.yaml(nằm cạnh file cấu hình) được ghi lại. - Collector, sink không được khởi tạo lại từ chỉnh sửa local — muốn thêm/bớt source hay sink, hãy restart Agent.
- Nếu nguồn cấu hình hiện hành là bản pull từ Registry, mọi chỉnh sửa local bị bỏ qua hoàn toàn; log sẽ ghi:
Remote config is active — ignoring local config change.
Chỉ cập nhật push từ Registry mới thực hiện diff theo từng component (thêm, bỏ hoặc khởi động lại riêng lẻ từng collector/sink).
Ngưỡng tài nguyên
Resource guard: khi CPU, RAM hoặc ổ đĩa vượt ngưỡng quá lâu, pipeline tạm dừng để hệ thống hồi phục. Section tùy chọn.
Cú pháp
resources_threshold:
cpu:
threshold_percentage: 80.0
sustained_secs: 60
memory:
threshold_percentage: 80.0
sustained_secs: 60
disk:
threshold_percentage: 101.0
sustained_secs: 60
check_interval: 10Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
cpu.threshold_percentage | Float (%) | Không | 80.0 | Ngưỡng CPU; đặt > 100 để tắt theo dõi |
cpu.sustained_secs | Int (giây) | Không | 60 | CPU phải duy trì ở ngưỡng trong bao lâu trước khi tạm dừng |
memory.threshold_percentage | Float (%) | Không | 80.0 | Ngưỡng RAM; đặt > 100 để tắt theo dõi |
memory.sustained_secs | Int (giây) | Không | 60 | RAM phải duy trì ở ngưỡng trong bao lâu trước khi tạm dừng |
disk.threshold_percentage | Float (%) | Không | 101.0 | Ngưỡng ổ đĩa; mặc định 101.0 = tắt theo dõi ổ đĩa |
disk.sustained_secs | Int (giây) | Không | 60 | Đĩa phải duy trì ở ngưỡng trong bao lâu trước khi tạm dừng |
check_interval | Int (giây) | Không | 10 | Chu kỳ kiểm tra mức sử dụng tài nguyên |
Ví dụ
Cơ bản (giữ mặc định):
resources_threshold:
check_interval: 10Nâng cao (nới ngưỡng CPU, bật theo dõi ổ đĩa):
resources_threshold:
cpu:
threshold_percentage: 90.0
sustained_secs: 120
memory:
threshold_percentage: 85.0
sustained_secs: 60
disk:
threshold_percentage: 95.0
sustained_secs: 300
check_interval: 30Lưu ý
- Guard cho một tài nguyên chỉ hoạt động khi
threshold_percentage <= 100— đó là lý do disk mặc định101.0(tắt). - Theo mặc định: CPU và RAM được theo dõi (80% liên tục trong 60 giây thì pipeline tạm dừng), ổ đĩa thì không.
- Khi mức sử dụng xuống dưới ngưỡng, pipeline tự động tiếp tục — không cần can thiệp tay.
check_intervalcàng nhỏ thì phản hồi càng nhanh nhưng càng tốn CPU đọc số liệu.
Registry
Registry là điểm điều phối trung tâm (tùy chọn): Agent kéo cấu hình từ Registry, đẩy cấu hình local lên Registry và xác thực bằng API key. Bỏ trọn section nghĩa là Agent chạy độc lập, không gắn Registry.
Cú pháp
registry:
api_url: "https://blackhole.glabs.one"
config_update_interval: "15s"
tls:
ca_cert_path: null
insecure_skip_verify_https: false
proxy:
enable: true
http: "http://proxy.company.com:8080"
https: "https://proxy.company.com:8443"Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
api_url | String (URL) | Có (khi viết section) | — | API endpoint của Registry; giá trị chuẩn dùng trong mẫu là https://blackhole.glabs.one |
config_update_interval | String (duration) | Không | "15s" | Chu kỳ kiểm tra cập nhật cấu hình từ Registry, dạng 15s, 1m, 5m... |
tls.ca_cert_path | String | Không | null | Đường dẫn CA bundle (PEM) để xác thực Registry |
tls.insecure_skip_verify_https | Bool | Không | false | Bỏ qua xác thực chứng chỉ HTTPS (không khuyến nghị ở production) |
proxy.enable | Bool | Không | true | Bật/tắt proxy cho kết nối ra ngoài |
proxy.http | String (URL) | Không | null | HTTP proxy, dạng http://user:pass@proxy.company.com:8080 |
proxy.https | String (URL) | Không | null | HTTPS proxy, dạng https://user:pass@proxy.company.com:8443 |
Ví dụ
Cơ bản:
registry:
api_url: "https://blackhole.glabs.one"Nâng cao (chu kỳ riêng, CA riêng, đi qua proxy):
registry:
api_url: "https://blackhole.glabs.one"
config_update_interval: "30s"
tls:
ca_cert_path: "/etc/blackhole/ca.pem"
insecure_skip_verify_https: false
proxy:
enable: true
http: "http://proxy.company.com:8080"
https: "https://proxy.company.com:8443"Lưu ý
- Section
registrycó mặt thìapi_urlbắt buộc — thiếu sẽ lỗi parse (missing field api_url). - Nếu dùng Registry, hãy xác thực trước bằng
blackhole-agt auth --key <KEY>; API key không bao giờ được ghi vào log hay file cấu hình. - Khi có Registry, lúc khởi động Agent ưu tiên cấu hình lấy từ Registry — lúc đó chỉnh sửa file local bị bỏ qua (xem Hot-reload).
insecure_skip_verify_httpschỉ có ý nghĩa vớiapi_urldạnghttps://.config_update_intervalkhông đọc được (sai định dạng duration) thì sẽ cảnh báo và dùng 60 giây.
Sources
sources là map đặt tên: key là định danh (identifier) của source, value là cấu hình của nó. Agent hỗ trợ đúng bốn loại source.
sources:
<ten-source>:
type: "file" # hoặc "apm", "sca", "windows_event"
# các trường khác tùy loại sourceTổng quan sources
type | Thu thập dữ liệu | Ghi chú |
|---|---|---|
file | Log từ file (glob patterns) | Có sẵn trên mọi nền tảng |
apm | Metrics hệ thống theo chu kỳ | Có sẵn trên mọi nền tảng |
sca | Đánh giá cấu hình bảo mật (policy tương thích Wazuh) | Có sẵn trên mọi nền tảng |
windows_event | Windows Event Log channels | Chỉ có trên build Windows |
- Key của map chính là identifier của source; identifier này được dùng trong
inputscủa sink. Key không được là*(dành riêng cho wildcard của sink) và không được rỗng. - Trường
identifierbên trong source không cần khai báo — Agent tự gán từ key của map. - Cả bốn source đều có
indexvàsourcetype(tùy chọn, mặc địnhnull) để gắn metadata cho sự kiện khi gửi đi. - Các loại source khác (
mqtt,kafka,grpc,rsyslog,snmp) không tồn tại trong Agent — xem cấu hình Forwarder.
file source
Theo dõi và thu thập log từ các file.
Cú pháp
sources:
security_logs:
type: "file"
includes:
- "/var/log/auth.log"
- "/var/log/secure.log"
index: "security"
sourcetype: "auth_logs"
tail: true
debounce_ms: 1000Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "file" |
includes | Array of String | Không | ["/var/log/auth.log", "/var/log/secure.log", "/var/log/commands.log"] | Danh sách glob pattern cần theo dõi (*, **, ?), ví dụ "/var/log/*.log", "/opt/app/**/*.log" |
index | String | Không | null | Index gắn cho dữ liệu thu thập được |
sourcetype | String | Không | null | Loại dữ liệu, giúp downstream biết định dạng log |
tail | Bool | Không | true | true: chỉ đọc phần thêm sau khi khởi động (giống tail -f); false: đọc toàn bộ file từ đầu rồi theo dõi tiếp |
debounce_ms | Int (ms) | Không | 1000 | Cửa sổ gộp các thay đổi file liên tiếp thành một lần xử lý |
Ví dụ
Cơ bản:
sources:
security_logs:
type: "file"
includes:
- "/var/log/auth.log"
- "/var/log/secure.log"Nâng cao (nhiều nguồn, debounce khác nhau):
sources:
# Theo dõi security logs với phản hồi nhanh
security_logs:
type: "file"
includes:
- "/var/log/auth.log"
- "/var/log/secure.log"
- "/var/log/audit/audit.log"
index: "security"
sourcetype: "auth_logs"
tail: true
debounce_ms: 500
# Đọc lại toàn bộ application logs
app_logs:
type: "file"
includes:
- "/var/log/application/*.log"
- "/opt/app/logs/**/*.log"
index: "application"
sourcetype: "app_logs"
tail: false
debounce_ms: 2000Lưu ý
- Hỗ trợ glob patterns; tự phát hiện log rotation (file bị xoay thì tiếp tục theo dõi file mới).
debounce_msnhỏ = phản hồi nhanh hơn nhưng tăng CPU; lớn = gộp nhiều thay đổi, giảm số event lẻ.- Đặt
tail: falseở môi trường có sẵn nhiều log cũ sẽ đọc lại toàn bộ file đó lúc khởi động — hãy cân nhắc kỹincludesđể giới hạn đúng phạm vi.
apm source
Thu thập metrics hệ thống (CPU, bộ nhớ, ổ đĩa, mạng, tiến trình) theo chu kỳ.
Cú pháp
sources:
apm_system:
type: "apm"
interval: 30
index: "apm"
sourcetype: "apm_metrics"Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "apm" |
interval | Int (giây) | Có | — | Chu kỳ thu thập metrics (giây). Không có giá trị mặc định khi đọc YAML — giá trị thường dùng là 30 |
index | String | Không | null | Index gắn cho metrics |
sourcetype | String | Không | null | Loại dữ liệu |
Ví dụ
Cơ bản:
sources:
apm_system:
type: "apm"
interval: 30Nâng cao (metrics real-time cho monitoring + bản tổng hợp cho báo cáo):
sources:
apm_realtime:
type: "apm"
interval: 10
index: "system_metrics"
sourcetype: "apm_realtime"
apm_summary:
type: "apm"
interval: 300
index: "system_summary"
sourcetype: "apm_summary"Lưu ý
- Thiếu
intervalsẽ lỗi parse:missing field interval— đây là trường bắt buộc duy nhất của source này. intervalcàng nhỏ thì dữ liệu càng chi tiết nhưng càng tốn tài nguyên; 30 giây là giá trị cân bằng thường dùng.- Metrics được thu thập: CPU usage, memory usage, disk, network interfaces và process information.
sca source
Thu thập và đánh giá cấu hình bảo mật theo các policy tương thích Wazuh: Agent đọc file policy YAML từ thư mục chỉ định, chạy các check trên máy cục bộ và phát kết quả dạng sự kiện.
Cú pháp
sources:
sca_policy:
type: "sca"
policy_directory: "/etc/agent/sca/policies"
scan_interval: "86400s"
run_on_start: true
allow_commands: false
enabled_policies: []
index: "sca"
sourcetype: "sca_results"Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "sca" |
policy_directory | String | Không | /etc/agent/sca/policies (Linux) · C:\ProgramData\agent\sca\policies (Windows) | Thư mục chứa policy YAML; quét đệ quy mọi file .yml/.yaml |
scan_interval | String (duration) | Không | null → dùng 1h | Chu kỳ quét dạng chuỗi duration: "1h", "30m", "90s", "86400s"; đặt "0s" để tắt quét định kỳ. Alias: scan_interval_secs |
scan_cron | String | Không | null | Cron expression cho lịch quét, ví dụ "0 */15 * * * * *" (mỗi 15 phút); loại trừ với scan_interval |
run_on_start | Bool | Không | true | Quét ngay khi collector khởi động |
allow_commands | Bool | Không | false | Cho phép thực thi các rule kiểu c: (mặc định tắt vì lý do bảo mật) |
enabled_policies | Array of String | Không | [] (tất cả policy) | Chỉ xử lý những file policy có tên trong danh sách (phân biệt hoa thường) |
index | String | Không | null | Index gắn cho kết quả quét |
sourcetype | String | Không | null | Loại dữ liệu |
scan_interval: "86400s" # ✅ đúng — 86400 giây
scan_interval_secs: 86400 # ❌ lỗi parse: invalid type: integer `86400`, expected a stringAlias scan_interval_secs nhận cùng kiểu chuỗi ("86400s", "1h"), không phải số giây dạng số.
Ví dụ
Cơ bản (quét mỗi 24 giờ):
sources:
sca_policy:
type: "sca"
policy_directory: "/etc/agent/sca/policies"
scan_interval: "86400s"
run_on_start: trueNâng cao (cron cho CIS, và một source SCA trên Windows):
sources:
sca_cis:
type: "sca"
policy_directory: "/etc/agent/sca/policies"
scan_cron: "0 */15 * * * * *"
run_on_start: true
allow_commands: false
enabled_policies:
- "cis_ubuntu22.yml"
- "cis_debian11.yml"
index: "compliance"
sourcetype: "sca_cis"
sca_windows:
type: "sca"
policy_directory: "C:\\ProgramData\\agent\\sca\\policies"
scan_interval: "1h"
enabled_policies:
- "cis_windows_server_2022.yml"
index: "windows_compliance"
sourcetype: "sca_windows"Lưu ý
scan_intervalvàscan_cronloại trừ nhau — chỉ được dùng một trong hai; đặt cùng lúc sẽ bị báo lỗi lịch trình (mutually exclusive).- Không khai báo
scan_intervalthì mặc định quét mỗi 1 giờ. allow_commandsmặc địnhfalse: các check cần chạy lệnh bị đánh dấu "not applicable" (hoặc error tùy policy). Chỉ bật khi bạn tin tưởng file policy.- Kết quả mỗi check gồm:
policy_id,check_id,check_title,result(pass/fail/not_applicable/error),evidence, và các trường phụ trợ nhưdescription,rationale,remediation,compliance,references.
Các loại rule trong policy:
| Prefix | Phạm vi | Ví dụ |
|---|---|---|
f: | File (tồn tại, nội dung, regex) | f:/etc/passwd -> exists |
d: | Thư mục | d:/etc/ssh |
p: | Tiến trình đang chạy | p:sshd |
c: | Thực thi lệnh (cần allow_commands: true) | c:systemctl is-enabled sshd -> r:enabled |
r: | Windows registry (chỉ Windows) | r:HKLM\SOFTWARE\Policies -> ValueName |
Cấu trúc file policy YAML (tương thích Wazuh):
policy:
id: "example_policy"
name: "Example Security Policy"
description: "Sample policy for demonstration"
variables:
sshd_config: "/etc/ssh/sshd_config"
requirements:
title: "System requirements"
description: "Check if this policy applies"
condition: all
rules:
- "f:/etc/os-release -> r:Ubuntu"
checks:
- id: 1001
title: "Ensure SSH root login is disabled"
description: "Root login via SSH should be disabled"
rationale: "Prevents direct root access via SSH"
remediation: "Set PermitRootLogin no in /etc/ssh/sshd_config"
compliance:
- cis: ["5.2.10"]
- pci_dss: ["2.2.4"]
condition: all
rules:
- 'f:$sshd_config -> r:^\s*PermitRootLogin\s+no'windows_event source
Thu thập Windows Event Log từ các channel chỉ định. Source này chỉ tồn tại trong bản build cho Windows — trên Linux, type: "windows_event" sẽ không được nhận diện.
Cú pháp
sources:
windows_events:
type: "windows_event"
channels:
- name: "Application"
ids: []Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "windows_event" |
channels | Array of Object | Không | [] (không kênh nào) | Danh sách kênh cần thu thập; mỗi phần tử là một object, không phải chuỗi |
channels[].name | String | Có (với mỗi phần tử) | — | Tên kênh (alias: channel), ví dụ Application, Security, System, Setup, ForwardedEvents |
channels[].ids | Array of Int | Không | [] = lấy mọi event | Lọc theo Event ID, ví dụ [4624, 4625] |
index | String | Không | null | Index gắn cho sự kiện |
sourcetype | String | Không | null | Loại dữ liệu |
channels: ["Application", "Security"] # ❌ lỗi: invalid type: string "Application", expected struct WindowsEventChannel
channels: # ✅ đúng
- name: "Application"
ids: []
- name: "Security"
ids: [4624, 4625]Nếu không khai báo channels thì danh sách rỗng và không kênh nào được subscribe — hãy luôn liệt kê kênh cần thu thập.
Ví dụ
Cơ bản:
sources:
windows_events:
type: "windows_event"
channels:
- name: "Application"
ids: []Nâng cao (chỉ login/logout events, tách nguồn theo kênh):
sources:
security_events:
type: "windows_event"
channels:
- name: "Security"
ids: [4624, 4625, 4634, 4648, 4768, 4769]
index: "security"
sourcetype: "windows_security"
system_events:
type: "windows_event"
channels:
- name: "System"
ids: []
- name: "Application"
ids: []
index: "system"
sourcetype: "windows_system"Lưu ý
ids: []nghĩa là lấy tất cả event của kênh đó.- Các kênh phổ biến:
Application(ứng dụng),Security(đăng nhập/phân quyền — cần quyền administrator),System(sự kiện hệ điều hành). - Thu thập
Securitychannel thường yêu cầu Agent chạy bằng tài khoản có quyền đọc Security log.
Sinks
sinks là map đặt tên: key là identifier của sink, value là cấu hình. Agent hỗ trợ sáu loại sink.
type | Điểm đến | Yêu cầu tối thiểu |
|---|---|---|
grpc | gRPC endpoint (thường là Forwarder) | url |
kafka | Kafka cluster | bootstrap_servers |
mqtt | MQTT broker | url, auth |
blackhole | OpenSearch / BlackHole index | url |
file | File local (debug, lưu trữ) | không — có sẵn giá trị mặc định |
alert | Cảnh báo gửi về Registry | không — URL lấy từ registry.api_url |
- Key của map chính là identifier của sink; trường
identifierbên trong không cần khai báo. inputs(tùy chọn, mặc định["*"], aliasincludes) chọn dữ liệu nào được gửi vào sink:["*"]là nhận tất cả, hoặc nêu đích danh["security_logs", "apm_system"].- TLS có sẵn ở các sink
grpc,kafka,mqtt,blackholenhưng mặc định tắt — muốn dùng phải khai báo tường minh.
Cấu hình batch (chung cho nhiều sink)
# ❌ SAI — khối rate_limit bị bỏ qua im lặng, batch_size vẫn là 500
sinks:
my_sink:
type: "mqtt"
url: "mqtt://broker:1883"
auth: { type: "none" }
rate_limit:
batch_size: 100# ✅ Đúng — ba trường ở cấp cao nhất của sink
sinks:
my_sink:
type: "mqtt"
url: "mqtt://broker:1883"
auth: { type: "none" }
batch_size: 100
batch_interval: 500
batch_max_bytes: 1048576Ba trường batch áp dụng cho sink grpc, kafka, mqtt, blackhole, file (sink alert không có):
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
batch_size | Int | Không | 500 | Số message tối đa trong một lô gửi |
batch_interval | Int (ms) | Không | 1000 | Thời gian chờ tối đa trước khi gửi lô (dù lô chưa đầy) |
batch_max_bytes | Int (bytes) | Không | 10485760 (10 MB) | Tổng kích thước tối đa của một lô, chặn lô quá lớn |
grpc sink
Gửi sự kiện tới một gRPC endpoint (ví dụ: Forwarder chạy gRPC server nhúng). Mỗi LogEvent được serialize JSON và gửi qua RPC Publish (unary) hoặc PublishStream (client-streaming); trường topic của request lấy từ index của event.
Cú pháp
sinks:
grpc_forwarder:
type: "grpc"
url: "http://forwarder.company.com:50051"
inputs: ["*"]
headers:
x-api-key: "forwarder-secret"
use_streaming: true
max_concurrent_requests: 4
batch_size: 500
batch_interval: 1000
batch_max_bytes: 10485760Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "grpc" |
url | String (URL) | Có | — | Endpoint đầy đủ gồm scheme, host, port (http:// hoặc https://). Alias: endpoint. Không có giá trị mặc định khi đọc YAML |
inputs | Array of String | Không | ["*"] | Nguồn gửi vào sink (alias includes) |
headers | Map | Không | {} | Header tùy chỉnh, gửi kèm mọi request dạng gRPC metadata |
use_streaming | Bool | Không | true | true: dùng PublishStream (throughput cao); false: gửi từng event qua Publish |
max_concurrent_requests | Int | Không | null (shipper dùng 1) | Số request gRPC đồng thời tối đa mỗi lô |
message_limits | Object | Không | null | Giới hạn kích thước message: max_decoding_message_size, max_encoding_message_size (bytes) |
batch_size / batch_interval / batch_max_bytes | Int | Không | 500 / 1000 / 10485760 | Xem batch chung |
Các tùy chọn nâng cao (tùy chọn)
| Trường | Kiểu | Mặc định | Mô tả |
|---|---|---|---|
tls | Object | null | TLS client: ca_cert_path, client_cert_path, client_key_path, domain_name, insecure_skip_verify (mặc định false) |
connect_timeout_secs | Int (giây) | null | Timeout kết nối TCP |
request_timeout_secs | Int (giây) | null | Timeout mỗi RPC (alias: timeout_secs) |
tcp_keepalive_secs | Int (giây) | null | TCP keepalive |
tcp_nodelay | Bool | null | Bật/tắt TCP_NODELAY |
http2_keep_alive_interval_secs | Int (giây) | null | Chu kỳ HTTP/2 keep-alive |
http2_keep_alive_timeout_secs | Int (giây) | null | Timeout HTTP/2 keep-alive |
http2_keep_alive_while_idle | Bool | null | Keep-alive khi kết nối nhàn rỗi |
initial_stream_window_size | Int (bytes) | null | Cửa sổ stream ban đầu (HTTP/2) |
initial_connection_window_size | Int (bytes) | null | Cửa sổ connection ban đầu (HTTP/2) |
http2_adaptive_window | Bool | null | Bật kiểm soát luồng thích ứng (HTTP/2) |
concurrency_limit | Int | null | Giới hạn concurrency ở tầng kết nối |
buffer_size | Int | null | Kích thước buffer nội bộ của endpoint |
user_agent | String | null | User-Agent gửi đi |
proxy | Object | null | Proxy (cùng cấu trúc với proxy của Registry) |
reflection | Object | null | Client reflection: enabled (Bool, mặc định false), timeout_secs |
proto | Object | null | Trỏ tới schema: path (bắt buộc trong object), include_paths, service, method |
Ví dụ
Cơ bản:
sinks:
grpc_forwarder:
type: "grpc"
url: "http://forwarder.company.com:50051"Nâng cao (TLS, header, tinh chỉnh HTTP/2):
sinks:
grpc_forwarder:
type: "grpc"
url: "https://forwarder.company.com:50051"
inputs: ["security_logs", "apm_system"]
headers:
x-api-key: "forwarder-secret"
tls:
ca_cert_path: "/etc/blackhole/ca.pem"
domain_name: "forwarder.company.com"
connect_timeout_secs: 10
use_streaming: true
max_concurrent_requests: 4
message_limits:
max_encoding_message_size: 4194304
max_decoding_message_size: 4194304
http2_keep_alive_interval_secs: 30
batch_size: 500
batch_interval: 1000
batch_max_bytes: 10485760Lưu ý
- Các giá trị
nulltrong bảng nâng cao nghĩa là "không khai báo thì dùng mặc định của gRPC library". - Một số tùy chọn chưa được áp dụng ở phía shipper hiện tại:
request_timeout_secs,proxy,ca_cert_path/client_cert_path/client_key_path,reflection,proto— khai báo được nhưng hành vi thực tế chưa thay đổi;domain_namethì có hiệu lực (override SNI/hostname verify). - TLS cho
grpcchỉ hoạt động khiurldùng schemehttps://.
kafka sink
Gửi sự kiện tới Kafka cluster qua librdkafka.
Cú pháp
sinks:
kafka_production:
type: "kafka"
inputs: ["*"]
bootstrap_servers:
- "kafka1.company.com:9092"
- "kafka2.company.com:9092"
client_id: "blackhole-agent"
security:
type: "sasl"
sasl:
mechanism: "PLAIN"
username: "agent"
password: "secure-password"
acks: "leader"
compression: "gzip"
enable_idempotence: true
batching:
linger_ms: 100
batch_num_messages: 1000
batch_kbytes: 1024
retries:
max_retries: 10
backoff_ms: 100
producer_pool_size: 4
batch_size: 500
batch_interval: 1000
batch_max_bytes: 10485760Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "kafka" |
bootstrap_servers | Array of String | Có | — | Danh sách broker, dạng "host:port". Thiếu sẽ lỗi parse (missing field bootstrap_servers) |
inputs | Array of String | Không | ["*"] | Nguồn gửi vào sink (alias includes) |
client_id | String | Không | null (tự sinh) | Tên client nhận diện producer |
security | Object | Không | { type: "none" } | Xem Cấu hình security |
acks | String | Không | "leader" | Mức xác nhận: "none" (mất dữ liệu có thể, nhanh nhất), "leader" (acks=1), "all" (mọi replica, an toàn nhất) |
compression | String | Không | "none" | Nén: "none", "gzip", "snappy", "lz4", "zstd" |
enable_idempotence | Bool | Không | false | Bật idempotent producer, tránh trùng lặp (nên kèm acks: "all") |
transactional_id | String | Không | null | Transaction ID cho ngữ nghĩa exactly-once |
batching | Object | Không | linger_ms: 0, batch_num_messages: 100000, batch_kbytes: 1048576 | Tinh chỉnh lô của librdkafka: chờ linger_ms (ms), số message, tổng KB |
retries | Object | Không | max_retries: 10, backoff_ms: 100 | Retry gửi: số lần và khoảng nghỉ (ms) |
timeouts | Object | Không | socket_timeout_ms: 60000, request_timeout_ms: 30000, message_timeout_ms: 300000, connections_max_idle_ms: 300000 | Các timeout (ms) của Kafka client |
proxy | Object | Không | null | Proxy (cùng cấu trúc với proxy của Registry) |
producer_pool_size | Int | Không | 4 | Số producer trong pool (1–64); giữ nguyên thứ tự theo key |
extra | Map (String → String) | Không | {} | Thuộc tính librdkafka truyền thẳng, ví dụ batch.size: "16384" |
batch_size / batch_interval / batch_max_bytes | Int | Không | 500 / 1000 / 10485760 | Xem batch chung |
Cấu hình security
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
security.type | String | Không | "none" | "none" (PLAINTEXT), "tls" (chỉ mã hóa), "sasl" (xác thực SASL) |
security.tls.ca_location | String | Không | null | CA bundle (PEM); thiếu thì dùng CA hệ thống |
security.tls.certificate_location | String | Không | null | Client certificate cho mTLS |
security.tls.key_location | String | Không | null | Private key của client certificate |
security.tls.key_password | String | Không | null | Mật khẩu private key (nếu key có mật khẩu) |
security.tls.verify_certificate | Bool | Không | true | Xác minh chain + hostname của broker |
security.sasl.mechanism | String | Không | "PLAIN" | PLAIN, SCRAM_SHA256, SCRAM_SHA512, GSSAPI, OAUTHBEARER |
security.sasl.username | String | Khi dùng PLAIN/SCRAM | null | Tên đăng nhập |
security.sasl.password | String | Khi dùng PLAIN/SCRAM | null | Mật khẩu |
security.sasl.gssapi | Object | Khi mechanism: "GSSAPI" | null | principal (bắt buộc), keytab (bắt buộc), service_name (mặc định "kafka"), krb5_config |
security.sasl.oauthbearer | Object | Khi mechanism: "OAUTHBEARER" | null | token, oidc_config |
security.sasl.tls | Object | Không | null | Khi có mặt thì chạy SASL qua TLS (SASL_SSL); schema giống security.tls |
mechanism: "SCRAM_SHA256" # ✅
mechanism: "SCRAM-SHA-256" # ❌ lỗi parse: unknown variantCác giá trị hợp lệ: PLAIN, SCRAM_SHA256, SCRAM_SHA512, GSSAPI, OAUTHBEARER.
Ví dụ
Cơ bản (PLAINTEXT):
sinks:
kafka_local:
type: "kafka"
bootstrap_servers:
- "localhost:9092"
acks: "leader"
compression: "none"Nâng cao (SASL/SCRAM + TLS, high throughput):
sinks:
kafka_production:
type: "kafka"
bootstrap_servers:
- "kafka1.company.com:9092"
- "kafka2.company.com:9092"
- "kafka3.company.com:9092"
client_id: "blackhole-agent"
security:
type: "sasl"
sasl:
mechanism: "SCRAM_SHA256"
username: "agent"
password: "secure-password"
tls:
ca_location: "/etc/blackhole/ca.pem"
verify_certificate: true
acks: "all"
compression: "gzip"
enable_idempotence: true
batching:
linger_ms: 100
batch_num_messages: 1000
batch_kbytes: 1024
retries:
max_retries: 10
backoff_ms: 100
producer_pool_size: 8
batch_size: 1000
batch_interval: 500
batch_max_bytes: 10485760
extra:
linger.ms: "5"Lưu ý
bootstrap_serverslà trường bắt buộc duy nhất; mọi trường khác đều có mặc định.- TLS chỉ hoạt động khi bạn chọn
security.type: "tls"(hoặcsasl.tls); mặc định lànone— không mã hóa. acks: "all"+enable_idempotence: truelà tổ hợp khuyến nghị cho dữ liệu quan trọng (chậm hơn nhưng không mất/không trùng).batch_kbytestính bằng KiB: mặc định1048576= 1 GiB ngưỡng queue của librdkafka.extraghi đè trực tiếp lên cấu hình librdkafka — chỉ dùng khi bạn biết chắc ý nghĩa của key.
mqtt sink
Publish sự kiện tới MQTT broker.
Cú pháp
sinks:
mqtt_production:
type: "mqtt"
url: "mqtts://broker.company.com:8883?client_id=agent-001"
inputs: ["*"]
auth:
type: "basic"
username: "agent"
password: "secure-password"
batch_size: 500
batch_interval: 1000
batch_max_bytes: 10485760Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "mqtt" |
url | String (URL) | Có | — | URL broker dạng mqtt:// (không mã hóa) hoặc mqtts:// (TLS), có thể kèm query như ?client_id=agent-001 |
inputs | Array of String | Không | ["*"] | Nguồn gửi vào sink (alias includes) |
auth | Object | Có | — | Xác thực với broker — xem bảng dưới |
tls | Object | Không | null | TLS/mTLS cho broker — xem bảng dưới |
proxy | Object | Không | null | Proxy (cùng cấu trúc với proxy của Registry) |
batch_size / batch_interval / batch_max_bytes | Int | Không | 500 / 1000 / 10485760 | Xem batch chung |
Cấu hình auth và tls
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
auth.type | String | Có | — | "none" (không xác thực) hoặc "basic" (username/password) |
auth.username | String | Khi type: "basic" | — | Tên đăng nhập |
auth.password | String | Khi type: "basic" | — | Mật khẩu |
tls.ca_cert_path | String | Không | null | CA certificate (PEM) — cần với broker dùng chứng chỉ tự ký |
tls.client_cert_path | String | Không | null | Client certificate cho mTLS (alias của khóa viết gọn certpath) |
tls.client_key_path | String | Không | null | Private key cho mTLS (alias của khóa viết gọn keypath) |
tls.insecure | Bool | Không | false | Bỏ qua xác minh chứng chỉ (chỉ để thử nghiệm) |
Ví dụ
Cơ bản (broker nội bộ, không xác thực):
sinks:
mqtt_local:
type: "mqtt"
url: "mqtt://localhost:1883?client_id=agent-local"
auth:
type: "none"Nâng cao (TLS + basic auth + proxy):
sinks:
mqtt_secure:
type: "mqtt"
url: "mqtts://broker.company.com:8883?client_id=agent-001"
auth:
type: "basic"
username: "agent"
password: "secure-password"
tls:
ca_cert_path: "/etc/blackhole/mqtt/ca-cert.pem"
client_cert_path: "/etc/blackhole/mqtt/client-cert.pem"
client_key_path: "/etc/blackhole/mqtt/client-key.pem"
proxy:
enable: true
https: "https://proxy.company.com:8443"
batch_size: 200
batch_interval: 500
batch_max_bytes: 2097152Lưu ý
- Muốn TLS thì dùng scheme
mqtts://(thường cổng 8883) và khai báotls; TLS mặc định tắt. tlschấp nhận cả khóa viết gọn (capath,certpath,keypath) lẫn khóa đầy đủ (ca_cert_path,client_cert_path,client_key_path).- Khóa
client_cert_pathvàclient_key_pathphải đi kèm nhau khi broker yêu cầu mutual TLS.
opensearch (blackhole) sink
Index sự kiện vào OpenSearch / BlackHole. Trong YAML, sink này được chọn bằng type: "blackhole".
sinks:
my_index:
type: "blackhole" # ✅ đúng
url: "https://opensearch.company.com:9200"Tên "opensearch" chỉ dùng để gọi tên sink trong tài liệu; khóa nhận diện trong cấu hình là blackhole.
Cú pháp
sinks:
blackhole_production:
type: "blackhole"
inputs: ["*"]
url: "https://blackhole.company.com:9200"
healthcheck: false
auth:
type: "basic"
username: "agent"
password: "secure-password"
tls:
insecure_skip_verify: false
headers:
X-Custom-Header: "value"
timeouts:
request_timeout_secs: 30
connect_timeout_secs: 10
batch_size: 200
batch_interval: 2000
batch_max_bytes: 2097152Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "blackhole" |
url | String (URL) | Có | — | Endpoint của cluster, dạng http:// hoặc https:// (alias: endpoint) |
inputs | Array of String | Không | ["*"] | Nguồn gửi vào sink (alias includes) |
healthcheck | Bool | Không | false | Gửi request kiểm tra sức khỏe cluster |
request | Object | Không | null | Tương thích ngược: retry_attempts (Int), timeout_secs (Int) |
auth | Object | Không | { type: "none" } | Xác thực — xem bảng auth |
tls | Object | Không | ca_cert_path: null, insecure_skip_verify: false | ca_cert_path (CA bundle PEM), insecure_skip_verify (bỏ qua xác minh — không khuyến nghị) |
proxy | Object | Không | null | Proxy (cùng cấu trúc với proxy của Registry) |
headers | Map | Không | {} | HTTP header gửi kèm mọi request (hữu ích cho API versioning, auth tùy chỉnh) |
timeouts | Object | Không | request_timeout_secs: 30, connect_timeout_secs: 10 | Timeout (giây) cho request và kết nối |
bulk_doc_metadata_overhead_bytes | Int (bytes) | Không | 128 | Ước tính overhead metadata mỗi document trong bulk request |
bulk_max_docs_hard_cap | Int | Không | 5000 | Giới hạn cứng số document mỗi bulk request |
bulk_max_bytes_hard_cap | Int (bytes) | Không | 67108864 (64 MiB) | Giới hạn cứng kích thước payload mỗi bulk request |
batch_size / batch_interval / batch_max_bytes | Int | Không | 500 / 1000 / 10485760 | Xem batch chung |
Cấu hình auth
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
auth.type | String | Không | "none" | "none", "basic", "clientcert", "jwt", "awssigv4" |
auth.username | String | Khi type: "basic" | — | Tên đăng nhập basic auth |
auth.password | String | Khi type: "basic" | — | Mật khẩu basic auth |
auth.pkcs12_path | String | Khi type: "clientcert" | — | File chứng chỉ client dạng PKCS#12/PFX |
auth.pkcs12_password | String | Khi type: "clientcert" | — | Mật khẩu file PKCS#12 |
auth.token | String | Khi type: "jwt" | — | JWT/OIDC bearer token |
auth.header_name | String | Không | "Authorization" | Tên header mang token |
auth.region | String | Khi type: "awssigv4" | — | AWS region, ví dụ us-east-1 |
auth.profile | String | Không | null | AWS profile (thiếu thì dùng default credential chain) |
auth.role_arn | String | Không | null | IAM role ARN để assume |
auth.service | String | Không | "es" | Dịch vụ AWS: "es" (OpenSearch Service) hoặc "aoss" (OpenSearch Serverless) |
Ví dụ
Cơ bản (không xác thực):
sinks:
blackhole_local:
type: "blackhole"
url: "http://localhost:9200"
auth:
type: "none"Nâng cao (basic auth + custom headers):
sinks:
blackhole_secure:
type: "blackhole"
url: "https://blackhole.company.com:9200"
inputs: ["*"]
healthcheck: true
auth:
type: "basic"
username: "agent"
password: "secure-password"
tls:
ca_cert_path: "/etc/blackhole/ca.pem"
insecure_skip_verify: false
headers:
X-Api-Version: "1.0"
timeouts:
request_timeout_secs: 30
connect_timeout_secs: 10
batch_size: 200
batch_interval: 2000
batch_max_bytes: 2097152Lưu ý
- Kích thước lô thực tế: số document =
min(batch_size, bulk_max_docs_hard_cap), bytes =min(batch_max_bytes, bulk_max_bytes_hard_cap). authmặc địnhnone;insecure_skip_verifymặc địnhfalse— đừng tắt xác minh ở production.- Chọn chứng chỉ nào (
basic,jwt,awssigv4...) tùy policy của cluster; khi không chắc, dùngbasic.
file sink
Ghi sự kiện ra file local — dùng để debug hoặc lưu trữ tạm.
Cú pháp
sinks:
file_debug:
type: "file"
path: "./debug-events/"
max_size_mb: 10
max_files: 5
inputs: ["*"]
batch_size: 100
batch_interval: 1000
batch_max_bytes: 1048576Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "file" |
path | String (thư mục) | Không | "./debug-events/" | Thư mục ghi file; đường dẫn tương đối tính theo thư mục làm việc |
max_size_mb | Int (MB) | Không | 10 | Kích thước tối đa mỗi file trước khi tạo file mới |
max_files | Int | Không | 5 | Số file giữ lại; file cũ hơn bị xóa |
inputs | Array of String | Không | ["*"] | Nguồn gửi vào sink (alias includes) |
batch_size / batch_interval / batch_max_bytes | Int | Không | 500 / 1000 / 10485760 | Xem batch chung |
Ví dụ
Cơ bản:
sinks:
file_debug:
type: "file"Nâng cao (riêng cho security logs, giữ nhiều file hơn):
sinks:
file_security:
type: "file"
path: "/var/log/blackhole/security/"
max_size_mb: 100
max_files: 20
inputs: ["security_logs"]Lưu ý
- Theo mặc định mọi file sink ghi vào
./debug-events/(tính theo thư mục làm việc). - Rotation chạy theo cặp
max_size_mb/max_files: vượt kích thước thì tạo file mới, vượt số file thì xóa cái cũ nhất.
alert sink
Gửi cảnh báo (alert events) về Registry bằng HTTP POST. Đây là sink không cấu hình URL — địa chỉ đích được lấy từ registry.api_url tại runtime và xác thực bằng header x-device-token, để endpoint cảnh báo luôn gắn với Registry mà thiết bị đã đăng ký. Không có giao diện web đi kèm: chỉ là một sink HTTP.
Cú pháp
sinks:
alerts:
type: "alert"
inputs: ["alerts"]
max_retry: 3
timeout_ms: 5000Các trường cấu hình
| Trường | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
type | String | Có | — | Phải là "alert" |
inputs | Array of String | Không | null → tự nhận channel "alerts" | Alert events được phát vào channel dành riêng "alerts", thông thường giữ mặc định |
max_retry | Int | Không | null (shipper dùng 3) | Số lần gửi lại tối đa cho lỗi tạm thời |
timeout_ms | Int (ms) | Không | null (shipper dùng 10000) | Timeout mỗi request |
Ví dụ
Cơ bản (chỉ khai báo loại sink):
sinks:
alerts:
type: "alert"Nâng cao (đổi retry/timeout):
sinks:
alerts:
type: "alert"
inputs: ["alerts"]
max_retry: 5
timeout_ms: 3000Lưu ý
- Mỗi alert event = một HTTP POST tới
{registry.api_url}/client/alerts, kèm headerx-device-token. - Chỉ lỗi tạm thời (5xx, lỗi mạng) được retry; lỗi 4xx bị bỏ qua ngay (backend từ chối). Hết số retry thì event được giữ trong
inventoryđể gửi lại sau. - Kết nối dùng
tlsvàproxytừ section Registry. - Không có section
registrythì alert events không gửi đi được — chúng được lưu vàoinventorycho tới khi Registry sẵn sàng.
Hướng dẫn tạo chứng chỉ SSL
Các sink mqtt, kafka, grpc, blackhole đều hỗ trợ TLS nhưng mặc định tắt. Khi backend dùng chứng chỉ tự ký (self-signed), bạn cần cấu hình CA tương ứng. Phần dưới đây hướng dẫn tạo chứng chỉ tự ký bằng openssl / keytool.
Tạo chứng chỉ SSL tự ký cho MQTT Broker
Bước 1: Tạo thư mục lưu trữ chứng chỉ
sudo mkdir -p /etc/ssl/mqtt
sudo chmod 700 /etc/ssl/mqttBước 2: Tạo CA (Certificate Authority) tự ký
# Tạo private key cho CA
sudo openssl genrsa -out /etc/ssl/mqtt/ca-key.pem 4096
# Tạo certificate cho CA
sudo openssl req -new -x509 -days 365 -key /etc/ssl/mqtt/ca-key.pem -out /etc/ssl/mqtt/ca-cert.pemKhi được hỏi, điền thông tin (Country Name, State, City, Organization...); Common Name ví dụ: MQTT CA.
Bước 3: Tạo server certificate
# Tạo private key cho server
sudo openssl genrsa -out /etc/ssl/mqtt/server-key.pem 4096
# Tạo CSR
sudo openssl req -new -key /etc/ssl/mqtt/server-key.pem -out /etc/ssl/mqtt/server.csrThông tin giống CA, nhưng Common Name phải là hostname hoặc IP của MQTT broker.
Bước 4: Ký server certificate bằng CA
sudo openssl x509 -req -in /etc/ssl/mqtt/server.csr \
-CA /etc/ssl/mqtt/ca-cert.pem -CAkey /etc/ssl/mqtt/ca-key.pem \
-CAcreateserial -out /etc/ssl/mqtt/server-cert.pem -days 365Bước 5: Tạo client certificate (tùy chọn, cho mutual TLS)
sudo openssl genrsa -out /etc/ssl/mqtt/client-key.pem 4096
sudo openssl req -new -key /etc/ssl/mqtt/client-key.pem -out /etc/ssl/mqtt/client.csr
sudo openssl x509 -req -in /etc/ssl/mqtt/client.csr \
-CA /etc/ssl/mqtt/ca-cert.pem -CAkey /etc/ssl/mqtt/ca-key.pem \
-CAcreateserial -out /etc/ssl/mqtt/client-cert.pem -days 365Bước 6: Cấu hình MQTT sink với TLS
sinks:
mqtt_secure:
type: "mqtt"
url: "mqtts://broker.company.com:8883?client_id=agent-001"
auth:
type: "basic"
username: "agent"
password: "secure-password"
tls:
ca_cert_path: "/etc/ssl/mqtt/ca-cert.pem"
client_cert_path: "/etc/ssl/mqtt/client-cert.pem"
client_key_path: "/etc/ssl/mqtt/client-key.pem"Xử lý lỗi TLS
Nếu gặp TLS: I/O: tls handshake eof hoặc lỗi TLS khác, kiểm tra theo thứ tự:
- Đường dẫn CA:
ca_cert_pathtrỏ đúng file và tiến trình có quyền đọc. - Định dạng file: certificate phải là PEM (bắt đầu bằng
-----BEGIN CERTIFICATE-----). - Scheme URL: dùng
mqtts://thay vìmqtt://. - Cổng: MQTT over TLS thường là 8883, không phải 1883.
- Common Name/SAN: hostname trong URL phải khớp certificate của broker.
Tạo chứng chỉ SSL cho Kafka
Bước 1: Tạo keystore cho Kafka broker
# Tạo keystore
keytool -keystore kafka.server.keystore.jks -alias localhost -validity 365 \
-genkey -keyalg RSA -keysize 2048 -storepass password -keypass password \
-dname "CN=localhost, OU=IT, O=YourCompany, L=HCMC, ST=HCMC, C=VN"
# Tạo CSR
keytool -keystore kafka.server.keystore.jks -alias localhost \
-certreq -file cert-file -storepass password
# Ký certificate bằng CA
openssl x509 -req -CA ca-cert -CAkey ca-key -in cert-file -out cert-signed \
-days 365 -CAcreateserial -passin pass:password
# Import CA vào keystore
keytool -keystore kafka.server.keystore.jks -alias CARoot \
-import -file ca-cert -storepass password
# Import certificate đã ký vào keystore
keytool -keystore kafka.server.keystore.jks -alias localhost \
-import -file cert-signed -storepass passwordBước 2: Tạo truststore cho client
keytool -keystore kafka.client.truststore.jks -alias CARoot \
-import -file ca-cert -storepass passwordBước 3: Cấu hình Kafka sink với TLS
sinks:
kafka_secure:
type: "kafka"
bootstrap_servers:
- "kafka1.company.com:9093"
security:
type: "tls"
tls:
ca_location: "/path/to/ca-cert"
certificate_location: "/path/to/client-cert"
key_location: "/path/to/client-key"
verify_certificate: true
batch_size: 500
batch_interval: 1000
batch_max_bytes: 10485760Cấu hình nâng cao
High Availability
Cho Kafka, tăng độ bền bằng acks: "all" và idempotent producer; đưa nhiều broker vào bootstrap_servers để dự phòng:
sinks:
kafka_ha:
type: "kafka"
bootstrap_servers:
- "kafka1.company.com:9092"
- "kafka2.company.com:9092"
- "kafka3.company.com:9092"
acks: "all"
enable_idempotence: true
retries:
max_retries: 2147483647
backoff_ms: 100
batch_size: 1000
batch_interval: 500
batch_max_bytes: 10485760Performance Tuning
Tối ưu cho high-throughput — tăng buffer, giảm độ trễ batch:
channel_buffers:
orchestrator_capacity: 500000
shipper_capacity: 500000
router_max_in_flight_routes: 8
sources:
high_freq_apm:
type: "apm"
interval: 5
sinks:
high_throughput_kafka:
type: "kafka"
bootstrap_servers:
- "kafka1.company.com:9092"
batching:
linger_ms: 0
batch_num_messages: 10000
batch_kbytes: 10240
batch_size: 1000
batch_interval: 100
batch_max_bytes: 10485760Xem thêm
- ./quickstart - Chạy Agent lần đầu
- ./install - Cài đặt và cài service
- ./operation - Vận hành hằng ngày
- ./troubleshooting - Khắc phục sự cố
- /components/forwarder/configuration - Tham chiếu cấu hình Forwarder
