fail2ban-client status sshd sering terlihat normal. Jail aktif, angka Total banned naik, daftar IP terisi. Tapi log /var/log/secure tetap penuh percobaan login dari IP yang katanya sudah di-ban. Penyebabnya biasanya bukan Fail2ban yang mati. Bagian yang mendeteksi serangan masih jalan, sedangkan bagian yang memasang blokir di firewall tidak lagi cocok dengan backend firewall yang baru.
Alurnya kita pisah jadi dua. Pertama, Fail2ban membaca log dan memutuskan sebuah IP harus di-ban. Kedua, Fail2ban menjalankan action, yaitu perintah shell yang memasang rule di firewall. Status jail hanya mencerminkan langkah pertama. Langkah kedua harus kita cek sendiri.
Kenapa Fail2ban bisa terlihat normal padahal blokirnya tidak berlaku
iptables di sistem ini umumnya disediakan oleh iptables-nft. Perintahnya sama, tapi rule-nya diterjemahkan ke nftables di belakang layar.
Yang menentukan cara Fail2ban memblokir adalah banaction, yaitu nama file action di /etc/fail2ban/action.d/ yang dipakai saat ban dan unban. Default bawaan di jail.conf adalah action berbasis iptables. Paket fail2ban-firewalld dari EPEL biasanya menimpanya lewat jail.d/00-firewalld.conf supaya memakai action firewallcmd.
Masalah muncul dari beberapa arah. jail.local lama yang ikut terbawa saat upgrade atau migrasi bisa masih menulis banaction = iptables-multiport. Karena jail.local dibaca setelah jail.d/*.conf, setting lama itu menang. Kalau binary yang dipanggil action tidak ada atau error, perintah ban gagal. Di banyak versi, IP tetap tercatat sebagai banned di memori Fail2ban, jadi status terlihat sehat padahal tidak ada rule yang terpasang.
Perlu diluruskan juga satu anggapan. Rule iptables-nft dan rule firewalld yang jalan berdampingan tidak otomatis saling membatalkan. Di nftables, paket yang di-drop di satu tabel tetap tertolak walaupun tabel lain mengizinkannya. Jadi kalau ban tidak berlaku, penyebabnya biasanya lebih konkret: action gagal, rule masuk ke zone yang salah, port yang diblokir tidak sama dengan port service yang sebenarnya, atau rule hilang setelah firewall di-reload. Keempatnya bisa dicek dari CLI.
Cek backend firewall dan banaction yang benar-benar dipakai
BASH
# Service firewall yang aktif
systemctl is-active firewalld nftables
# iptables versi nf_tables atau legacy
iptables -V
# Paket yang terpasang
rpm -q fail2ban fail2ban-firewalld iptables-nft
# Semua tempat banaction didefinisikan (urutan baca: jail.conf, jail.d/*.conf, jail.local, jail.d/*.local)
grep -rn 'banaction' /etc/fail2ban/jail.conf /etc/fail2ban/jail.d/ /etc/fail2ban/jail.local 2>/dev/null
# Action yang benar-benar dimuat jail sshd
fail2ban-client get sshd actions
# Error saat menjalankan action (lokasi log tergantung logtarget di fail2ban.conf)
grep -i 'error' /var/log/fail2ban.log | tail -n 20
journalctl -u fail2ban --since today | grep -i 'error'
# Port sshd yang sebenarnya listen
ss -tlnp | grep sshdfail2ban-client get sshd actions adalah sumber kebenaran, bukan isi file yang kamu kira sedang dipakai. Kalau firewalld aktif tapi jail masih memuat action iptables, itu tanda pertama ada setting lama yang menimpa. Baris error di log Fail2ban biasanya menyebut nama jail, nama action, dan perintah yang gagal. Itu petunjuk paling langsung.
Cek juga port. Action multiport hanya memblokir port yang disebut di jail. Kalau sshd sudah pindah ke port lain tapi jail masih port = ssh, ban hanya menutup port 22. Penyerang yang menyasar port baru tidak terpengaruh.
Ban IP uji, lalu cari rule-nya di firewall
ignoreip kalau memang mau dites.
Contoh di bawah memakai 198.51.100.20 dari rentang alamat dokumentasi. Ganti dengan IP mesin ujimu.
BASH
# Ban manual lewat Fail2ban
fail2ban-client set sshd banip 198.51.100.20
fail2ban-client status sshd
# Kalau firewalld aktif: zone mana yang dipakai interface publik
firewall-cmd --get-default-zone
firewall-cmd --get-active-zones
firewall-cmd --list-rich-rules
firewall-cmd --zone=public --list-rich-rules
# Cari IP-nya di seluruh ruleset nftables (termasuk isi set/ipset)
nft list ruleset | grep -n '198.51.100.20'--get-active-zones menunjukkan interface publik ada di zone B, rule itu tidak pernah dilewati paket dari internet. Kalau IP ada di set atau rule yang memang dipakai interface yang benar, lanjut ke pembuktian di jaringan.
Nama zone public di contoh di atas hanya umum dipakai. Sesuaikan dengan output --get-active-zones di servermu.
Buktikan paketnya benar-benar ditolak
tcpdump di server, lalu coba koneksi dari mesin uji yang IP-nya sedang di-ban.
BASH
# Di server: lihat paket dari IP uji ke port SSH (sesuaikan port kalau bukan 22)
tcpdump -ni any 'host 198.51.100.20 and tcp port 22'
# Di mesin uji: coba buka koneksi dengan batas waktu 5 detik
nc -vz -w 5 IP_SERVER 22
# Setelah selesai, cabut ban uji di server
fail2ban-client set sshd unbanip 198.51.100.20Penyebab yang sering muncul dan cara membetulkannya
jail.local lama menimpa banaction, perbaiki di file itu. Jangan sunting jail.conf, karena file itu bisa ditimpa saat paket di-update. Di bagian [DEFAULT], set banaction dan banaction_allports ke action yang cocok dengan backend. Pakai action firewallcmd kalau firewalld yang mengelola firewall, atau action nftables kalau kamu memakai nftables langsung tanpa firewalld.
Nama file action berbeda antar versi Fail2ban. Lihat dulu isi /etc/fail2ban/action.d/ sebelum menulis namanya. Setelah itu jalankan fail2ban-client reload, cek ulang fail2ban-client get sshd actions, lalu ulangi tes ban dan tcpdump.
Kalau masalahnya zone, ada dua pilihan. Pastikan interface publik ada di default zone, atau atur action supaya menulis rule ke zone yang benar. Opsi kedua tergantung parameter yang didukung file action di versimu. Baca isi file action-nya sebelum mengubah apa pun.
Kalau masalahnya port, samakan nilai port di jail dengan output ss -tlnp. Pilihan lain, pakai action allports supaya IP yang di-ban tertolak di semua port. Trade-off-nya, IP itu juga tidak bisa mengakses website atau email di server yang sama selama masa ban. Untuk server shared hosting, ini bisa memicu keluhan dari pengguna yang sah di balik IP NAT yang sama.
Satu hal lagi sering terlewat. Rule yang ditambahkan action firewallcmd biasanya hanya runtime. Setelah firewall-cmd --reload, rule itu bisa hilang sementara Fail2ban masih menganggap IP-nya banned. Biasakan menjalankan fail2ban-client reload setelah reload firewalld, lalu cek lagi lewat nft list ruleset.
Dari sisi support, keluhan yang sering masuk adalah log SSH masih ramai padahal Fail2ban terpasang. Langkah pertama yang paling berguna bukan menambah jail atau memperketat maxretry. Langkah pertamanya adalah memastikan satu ban manual benar-benar menghentikan paket.
Setelah upgrade OS, anggap integrasi Fail2ban dengan firewall belum terbukti sampai kamu mengujinya. Cek action yang dimuat, ban satu IP uji milikmu, cari IP itu di ruleset dan zone yang aktif, lalu lihat dengan tcpdump bahwa koneksinya memang tidak dibalas. Tes ini cuma butuh beberapa menit, dan hasilnya lebih bisa dipercaya daripada angka Total banned di status jail.