Bối cảnh & Tại sao cần: Khi Firewall truyền thống là chưa đủ
Chỉ dựng firewalld, đóng hết cổng thừa rồi đổi port SSH sang 2222 là server đã an toàn? Không hề. Một truy vấn SQL Injection hay một request khai thác lỗ hổng Log4j/RCE vẫn chui lọt qua cổng 80 hoặc 443 bình thường. Tường lửa L3/L4 như iptables hay firewalld chỉ kiểm tra IP nguồn, IP đích và Port. Phần payload bên trong gói tin thì nó mù tịt.
Đó là lý do bạn cần NIDS/NIPS (Network Intrusion Detection / Prevention System) với khả năng phân tích gói tin sâu (Deep Packet Inspection – DPI).
Khi dựng cụm gateway CentOS Stream 9 hứng khoảng 300 – 500 Mbps traffic cho công ty, mình chọn Suricata làm chốt chặn chính. Khác với Snort 2.x chạy đơn luồng dễ nghẽn CPU, Suricata scale đa luồng rất mượt trên các máy chủ 16–32 core. Hệ thống phân bổ đều tải qua cơ chế AF-PACKET, không lo rớt gói khi lưu lượng tăng đột biến.
Cài đặt Suricata trên CentOS Stream 9
Suricata nằm sẵn trong kho EPEL của CentOS Stream 9. Tuy nhiên, trước hết bạn cần bật repository CRB (CodeReady Builder) để kéo đủ các thư viện phụ thuộc.
Cập nhật hệ thống và kích hoạt các kho cần thiết:
dnf update -y
dnf config-manager --set-enabled crb
dnf install -y epel-release epel-next-release
Cài đặt gói Suricata cùng hai công cụ bổ trợ hữu ích: jq (xử lý JSON log) và ethtool (chỉnh thông số card mạng):
dnf install -y suricata jq ethtool
Kiểm tra các module đi kèm sau khi cài xong:
suricata --build-info
Hãy để mắt tới ba mục: AF_PACKET, PCRE và Libnetfilter_queue. Nếu tất cả đều báo YES, engine đã sẵn sàng cho cả hai chế độ IDS (nghe thụ động) lẫn IPS (chặn inline qua NFQUEUE).
Cấu hình chi tiết Suricata: Chế độ IDS và Tải Rule
1. Xác định card mạng và subnet nội bộ
Xem danh sách giao diện mạng hiện có:
ip -br addr
Giả sử card mạng nhận traffic ngoài là eth0 và dải IP máy chủ nội bộ cần bảo vệ là 192.168.1.0/24.
2. Chỉnh sửa file cấu hình suricata.yaml
Mở file cấu hình chính /etc/suricata/suricata.yaml:
nano /etc/suricata/suricata.yaml
Bạn cần tập trung chỉnh hai vị trí cốt lõi:
Khai báo subnet nội bộ (HOME_NET): Đừng để mặc định là any. Gán đúng dải IP server quản lý giúp Suricata xác định đúng chiều traffic và giảm thiểu cảnh báo giả (false positive):
vars:
address-groups:
HOME_NET: "[192.168.1.0/24, 10.0.0.0/8]"
EXTERNAL_NET: "!$HOME_NET"
Cấu hình capture AF-PACKET: Cuộn tới phần af-packet và đổi interface: eth0 cho khớp với card mạng thực tế:
af-packet:
- interface: eth0
cluster-id: 99
cluster-type: cluster_flow
defrag: yes
use-mmap: yes
tpacket-v3: yes
3. Tắt Packet Offloading trên card mạng (Bắt buộc)
Card mạng hiện đại thường bật sẵn tính năng LRO/GRO để gộp nhiều gói tin nhỏ thành khối lớn (tới 64KB) trước khi chuyển lên OS. Cơ chế này giảm tải cho CPU nhưng lại phá hỏng engine DPI. Suricata không thể đối soát signature trên các gói đã bị gộp lệch chuẩn, dẫn tới việc bỏ lọt tấn công.
Tắt ngay các tính năng offload trên card giám sát:
ethtool -K eth0 rx off tx off gso off gro off
Để thiết lập này tự động áp dụng sau mỗi lần reboot trên CentOS Stream 9, dùng NetworkManager:
nmcli connection modify eth0 ethtool.feature-rx off ethtool.feature-tx off ethtool.feature-gro off ethtool.feature-gso off
nmcli connection up eth0
4. Tải tập luật (Signatures) với suricata-update
Suricata tích hợp sẵn công cụ suricata-update. Lệnh này tự động kéo bộ luật miễn phí Emerging Threats Open (ET Open) với hơn 40.000 signature được cập nhật hàng ngày:
suricata-update
Bộ rule hoàn chỉnh sẽ nằm ở /var/lib/suricata/rules/suricata.rules. Trước khi bật service, hãy kiểm tra xem file YAML có bị lỗi thụt dòng hay sai cú pháp không:
suricata -T -c /etc/suricata/suricata.yaml -v
Dòng thông báo Configuration provided was successfully verified xuất hiện nghĩa là mọi thứ đã chuẩn. Khởi động service:
systemctl enable --now suricata
systemctl status suricata
Kiểm tra & Monitoring: Đọc Log và Giả lập Tấn công
Suricata ghi log vào thư mục /var/log/suricata/ với hai file trọng tâm:
fast.log: Ghi vắn tắt 1 dòng cho mỗi alert, rất tiện để dùng lệnhtail -fsoi nhanh tình trạng mạng.eve.json: Log JSON chi tiết chứa đầy đủ metadata, DNS query, HTTP header, TLS handshake và flow mạng.
1. Bắn payload test kích hoạt cảnh báo
Bạn không cần cài tool hack phức tạp. Hãy dùng curl gửi request tới test domain chuẩn của cộng đồng IDS:
curl http://testmyids.com
Trang web này trả về chuỗi uid=0(root) gid=0(root), mô phỏng phản hồi của một máy chủ bị chiếm quyền root. Kiểm tra ngay fast.log:
tail -n 5 /var/log/suricata/fast.log
Suricata sẽ bắt được ngay lập tức:
[1:2100498:7] GPL ATTACK_RESPONSE id check returned root [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 217.160.0.187:80 -> 192.168.1.50:49284
2. Lọc log thời gian thực với jq
File eve.json chứa cả chục nghìn event mỗi giờ, mở bằng nano hay cat sẽ rất rối mắt. Bạn hãy dùng jq để chỉ bóc tách các alert quan trọng:
tail -f /var/log/suricata/eve.json | jq -c 'select(.event_type=="alert") | {time: .timestamp, alert: .alert.signature, src: .src_ip, dst: .dest_ip}'
Kết quả hiển thị ngắn gọn, dễ tích hợp tiếp vào Graylog hoặc ELK Stack:
{"time":"2026-11-05T12:00:15.123456+0700","alert":"GPL ATTACK_RESPONSE id check returned root","src":"217.160.0.187","dst":"192.168.1.50"}
Kinh nghiệm thực tế: Đừng vội chuyển ngay sang chế độ IPS để drop gói tin. Hãy để Suricata chạy chế độ IDS tối thiểu 1–2 tuần. Khoảng thời gian này giúp bạn theo dõi hành vi hệ thống, tinh chỉnh rule và thêm whitelist cho các tool scan nội bộ hay backup định kỳ. Tránh trường hợp vừa bật IPS lên đã chặn nhầm khách hàng thật.

