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
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 198.51.100.0/24
banaction = nftables-multiport[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.lognginx-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:
[recidive]
enabled = true
bantime = 1w
findtime = 1d
maxretry = 3Filter riêng
[Definition]
failregex = ^<HOST> .* "POST /login HTTP/[0-9.]+" 401
ignoreregex =[myapp]
enabled = true
port = http,https
filter = myapp
logpath = /var/log/nginx/access.log
maxretry = 10Test 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.50fail2ban 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
man jail.conf,man fail2ban-client,man fail2ban-regex- fail2ban trên GitHub
- CrowdSec documentation