- OpenSearch: lưu trữ và truy vấn log.
- OpenSearch Dashboards: trực quan hóa và thao tác dữ liệu.
- Fluentd: thu thập, parse, ship log vào OpenSearch.
- Fluent bit: thu thập và gửi raw log từ agent.
Kiến trúc:
Fluent bit thực hiện thu thập log từ OS, application; lấy raw log.
Fluentd nhận log từ các máy cài Fluent bit và thực hiện filter, buffer, routing; thực hiện chuẩn hóa trước khi gửi đến SIEM.
SIEM là OpenSearch thực hiện lưu trữ log, hỗ trợ dashboard, thiết lập rule.
Fluent Bit:
Fluentd là một data collector (trình thu thập log/streaming data) mã nguồn mở, thường dùng trong hệ thống logging, monitoring, và observability. Nó được thiết kế để thu thập, chuyển đổi, và gửi dữ liệu log từ nhiều nguồn khác nhau đến nhiều đích khác nhau.
1. Collect
Lấy log từ nhiều nguồn: file log (nginx, apache, ứng dụng), syslog, journald, container (Docker, Kubernetes), API, message queue (Kafka, RabbitMQ), …
2. Transform / Filter
Chuẩn hóa định dạng log thành JSON hoặc cấu trúc thống nhất.
Thêm, xóa, sửa field trong log.
Gắn nhãn (tag), lọc (filter), ẩn thông tin nhạy cảm.
3. Store / Forward
Đẩy log đến nhiều đích:
- Elasticsearch / OpenSearch (để phục vụ Kibana/Dashboards).
- Splunk, Loki, S3, Hadoop, MongoDB, Kafka.
- Xuất ra file hoặc gửi đến dịch vụ monitoring.
4. Đảm bảo tính ổn định
Có cơ chế buffer (bộ đệm) để không mất log khi hệ thống tạm thời gián đoạn.
Hỗ trợ retry, load balancing, high availability.
Chức năng chính:
Cài docker:
├── docker-compose.yml
└── default.conf
└── fluent.conf
Tạo file docker-compose.yml
Tạo file fluent.conf:
Tạo file default.conf:
Sau khi tạo xong 3 file thực hiện: docker-compose up -d
Triển khai trên host Linux:
Chỉnh sửa lại file /etc/fluent-bit/fluent-bit.conf để thu thập và gửi log đến fluentd
Chỉnh lại phần OUTPUT để có thể gửi log đến fluentd
Thêm các INPUT để có thể thu thập log từ nhiều nguồn
Khởi động lại:
Triển khai trên host Windows:
Cài fluent bit cho windows: https://packages.fluentbit.io/windows/fluent-bit-4.0.7-win64.exe
Thư mục chứa các file config sau khi cài: C:\fluent-bit\conf
Cấu hình file config C:\fluent-bit\conf\fluent-bit.conf:
Tạo dưới dạng service:
- OpenSearch Dashboards: trực quan hóa và thao tác dữ liệu.
- Fluentd: thu thập, parse, ship log vào OpenSearch.
- Fluent bit: thu thập và gửi raw log từ agent.
Kiến trúc:

Fluent bit thực hiện thu thập log từ OS, application; lấy raw log.
Fluentd nhận log từ các máy cài Fluent bit và thực hiện filter, buffer, routing; thực hiện chuẩn hóa trước khi gửi đến SIEM.
SIEM là OpenSearch thực hiện lưu trữ log, hỗ trợ dashboard, thiết lập rule.
Fluent Bit:

- Input
- Fluent Bit bắt đầu thu thập dữ liệu từ nhiều nguồn khác nhau như: file log, systemd journal, TCP/UDP, Kubernetes log, hay metrics từ node.
- Parser
- Sau khi lấy dữ liệu, Fluent Bit có thể phân tích cú pháp log (parsing).
- Ví dụ: tách timestamp, mức độ log (INFO, ERROR), message, hoặc chuyển đổi định dạng JSON, regex, Docker log…
- Filter
- Tại bước này, Fluent Bit áp dụng các bộ lọc (Filters) để xử lý, enrich hoặc loại bỏ log.
- Ví dụ: thêm metadata, ẩn thông tin nhạy cảm, đổi field, hoặc chỉ giữ lại những log quan trọng.
- Buffer
- Dữ liệu sau khi lọc sẽ được đưa vào buffer (bộ đệm).
- Fluent Bit hỗ trợ in-memory buffer và filesystem buffer để đảm bảo dữ liệu không bị mất khi có sự cố kết nối.
- Routing
- Fluent Bit định tuyến (routing) dữ liệu đến một hoặc nhiều Output plugins.
- Cơ chế routing giúp một log có thể gửi song song đến nhiều đích khác nhau tùy theo cấu hình.
- Output
- Đây là nơi dữ liệu được gửi đến các hệ thống đích, ví dụ: Elasticsearch, OpenSearch, Kafka, Loki, Splunk, S3, hay chỉ ghi ra stdout.
- Một input có thể được gửi tới nhiều outputs, tùy thuộc vào nhu cầu lưu trữ hoặc phân tích.
Fluentd là một data collector (trình thu thập log/streaming data) mã nguồn mở, thường dùng trong hệ thống logging, monitoring, và observability. Nó được thiết kế để thu thập, chuyển đổi, và gửi dữ liệu log từ nhiều nguồn khác nhau đến nhiều đích khác nhau.
1. Collect
Lấy log từ nhiều nguồn: file log (nginx, apache, ứng dụng), syslog, journald, container (Docker, Kubernetes), API, message queue (Kafka, RabbitMQ), …
2. Transform / Filter
Chuẩn hóa định dạng log thành JSON hoặc cấu trúc thống nhất.
Thêm, xóa, sửa field trong log.
Gắn nhãn (tag), lọc (filter), ẩn thông tin nhạy cảm.
3. Store / Forward
Đẩy log đến nhiều đích:
- Elasticsearch / OpenSearch (để phục vụ Kibana/Dashboards).
- Splunk, Loki, S3, Hadoop, MongoDB, Kafka.
- Xuất ra file hoặc gửi đến dịch vụ monitoring.
4. Đảm bảo tính ổn định
Có cơ chế buffer (bộ đệm) để không mất log khi hệ thống tạm thời gián đoạn.
Hỗ trợ retry, load balancing, high availability.
Chức năng chính:
- Thu thập log từ nhiều nguồn: Linux, Windows, ứng dụng, ...
- Xử lý & chuẩn hóa log: Fluentd hỗ trợ plugin để định dạng dữ liệu.
- Lưu trữ & tìm kiếm: OpenSearch cho phép query nhanh, hiệu quả.
- Phân tích bảo mật: phát hiện sự kiện bất thường qua alert.
- Trực quan hóa dữ liệu: dashboard.
Cài docker:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo usermod -aG docker $USER newgrp docker sudo apt install python3.12-venv -y python3 -m ensurepip --upgrade |
Triển khai Opensearch - SIEM
Cấu trúc thư mục├── docker-compose.yml
└── default.conf
└── fluent.conf
Tạo file docker-compose.yml
services: # --- OpenSearch Node 1 --- opensearch-node1: image: opensearchproject/opensearch:3 container_name: opensearch-node1 environment: - cluster.name=opensearch-cluster - node.name=opensearch-node1 - discovery.seed_hosts=opensearch-node1,opensearch-node2 - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 - bootstrap.memory_lock=true - OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m - OPENSEARCH_INITIAL_ADMIN_PASSWORD=Chinh123@ ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 volumes: - opensearch-data1:/usr/share/opensearch/data ports: - "9200:9200" - "9600:9600" networks: - opensearch-net # --- OpenSearch Node 2 --- opensearch-node2: image: opensearchproject/opensearch:3 container_name: opensearch-node2 environment: - cluster.name=opensearch-cluster - node.name=opensearch-node2 - discovery.seed_hosts=opensearch-node1,opensearch-node2 - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 - bootstrap.memory_lock=true - OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m - OPENSEARCH_INITIAL_ADMIN_PASSWORD=Chinh123@ ulimits: memlock: soft: -1 hard: -1 nofile: soft: 65536 hard: 65536 volumes: - opensearch-data2:/usr/share/opensearch/data networks: - opensearch-net # --- OpenSearch Dashboards --- opensearch-dashboards: image: opensearchproject/opensearch-dashboards:3 container_name: opensearch-dashboards ports: - "5601:5601" environment: OPENSEARCH_HOSTS: '["https://opensearch-node1:9200","https://opensearch-node2:9200"]' networks: - opensearch-net # --- Nginx --- nginx: image: nginx:1.27.4-alpine container_name: nginx ports: - "8080:80" volumes: - nginx-logs:/var/log/nginx - ./default.conf:/etc/nginx/conf.d/default.conf networks: - opensearch-net # --- Fluentd --- fluentd: image: fluent/fluentd:v1.17-debian container_name: fluentd user: root command: > sh -c "gem install fluent-plugin-opensearch && fluentd -c /fluentd/etc/fluent.conf" volumes: - nginx-logs:/var/log/fluentd - ./fluent.conf:/fluentd/etc/fluent.conf environment: - FLUENTD_CONF=fluent.conf ports: - "24224:24224" - "24225:24225" networks: - opensearch-net volumes: opensearch-data1: opensearch-data2: nginx-logs: fluentd-ui-data: networks: opensearch-net: |
# ========================= # --- Host Linux --- # ========================= <source> @type forward @id in_forward_linux port 24224 bind 0.0.0.0 tag linux </source> <match linux.**> @type opensearch @id out_os_linux @log_level info include_tag_key true host opensearch-node1 port 9200 scheme https ssl_verify false ssl_version TLSv1_2 user admin password Chinh123@ index_name fluentd_linux logstash_format false include_timestamp true time_key_format %Y-%m-%dT%H:%M:%S.%N%z time_key time <buffer> flush_thread_count 1 flush_mode interval flush_interval 10s chunk_limit_size 8M total_limit_size 512M retry_max_interval 30 retry_timeout 72h retry_forever false </buffer> </match> # ========================= # --- Host Windows --- # ========================= <source> @type forward @id in_forward_win port 24225 bind 0.0.0.0 tag win </source> <match win.**> @type opensearch @id out_os_win @log_level info include_tag_key true host opensearch-node1 port 9200 scheme https ssl_verify false ssl_version TLSv1_2 user admin password Chinh123@ index_name fluentd_win logstash_format false include_timestamp true time_key_format %Y-%m-%dT%H:%M:%S.%N%z time_key time <buffer> flush_thread_count 1 flush_mode interval flush_interval 10s chunk_limit_size 8M total_limit_size 512M retry_max_interval 30 retry_timeout 72h retry_forever false </buffer> </match> # ========================= # --- Wazuh Archives --- # ========================= <source> @type tail @id in_tail_wazuh path /wazuh-archives/*/*.log pos_file /fluentd/log/wazuh-archives.pos tag wazuh.archives <parse> @type none </parse> </source> <filter wazuh.archives> @type record_transformer enable_ruby true <record> @timestamp ${Time.now.utc.iso8601} source "wazuh-agent" </record> </filter> <match wazuh.archives> @type opensearch @id out_os_wazuh @log_level info hosts https://opensearch-node1:9200,https://opensearch-node2:9200 scheme https ssl_verify false ssl_version TLSv1_2 user admin password Chinh123@ index_name wazuh-archives-%Y.%m.%d logstash_format true include_timestamp true time_key @timestamp time_key_format %Y-%m-%dT%H:%M:%S.%N%z <buffer> flush_thread_count 1 flush_mode interval flush_interval 10s chunk_limit_size 8M total_limit_size 512M retry_max_interval 30 retry_timeout 72h retry_forever false </buffer> </match> |
server { listen 80; listen [::]:80; server_name localhost; access_log /var/log/nginx/host.access.log main; location / { root /usr/share/nginx/html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } |

Triển khai trên host Linux:
sudo sh -c 'curl https://packages.fluentbit.io/fluentbit.key | gpg --dearmor > /usr/share/keyrings/fluentbit-keyring.gpg' codename=$(grep -oP '(?<=VERSION_CODENAME=).*' /etc/os-release 2>/dev/null || lsb_release -cs 2>/dev/null) echo "deb [signed-by=/usr/share/keyrings/fluentbit-keyring.gpg] https://packages.fluentbit.io/ubuntu/$codename $codename main" | sudo tee /etc/apt/sources.list.d/fluent-bit.list sudo apt update sudo apt-get install fluent-bit |
Chỉnh lại phần OUTPUT để có thể gửi log đến fluentd
[OUTPUT] Name forward Match linux.* Host 10.30.194.7 Port 24224 |
# CPU [INPUT] Name cpu Tag linux.cpu Interval_Sec 10 # Memory [INPUT] Name mem Tag linux.mem Interval_Sec 10 # Disk I/O per device (không có tham số Path) [INPUT] Name disk Tag linux.disk Interval_Sec 10 # Network interface (đúng plugin là netif) [INPUT] Name netif Tag linux.net Interface ens33 Interval_Sec 10 |
sudo systemctl enable fluent-bit sudo systemctl start fluent-bit sudo systemctl status fluent-bit journalctl -u fluent-bit -f |

Triển khai trên host Windows:
Cài fluent bit cho windows: https://packages.fluentbit.io/windows/fluent-bit-4.0.7-win64.exe

Thư mục chứa các file config sau khi cài: C:\fluent-bit\conf
Cấu hình file config C:\fluent-bit\conf\fluent-bit.conf:
[SERVICE] Flush 1 Daemon Off Log_Level info Parsers_File parsers.conf Plugins_File plugins.conf HTTP_Server On HTTP_Listen 0.0.0.0 HTTP_Port 2020 storage.metrics on [INPUT] Name winlog Channels Application,Security,System,Setup,Windows PowerShell Interval_Sec 1 [INPUT] Name winstat Tag win.stat Interval_Sec 1 [FILTER] Name record_modifier Match win.* Record agent fluent-bit Record platform windows # Xuất ra console để test [OUTPUT] Name stdout Match * # Gửi đi server forward [OUTPUT] Name forward Match win.* Host 10.30.194.7 Port 24225 tls Off |
sc.exe create fluent-bit binPath= "C:\fluent-bit\bin\fluent-bit.exe -c C:\fluent-bit\conf\fluent-bit.conf" start= auto obj= LocalSystem DisplayName= "Fluent Bit" Start-Service fluent-bit |