Bản thân fail2ban không tự làm rơi gói tin nào: nó gọi ra một action, và chính action đó mới chỉ định giao thức và cổng. Khi jail báo đã cấm trong lúc daemon vẫn tiếp tục nhận đăng nhập, lệnh cấm đó thường là thật và hẹp hơn những gì nhật ký ngụ ý. Một client kết nối lại qua phương thức truyền tải còn lại sẽ không bao giờ gặp quy tắc đã được cài. Hãy so những gì action đã cài với những gì daemon đang lắng nghe trước khi bạn thay đổi bất cứ thứ gì, vì bằng chứng nằm trong chain firewall mà action đã ghi, chứ không nằm trong danh sách jail.

Đọc chain, đừng đọc bản tóm tắt của jail

fail2ban chèn chain của riêng nó lên trước chain của dịch vụ, nên bảng đếm hiển thị chính xác những gì đang tồn tại. Một chain mang tên jail, chỉ chứa một quy tắc với cột giao thức ghi udp, là lời giải thích trọn vẹn cho việc các lần đăng nhập TCP vẫn cứ đến. Chỉ các gói UDP từ nguồn bị cấm là bị từ chối. Dịch vụ có một listener TCP, và không có gì trong chain đó chạm tới nó.

Cũng hãy để ý hiệu ứng jail lân cận. Một máy chủ có thể trông như được cấu hình hoàn hảo chỉ vì một jail khác cung cấp nửa còn thiếu, và cùng bản dựng đó chẳng làm gì ở nơi không cài jail ấy.

Action chỉ nêu một giao thức, và đó là chỗ nó hỏng

Mỗi banaction là một mẫu lệnh firewall, và giao thức nằm trong một trong các placeholder của nó. Sự hẹp này là có chủ ý, vì một jail web và một jail DNS không có lý do gì phải chặn cùng những cổng giống nhau. Nó trở thành cái bẫy khi dịch vụ lắng nghe trên nhiều hơn một phương thức truyền tải, điều mà các daemon VPN vẫn thường làm. Bộ lọc có thể theo dõi các lần đăng nhập thất bại từ cả hai phương thức trong khi action chỉ phủ một.

Các triển khai SoftEther và OpenVPN thường lắng nghe cả UDP lẫn TCP cùng lúc, và vì dòng nhật ký trông giống nhau ở cả hai, bộ lọc theo dõi cả hai. Sự bất đối xứng này không bao giờ hiện ra trong báo cáo của chính jail. fail2ban đếm số lần thất bại một cách chính xác rồi cài một quy tắc chỉ áp dụng cho một nửa lưu lượng mà những thất bại đó đến từ đó.

Làm cho lệnh cấm phủ cả hai phương thức truyền tải

Hãy sửa ngay trong định nghĩa jail; các quy tắc viết tay sẽ bị xáo trộn ở lần nạp lại kế tiếp. Viết rõ hai action, mỗi giao thức một cái:

action = %(banaction)s[name=%(__name__)s-tcp, actionname=%(__name__)s-tcp, protocol="tcp", port="%(port)s", chain="%(chain)s"]
         %(banaction)s[name=%(__name__)s-udp, actionname=%(__name__)s-udp, protocol="udp", port="%(port)s", chain="%(chain)s"]

Đừng cố rút gọn nó bằng protocol = all. Banaction mặc định là một action multiport, và nó bung ra thành -p <protocol> -m multiport --dports <port>; không có giao thức L4 thì phần khớp cổng chẳng có gì để kiểm tra, nên iptables từ chối quy tắc trong khi jail vẫn báo cấm thành công. Một action toàn cổng như iptables-allports hay nftables-allports thì chấp nhận một mục duy nhất, nhưng nó cấm mọi cổng trên nguồn đó, đó là một quyết định khác và cần lý lẽ riêng. Hãy để protocol ở tcp hoặc udp và chấp nhận hai mục.

Hãy chứng minh quy tắc thực sự tồn tại thay vì tin vào thiết lập, bởi một thiết lập chỉ mô tả ý định cho đến khi một chain giữ lấy nó:

iptables -S f2b-vpn-tcp
iptables -S f2b-vpn-udp

Mỗi chain phải liệt kê một quy tắc, với -p tcp trong chain thứ nhất và -p udp trong chain thứ hai, cả hai đều nêu địa chỉ bị cấm. Sau đó xác nhận cùng địa chỉ đó bị từ chối trên cả hai phương thức truyền tải. Một lệnh cấm mà bạn chưa từng thấy trong chain chỉ là hy vọng, và báo cáo tiếp theo về đúng triệu chứng ấy sẽ lại tiêu tốn đúng một giờ như thế.

Thứ một lệnh cấm vẫn bỏ sót, và ca kế tiếp

Điều action làm là từ chối một nguồn duy nhất, và chỉ trên những cổng được liệt kê trong đó. Nó không làm gì trước một kẻ tấn công đổi địa chỉ liên tục, và nó không thể tách một máy thù địch khỏi một đầu ra NAT cấp nhà mạng bị hàng trăm người dùng chia sẻ, nơi một lệnh cấm khóa luôn cả những người không làm gì. Hãy chắc rằng bộ lọc đọc địa chỉ mà client thực sự có, chứ không phải một header được chuyển tiếp hay địa chỉ proxy. Giữ cửa sổ đủ ngắn để một sai sót tự hết hạn.

Không điều nào ở trên biện minh cho việc bỏ qua phần sửa giao thức; nó biện minh cho việc giữ hai ý cùng lúc. Lệnh cấm hẹp hơn bản tóm tắt của jail, và ngay cả một lệnh cấm hoàn chỉnh cũng hẹp hơn mối đe dọa. Hãy đặt chain firewall bên cạnh danh sách listener của daemon và so từng giao thức một, vì hai danh sách ấy quyết định liệu một lệnh cấm có thể chạm tới dịch vụ hay không.

Hãy giữ lệnh nạp lại và bản liệt kê chain trong runbook ngay cạnh jail. Người kế tiếp sẽ cần cả hai, và bản tóm tắt của jail sẽ chẳng nói gì cho họ.

Bài viết liên quan