Cài Fail2ban Chống Brute-Force VPS 2026 — Kinh Nghiệm Thực Tế Từ 200+ IP/ngày

📅 24/06/2026 · ⏱ 14 phút đọc · 🏷 Bảo mật · SSH · WordPress

1. Bạn Đang Bị Dò Mật Khẩu Mỗi Ngày Mà Không Biết

Tôi có một thói quen: cứ mỗi lần mở VPS mới, việc đầu tiên là kiểm tra log SSH. Mỗi lần như vậy, tôi thấy cùng một cảnh — hàng trăm dòng Failed password for root from xxx.xxx.xxx.xxx tua nhanh như bảng giá chứng khoán. Một VPS chỉ cần mở cổng 22 ra internet chưa đầy 5 phút là đã có bot Trung Quốc, Nga, Mỹ quét tới.

Con số thực tế từ một VPS nhỏ của tôi chạy thử nghiệm tuần trước: 237 IP độc nhất thử SSH trong 24 giờ, tổng cộng hơn 4.800 lần login thất bại. Chưa kể thêm vài trăm request vào /wp-login.php nếu bạn chạy WordPress.

UFW (tường lửa) chặn cổng thì tốt, nhưng nếu phải mở cổng 22 để quản trị, bạn cần lớp bảo vệ thứ hai. Đó là Fail2ban — một con bot "bảo kê" nằm đọc log, phát hiện kẻ đáng ngờ, và tự động khóa IP chúng ra khỏi server của bạn.

🔑 Fail2ban không phải thần dược: Nó là lớp phòng thủ thứ hai, KHÔNG thay thế cho SSH key, tắt root login, và cập nhật thường xuyên. Nếu bạn chưa làm những thứ cơ bản đó, làm chúng trước — rồi hãy đọc tiếp bài này.

2. Fail2ban Là Gì? Nó Hoạt Động Như Thế Nào?

Fail2ban là phần mềm mã nguồn mở viết bằng Python, chạy nền trên Linux. Cách nó hoạt động đơn giản đến bất ngờ:

  1. Đọc log: Nó đuôi theo file log của SSH, Nginx, Apache... đọc từng dòng mới xuất hiện.
  2. Khớp mẫu (regex): Mỗi dịch vụ có một bộ "filter" — regex để nhận diện login thất bại. Ví dụ SSH: Failed password for .* from <HOST>
  3. Đếm số lần vi phạm: Nếu cùng một IP có N lần thất bại trong khoảng thời gian T → bị coi là tấn công.
  4. Hành động (action): Tự động thêm IP vào tường lửa (UFW/iptables), chặn trong X phút. Có thể gửi email cảnh báo.

Nghe thì đơn giản, nhưng Fail2ban giải quyết một vấn đề mà tường lửa tĩnh không làm được: phản ứng tự động với hành vi đáng ngờ theo thời gian thực. Tường lửa chặn cổng, Fail2ban chặn kẻ tấn công — hai thứ bổ trợ cho nhau.

3. Fail2ban Có Thực Sự Cần Thiết Năm 2026?

Câu hỏi nhiều người hỏi: "Tôi dùng SSH key rồi, cần Fail2ban làm gì?"

Thực tế: SSH key bảo vệ bạn khỏi bị chiếm quyền, nhưng không bảo vệ bạn khỏi lãng phí tài nguyên. Mỗi lần bot thử login là một lần CPU xử lý, RAM cấp phát, disk ghi log. Trên VPS 1GB RAM, 5.000 lần thử mỗi ngày không làm server sập, nhưng nó chiếm tài nguyên đáng kể, đặc biệt nếu bạn chạy thêm web server hay database.

Thứ hai: log noise. Khi bạn thực sự cần debug một vấn đề SSH, việc phải lọc qua 4.800 dòng "Failed password" là cực hình. Fail2ban dọn sạch đống nhiễu đó.

Thứ ba: WordPress vẫn là một trong những mục tiêu bị tấn công brute-force nhiều nhất năm 2026. wp-login.phpxmlrpc.php là hai điểm nóng. Nếu bạn chạy WordPress trên VPS, Fail2ban là lớp phòng thủ không thể thiếu cho phần web.

Tình huốngCần Fail2ban?Lý do
VPS chỉ dùng SSH key, không chạy webCó, mức nhẹGiảm noise log, tiết kiệm CPU
VPS chạy WordPress + SSHBắt buộcwp-login.php là mục tiêu hàng đầu
VPS chạy nhiều service (mail, DB, web)Bắt buộcMỗi service mở thêm một cổng là một điểm yếu
VPS sau Cloudflare Tunnel / VPN nội bộTùy chọnKhông expose port ra ngoài thì ít rủi ro hơn
VPS production có SLABắt buộcMột đợt brute-force có thể làm chậm cả server

4. Cài Đặt Fail2ban Trên Ubuntu 24.04

Bắt tay vào làm. Tôi dùng Ubuntu 24.04 LTS, phiên bản Fail2ban trong repo là 1.0.x — đủ mới và ổn định.

Bước 1: Cài đặt

sudo apt update
sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban --no-pager

Kiểm tra nó đã chạy chưa:

sudo fail2ban-client ping

Kết quả mong đợi: Server replied: pong. Nếu không thấy, kiểm tra systemd status.

Lúc này sudo fail2ban-client status sẽ trả về danh sách jail trống — chưa có cấu hình nào. Đừng lo, mình sẽ tạo ngay.

Bước 2: Tạo file cấu hình — đừng sửa jail.conf

Đây là sai lầm kinh điển của người mới: mở /etc/fail2ban/jail.conf ra sửa. Đừng làm vậy. File này sẽ bị ghi đè mỗi khi bạn cập nhật package. Thay vào đó, tạo file jail.local — Fail2ban tự động merge nó lên trên mặc định.

sudo nano /etc/fail2ban/jail.local

Dán cấu hình cơ bản này vào:

[DEFAULT]
# Dùng systemd journal — cách ổn định nhất trên Ubuntu 2024+
backend = systemd

# Tích hợp với UFW
banaction = ufw

# Tham số khóa IP
findtime = 10m        # Khoảng thời gian đếm vi phạm
maxretry = 5          # Số lần sai thì khóa
bantime = 1h          # Thời gian khóa (giây hoặc h/m/d)

# Whitelist IP của bạn — quan trọng!
ignoreip = 127.0.0.1/8 ::1

# Email cảnh báo (tùy chọn, cần cấu hình MTA)
destemail = root@localhost
sender = fail2ban@yourdomain.com
mta = sendmail
action = %(action_)s

# ========== SSH Jail ==========
[sshd]
enabled = true
# systemd backend tự tìm auth log, không cần logpath
# Nếu dùng file backend, thêm: logpath = /var/log/auth.log
⚠️ Kinh nghiệm xương máu: findtime=10m, maxretry=5, bantime=1h là bộ tham số an toàn cho người mới. Tôi từng đặt maxretry=3, bantime=24h và tự khóa chính mình khi gõ sai mật khẩu SSH 3 lần lúc nửa đêm. May là vẫn còn phiên SSH đang mở. Luôn giữ một cửa sổ SSH dự phòng khi chỉnh Fail2ban.

Bước 3: Khởi động lại và kiểm tra

sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Output mẫu:

Status for the jail: sshd
|- Filter
|  |- Currently failed: 3
|  |- Total failed:     241
|  `- File list:        systemd-journal
`- Actions
   |- Currently banned: 12
   |- Total banned:     47
   `- Banned IP list:   45.33.32.156 61.177.172.14 ...

Thấy "Currently banned: 12" là biết nó đang hoạt động. Nếu bạn để VPS online vài giờ, con số này sẽ tăng lên trông thấy.

5. Kiểm Tra UFW: Chặn Có Thật Không?

Fail2ban báo "banned" nhưng firewall có thực sự chặn không? Đây là cái bẫy: Fail2ban tưởng nó đang chặn, nhưng action không khớp với firewall bạn dùng → kẻ tấn công vẫn vào bình thường.

Test nhanh:

# Kiểm tra UFW đã bật chưa
sudo ufw status verbose

# Ban thủ công một IP test (dùng IP documentation, không phải IP thật)
sudo fail2ban-client set sshd banip 203.0.113.50

# Kiểm tra UFW có rule mới không
sudo ufw status numbered | grep 203.0.113.50

# Gỡ ban sau khi test
sudo fail2ban-client set sshd unbanip 203.0.113.50

Nếu UFW hiện rule "DENY FROM 203.0.113.50" thì OK. Nếu không thấy gì, banaction của bạn sai — sửa thành banaction = ufw hoặc banaction = iptables-multiport tùy vào firewall bạn đang dùng.

🛑 Nếu dùng iptables (không UFW): đổi banaction = iptables-multiport trong [DEFAULT]. Nếu dùng nftables: banaction = nftables-multiport. Fail2ban 1.0+ hỗ trợ đủ cả ba.

6. Bảo Vệ WordPress: Chặn Brute-Force wp-login.php

WordPress là miếng mồi béo bở cho bot brute-force. Mỗi lần thử wp-login.php với username "admin" và password random là một lần PHP xử lý, MySQL query — tốn tài nguyên hơn SSH nhiều. Một VPS nhỏ có thể bị "đơ" nếu 20-30 bot cùng lúc dò WordPress.

Tạo bộ lọc riêng cho WordPress

sudo nano /etc/fail2ban/filter.d/wordpress.conf

Dán vào:

[Definition]
# Khớp request POST/GET tới wp-login.php và xmlrpc.php
failregex = ^<HOST> .* "(POST|GET) /(wp-login\.php|xmlrpc\.php).*" (200|401|403) .*

ignoreregex =

Regex này quét access log của web server. Khi một IP gửi quá nhiều request đến trang login WordPress trong thời gian ngắn → ban.

Thêm jail WordPress vào jail.local

# Thêm vào cuối /etc/fail2ban/jail.local:

[wordpress]
enabled = true
filter = wordpress
# Nếu dùng Nginx:
logpath = /var/log/nginx/access.log
# Nếu dùng Apache:
# logpath = /var/log/apache2/access.log
port = http,https
findtime = 5m
maxretry = 10
bantime = 2h

Tham số WordPress nên "dễ thở" hơn SSH: maxretry=10, findtime=5m. Lý do: người dùng thật cũng gõ sai mật khẩu WordPress vài lần, không nên khóa họ quá nhanh. Nhưng nếu một IP gửi 10 request trong 5 phút — chắc chắn là bot.

Khởi động lại và kiểm tra jail mới:

sudo systemctl restart fail2ban
sudo fail2ban-client status wordpress
💡 Nếu log Nginx của bạn là JSON (định dạng mới hơn): regex trên sẽ không khớp. Cách xử lý: đổi log format về dạng "combined" cũ trong Nginx config, hoặc viết regex JSON-aware. Cá nhân tôi thấy đổi về combined format dễ hơn — đặc biệt khi bạn không phải chuyên gia regex.

7. Tối Ưu Tham Số — Không Phải Càng Chặt Càng Tốt

Sau vài ngày chạy Fail2ban, bạn sẽ có số liệu để tinh chỉnh. Đây là chiến lược tôi dùng qua nhiều server:

Giai đoạnfindtimemaxretrybantimeMục đích
Mới cài (tuần đầu)10m51hAn toàn, tránh tự khóa mình
Ổn định (sau 1 tuần)10m36hChặn nặng tay hơn, tiết kiệm CPU
Server bị tấn công mạnh5m224hPhản ứng nhanh, khóa lâu
Server nội bộ / VPN only1h101hThoáng, vì chỉ có người nhà

Một lệnh tiện dụng để xem log Fail2ban theo thời gian thực:

sudo tail -f /var/log/fail2ban.log

Bạn sẽ thấy từng IP bị ban và unban. Nếu thấy IP nào lặp lại quá thường xuyên, có thể thêm nó vào blocklist vĩnh viễn bằng UFW trực tiếp.

8. Cảnh Báo Email — Để Biết Khi Có Chuyện

Fail2ban có thể gửi email mỗi khi khóa một IP. Nhưng thành thật mà nói: nếu server bạn bị tấn công 200 IP/ngày, bạn KHÔNG muốn nhận 200 email. Sẽ thành spam.

Cách tôi dùng: tắt cảnh báo từng lần (action = %(action_)s thay vì action_mw), nhưng dùng một script cron nhỏ kiểm tra số IP bị ban mỗi 6 giờ:

# Thêm vào crontab (crontab -e)
0 */6 * * * sudo fail2ban-client status sshd | grep "Currently banned" | mail -s "Fail2ban Status" admin@yourdomain.com

Như vậy bạn chỉ nhận email khi có điều bất thường (số IP bị ban tăng đột biến), không bị spam hàng trăm email mỗi ngày.

9. Mở Khóa IP — Khi Bạn Lỡ Khóa Nhầm

Chuyện này ai cũng gặp ít nhất một lần: bạn đang ở quán cà phê, gõ sai mật khẩu SSH 3 lần, và... bị khóa khỏi chính server của mình.

Cách xử lý:

🎯 Mẹo phòng thân: Luôn whitelist IP nhà riêng và văn phòng trong ignoreip. Ví dụ: ignoreip = 127.0.0.1/8 ::1 113.xxx.xxx.xxx 42.xxx.xxx.xxx. Đặc biệt nếu bạn có IP tĩnh từ FPT hay Viettel, hãy thêm nó vào ngay từ đầu.

10. Các Jail Khác Đáng Cài

SSH và WordPress là hai jail phổ biến nhất, nhưng Fail2ban còn hỗ trợ nhiều dịch vụ khác:

JailDịch vụ bảo vệKhi nào cần
sshdSSH loginLuôn luôn, bất kể VPS dùng làm gì
wordpresswp-login.php, xmlrpc.phpKhi host WordPress
nginx-http-authHTTP basic auth trên NginxKhi dùng .htpasswd Nginx
nginx-botsearchBot tìm kiếm URL nhạy cảmServer public chạy web app
postfixSMTP auth brute-forceKhi tự host mail server
dovecotIMAP/POP3 loginKhi tự host mail server
mysqld-authMySQL login thất bạiKhi MySQL mở port ra ngoài

Để bật thêm jail, chỉ cần thêm block tương tự [sshd] trong jail.local với enabled = true. Mỗi jail có filter mặc định trong /etc/fail2ban/filter.d/ nên bạn không cần tự viết regex.

11. Fail2ban So Với Các Công Cụ Khác

Năm 2026, có vài lựa chọn khác ngoài Fail2ban:

Công cụƯu điểmNhược điểmPhù hợp
Fail2banNhẹ, miễn phí, cộng đồng lớnRegex-based, cấu hình thủ côngVPS nhỏ, cá nhân, ai cần đơn giản
CrowdSecBehavior-based + community IP blocklistNặng hơn, học curve cao hơnServer production, team DevOps
SSHGuardCực nhẹ, C-based, ít dependencyÍt tính năng, ít jail hơnVPS siêu nhỏ, embedded system
Cloudflare WAFChặn từ edge, không tốn CPU VPSChỉ bảo vệ web, không bảo vệ SSHWeb server sau Cloudflare

Fail2ban vẫn là lựa chọn số một cho VPS cá nhân và vừa-nhỏ năm 2026 vì nó đơn giản, nhẹ, và "just works". CrowdSec mạnh hơn nhưng dành cho ai có thời gian học và cấu hình.

12. Những Sai Lầm Thường Gặp

Qua vài năm dùng Fail2ban trên các VPS, đây là những thứ tôi phải tự sửa hoặc thấy người khác mắc:

  1. Sửa jail.conf thay vì jail.local: Package update đè mất hết config. Luôn dùng .local.
  2. Không whitelist IP của chính mình: Rồi tự khóa mình khi gõ sai mật khẩu. Thêm ignoreip ngay từ đầu.
  3. bantime quá ngắn (vài phút): Bot sẽ retry sau vài phút, fail2ban thành vô nghĩa. Tối thiểu 1 giờ.
  4. maxretry quá thấp (1-2 lần): Gõ sai mật khẩu một lần là bị khóa. Người dùng thật cũng gõ sai.
  5. Không kiểm tra ban action có hoạt động không: Fail2ban báo banned nhưng firewall không có rule. Luôn test thủ công ít nhất một lần.
  6. Dùng file log backend trên systemd system: Ubuntu 22.04+ dùng systemd-journal, nếu bạn chỉ định logpath = /var/log/auth.log có thể trỏ sai. Dùng backend = systemd thì không cần logpath.
  7. Không cập nhật Fail2ban: Phiên bản cũ có regex lỗi thời, không bắt được pattern tấn công mới.

🚀 Muốn tự cài Fail2ban nhưng chưa có VPS?

Thuê VPS giá rẻ từ 40K/tháng, IP riêng, cài đặt tự do mọi phần mềm bảo mật.

Thuê VPS Ngay

13. Tổng Kết

Fail2ban không phải là phần mềm hào nhoáng. Nó không có dashboard đẹp, không có AI/ML gì cả. Nó chỉ là một con Python script cần mẫn đọc log và chặn IP. Nhưng trong thế giới mà mỗi VPS mới mở cổng 22 là bị quét trong vài phút, Fail2ban là công cụ bạn không thể không cài.

Cài mất 5 phút. Cấu hình cơ bản mất 10 phút. Đổi lại, server của bạn được bảo vệ 24/7 trước hàng trăm bot quét tự động mỗi ngày — mà không tốn một xu nào.

Nếu bạn nghiêm túc về bảo mật VPS, đọc thêm các bài liên quan bên dưới.