Hướng dẫn cài đặt và cấu hình Fail2ban trên Linux: Chặn tấn công Brute-force SSH và Web Server

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

Chỉ cần vừa thuê một con VPS Linux mới toanh và mở cổng SSH public, bạn check thử log xác thực xem: hàng trăm con bot tự động từ khắp nơi trên thế giới đang thi nhau dò password root mỗi phút. Nếu chỉ đặt mật khẩu đơn giản, server của bạn có thể bị chiếm quyền kiểm soát bất kỳ lúc nào.

Fail2ban chính là công cụ cứu cánh kinh điển giúp bạn dẹp tan nỗi lo này. Nó quét liên tục các file log hệ thống, phát hiện các IP có dấu hiệu dò quét thất bại nhiều lần và tự động tạo rule trên tường lửa (iptables/nftables) để chặn đứng IP đó.

1. Quick start: Cài đặt và kích hoạt bảo vệ SSH trong 5 phút

Để bắt đầu nhanh nhất trên Ubuntu/Debian hoặc CentOS/AlmaLinux, bạn chỉ cần thực hiện lần lượt các bước dưới đây.

Cài đặt Fail2ban

Với hệ điều hành Ubuntu hoặc Debian:

sudo apt update
sudo apt install -y fail2ban

Với họ RHEL/AlmaLinux/Rocky Linux (yêu cầu bật repo EPEL trước):

sudo dnf install -y epel-release
sudo dnf install -y fail2ban

Tạo file cấu hình riêng biệt

Nguyên tắc sống còn với Fail2ban là không bao giờ sửa trực tiếp file gốc /etc/fail2ban/jail.conf vì mỗi lần cập nhật phần mềm, file này sẽ bị ghi đè. Thay vào đó, hãy tạo file jail.local:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Cấu hình bảo vệ SSH nhanh

Mở file /etc/fail2ban/jail.local bằng text editor bạn quen dùng:

sudo nano /etc/fail2ban/jail.local

Tìm đến block [sshd] hoặc thêm nội dung sau vào cuối file:

[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(syslog_backend)s
maxretry = 5
findtime = 600
bantime = 3600

Khởi động dịch vụ

Lưu file lại và chạy lệnh để Fail2ban bắt đầu hoạt động:

sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

Kiểm tra xem jail bảo vệ SSH đã chạy hay chưa:

sudo fail2ban-client status sshd

2. Giải thích chi tiết các thông số cốt lõi trong Fail2ban

Sau khi đã có lớp khiên ban đầu, bạn cần hiểu rõ cơ chế hoạt động đằng sau để điều chỉnh cho phù hợp với môi trường thực tế.

Các thông số mặc định (DEFAULT section)

Trong file jail.local, các thông số quan trọng nhất bao gồm:

  • ignoreip: Danh sách IP tin cậy không bao giờ bị chặn. Ví dụ IP tĩnh của công ty, IP nhà bạn hoặc dải mạng nội bộ (127.0.0.1/8 ::1 192.168.1.0/24).
  • bantime: Thời gian một IP vi phạm bị khóa tính bằng giây. Ví dụ 3600 tương đương 1 giờ. Nếu muốn chặn vĩnh viễn, bạn có thể đặt số âm (-1).
  • findtime: Khung cửa sổ thời gian (giây) mà Fail2ban theo dõi các lần thử đăng nhập thất bại.
  • maxretry: Số lần thử sai tối đa trong khoảng findtime trước khi IP bị tống vào danh sách đen.

Ví dụ: Với findtime = 600 và maxretry = 3, nếu một IP gõ sai mật khẩu SSH 3 lần trong vòng 10 phút, IP đó sẽ lập tức bị chặn trong khoảng thời gian quy định bởi bantime.

Cấu trúc Jail và Filter

Fail2ban vận hành dựa trên hai thành phần chính:

  • Filter: Nằm tại thư mục /etc/fail2ban/filter.d/, chứa các biểu thức chính quy (Regex) dùng để bắt các dòng báo lỗi đăng nhập thất bại trong log.
  • Jail: Kết hợp một Filter với một Action (hành động chặn qua iptables/nftables hoặc gửi email thông báo) áp dụng cho một dịch vụ cụ thể.

3. Nâng cao: Mở rộng bảo vệ Nginx và Web Server

Không chỉ bảo vệ cổng SSH, Fail2ban còn cực kỳ hiệu quả trong việc ngăn chặn các cuộc quét dò lỗ hổng đường dẫn (directory traversal) hoặc tấn công brute-force trang đăng nhập admin (như wp-login.php trên WordPress).

Chặn dò quét URL độc hại trên Nginx

Mở file /etc/fail2ban/jail.local và cấu hình thêm jail chặn các truy vấn tìm kiếm file nhạy cảm lặp lại liên tục gây mã lỗi 404/403:

[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 300
bantime = 86400

Chặn Brute-force trang đăng nhập WordPress/Web App

Tạo một filter tùy chỉnh để bắt các request POST liên tục vào trang xác thực. Tạo file /etc/fail2ban/filter.d/nginx-login.conf:

[Definition]
failregex = ^<HOST> -.* "POST /wp-login.php HTTP/.*" 200
            ^<HOST> -.* "POST /login HTTP/.*" 200
ignoreregex =

Sau đó thêm block jail vào /etc/fail2ban/jail.local:

[nginx-login]
enabled = true
port = http,https
filter = nginx-login
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 600
bantime = 7200

Nạp lại cấu hình để các jail mới có hiệu lực ngay lập tức:

sudo fail2ban-client reload

4. Quản trị và Tips thực tế từ môi trường Production

Sau 3 năm quản lý hơn 10 VPS chạy Linux, mình rút ra kinh nghiệm là nên kiểm tra kỹ trước khi áp dụng lên production. Đã có lần một bạn đồng nghiệp gõ nhầm mật khẩu VPN/SSH và bị Fail2ban khóa sạch quyền truy cập từ IP văn phòng giữa giờ cao điểm chỉ vì quên khai báo whitelist.

Các lệnh quản trị hàng ngày bạn cần nhớ

Xem danh sách các jail đang kích hoạt và số lượng IP bị ban:

sudo fail2ban-client status

Xem chi tiết danh sách IP đang bị khóa ở jail sshd:

sudo fail2ban-client status sshd

Nếu chẳng may bạn hoặc đồng nghiệp tự khóa IP của chính mình, hãy mở khóa ngay bằng lệnh:

sudo fail2ban-client set sshd unbanip 203.0.113.45

Kiểm tra trực tiếp log hoạt động của Fail2ban để phân tích:

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

Những lưu ý thực chiến không nên bỏ qua

  • Luôn luôn whitelist IP văn phòng/IP cá nhân: Thêm dải IP mạng nhà mạng của bạn vào ignoreip trước khi bật bất kỳ jail nào có giá trị bantime lớn.
  • Cẩn thận khi đổi cổng SSH: Nếu bạn đổi port SSH mặc định từ 22 sang ví dụ 2222, hãy nhớ cập nhật lại dòng port = 2222 trong block [sshd] của jail.local. Nếu không, Fail2ban sẽ vẫn tạo rule iptables chặn cổng 22, còn cổng mới thì bỏ ngỏ.
  • Kiểm tra Regex trước khi kích hoạt: Dùng công cụ test có sẵn của Fail2ban để xem filter của bạn có bắt đúng log hay không trước khi áp dụng thật:
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/nginx-login.conf

Nắm vững Fail2ban giúp hệ thống của bạn tăng thêm một tầng phòng vệ chủ động, loại bỏ tới 99% các đợt càn quét tự động từ botnet mà không tốn nhiều tài nguyên máy chủ.

Share: