Sổ tay kỹ thuật

fail2ban cho sshd/nginx và so sánh với CrowdSec

how-to#fail2ban#security#linux· cập nhật 2026-11-07

Dùng khi cần tự động ban IP brute-force trên server Linux (sshd, nginx), viết filter riêng, và cân nhắc CrowdSec thay thế.

Sửa trang này
Mục lục

Tóm tắt: fail2ban đọc log, đếm lần thất bại theo IP bằng regex trong filter, vượt maxretry trong findtime thì chạy action (thường thêm rule firewall) trong bantime. Cấu hình đặt trong /etc/fail2ban/jail.d/*.local, không sửa jail.conf. CrowdSec cùng ý tưởng nhưng tách phần phát hiện (agent) khỏi phần chặn (bouncer) và chia sẻ danh sách IP xấu theo cộng đồng. Jail sshd cơ bản: xem SSH hardening.

Luồng hoạt động

flowchart LR L["Log (journal / file)"] --> F["filter: regex failregex"] F -->|"đếm theo IP"| J["jail: maxretry / findtime"] J -->|"vượt ngưỡng"| A["action: ban"] A --> N["nftables / iptables"] J -->|"hết bantime"| U["unban"]

Cấu hình

Mặc định chung và jail nginx

/etc/fail2ban/jail.d/defaults.local
[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 198.51.100.0/24
banaction = nftables-multiport
/etc/fail2ban/jail.d/nginx.local
[nginx-http-auth]
enabled = true
port    = http,https
logpath = /var/log/nginx/error.log
 
[nginx-botsearch]
enabled = true
port    = http,https
logpath = /var/log/nginx/access.log

nginx-http-auth và nginx-botsearch là filter có sẵn trong gói fail2ban; banaction phải khớp firewall đang dùng (nftables-multiport hay iptables-multiport, xem ls /etc/fail2ban/action.d/). Giới thiệu firewall: nftables.

Ban lặp lại (recidive)

Jail recidive đọc log của chính fail2ban và ban lâu hơn những IP bị ban nhiều lần:

/etc/fail2ban/jail.d/recidive.local
[recidive]
enabled  = true
bantime  = 1w
findtime = 1d
maxretry = 3

Filter riêng

/etc/fail2ban/filter.d/myapp.conf
[Definition]
failregex = ^<HOST> .* "POST /login HTTP/[0-9.]+" 401
ignoreregex =
/etc/fail2ban/jail.d/myapp.local
[myapp]
enabled = true
port    = http,https
filter  = myapp
logpath = /var/log/nginx/access.log
maxretry = 10

Test filter với log thật trước khi bật jail:

fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/myapp.conf

Áp dụng và vận hành

sudo fail2ban-client -t                       # kiểm tra cú pháp cấu hình
sudo systemctl restart fail2ban
sudo fail2ban-client status                   # danh sách jail
sudo fail2ban-client status nginx-http-auth   # IP đang bị ban
sudo fail2ban-client set nginx-http-auth banip 203.0.113.50
sudo fail2ban-client set nginx-http-auth unbanip 203.0.113.50

fail2ban vs CrowdSec

Tiêu chí fail2ban CrowdSec
Kiến trúc Một daemon: đọc log, ban Agent (phát hiện) + bouncer (chặn) tách riêng
Phát hiện filter regex + ngưỡng của jail Parser + scenario (collection tải từ hub)
Danh sách IP từ cộng đồng Không Có, cộng đồng chia sẻ signal
Chặn ở đâu Action trong fail2ban (firewall) Bouncer: firewall, nginx, Traefik...
Nhiều server Mỗi máy tự quản Một LAPI trung tâm cho nhiều agent/bouncer
Độ phức tạp Thấp, chỉ file ini Cao hơn, có CLI cscli và nhiều thành phần

CrowdSec cài theo hướng dẫn chính thức của dự án (repo + gói + bouncer); lệnh quản lý chính là cscli (vd cscli decisions list, cscli metrics). Chọn fail2ban cho 1-2 máy cần đơn giản; chọn CrowdSec khi có nhiều máy hoặc muốn dùng blocklist cộng đồng. Không chạy cả hai cùng ban một dịch vụ nếu chưa cần.

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Jail không ban dù log có lỗi Sai logpath, hoặc filter không khớp định dạng log fail2ban-regex <log> <filter> xem số dòng matched
status có IP nhưng vẫn truy cập được banaction không khớp firewall thực tế Đổi banaction, kiểm tra rule bằng nft list ruleset
Tự ban chính mình / dải quản trị Thiếu ignoreip Thêm dải quản trị vào ignoreip, unbanip thủ công
Sau reverse proxy mọi request cùng một IP Log ghi IP của proxy/LB Ghi real client IP trong log (real_ip), hoặc ban ở tầng proxy
Jail không chạy sau restart Lỗi cú pháp trong .local fail2ban-client -t, xem journalctl -u fail2ban
Ban mất sau reboot Rule firewall không bền, DB ban chưa nạp lại Kiểm tra dbpurgeage và log fail2ban khi khởi động

Tham khảo