Blokir Brute Force Login Otomatis dengan Fail2ban
Cara menyusun jail Fail2ban untuk SSH, Nginx, dan login WordPress, memilih bantime dan findtime, mengecualikan IP kantor, dan mengecek IP yang diblokir.
Jawaban singkat
Fail2ban membaca log, menghitung kegagalan login per IP dalam jendela findtime, lalu memblokir IP yang melewati maxretry selama bantime lewat firewall. Aktifkan jail sshd dan nginx-http-auth, buat filter untuk wp-login, masukkan IP kantor ke ignoreip, dan cek dengan fail2ban-client.
Daftar isi
- Bagaimana menyusun jail yang aman?
- Mulai dari jail.local, bukan jail.conf
- Jail untuk SSH
- Jail untuk Nginx dan WordPress
- Bagaimana menguji filter dan mengecek IP yang diblokir?
- Berapa maxretry dan bantime yang wajar?
- Kapan memakai Fail2ban, kapan alat lain?
- Fail2ban bukan pengganti dasar keamanan
- Pertanyaan yang sering diajukan
Tugas Fail2ban sederhana: memantau file log (atau journal systemd), mencari pola kegagalan seperti password salah, lalu memerintahkan firewall memblokir IP pelakunya untuk sementara. Setiap aturan pemantauan disebut jail: satu jail berisi filter (pola yang dicari di log), batas percobaan, durasi blokir, dan aksi yang dijalankan.
Per 4 November 2026, rilis terbaru di halaman GitHub Fail2ban adalah 1.1.1. Contoh di bawah memakai opsi yang tersedia di jail.conf bawaan proyek.
Angka yang salah punya akibat di dua arah. Terlalu longgar, bot tetap bisa mencoba ribuan password per jam ke SSH atau halaman login. Terlalu ketat, staf yang salah ketik dua kali terkunci dari server, atau seluruh kantor terblokir karena berbagi satu IP publik. Fail2ban bekerja paling baik bila angkanya dipilih dengan sengaja.
Bagaimana menyusun jail yang aman?
Mulai dari jail.local, bukan jail.conf
File jail.conf adalah bawaan paket dan bisa tertimpa saat update. Semua perubahan ditulis di /etc/fail2ban/jail.local atau file di /etc/fail2ban/jail.d/. Contoh pengaturan dasar:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime.increment = true
Artinya: IP yang gagal 5 kali dalam 10 menit diblokir 1 jam. bantime.increment membuat blokir berikutnya untuk IP yang sama makin lama. ignoreip berisi IP yang tidak pernah diblokir; ganti 203.0.113.10 dengan IP statis kantormu.
Di distro modern yang mencatat SSH ke journal systemd, tambahkan backend = systemd pada jail terkait. Pastikan juga banaction cocok dengan firewall yang dipakai, misalnya nftables atau firewalld.
Jail untuk SSH
[sshd]
enabled = true
port = ssh
maxretry = 4
Kalau SSH berjalan di port lain, isi port dengan nomor itu. Fail2ban untuk SSH paling berguna bila login password masih dibuka. Dengan login SSH key saja, risiko brute force jauh berkurang, seperti dijelaskan di SSH key vs password.
Jail untuk Nginx dan WordPress
Untuk halaman yang dilindungi basic auth Nginx, Fail2ban menyediakan filter nginx-http-auth:
[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
WordPress tidak menulis kegagalan login ke log server, jadi pendekatannya dua. Pertama, filter sederhana yang menghitung POST ke wp-login.php dan xmlrpc.php di log akses. Buat /etc/fail2ban/filter.d/wordpress-login.conf:
[Definition]
failregex = ^<HOST> .* "POST /(wp-login|xmlrpc)\.php
ignoreregex =
Lalu jail-nya:
[wordpress-login]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 6
findtime = 5m
Filter ini juga menghitung login yang berhasil, karena di log akses keduanya sama-sama POST. Itu sebabnya maxretry dibuat sedikit lebih longgar. Pendekatan kedua adalah plugin WordPress yang menulis login gagal ke log sistem, sehingga filter bisa membedakan gagal dan berhasil. Selebihnya, tetap terapkan dasar pengamanan WordPress seperti update plugin dan password kuat.
Bagaimana menguji filter dan mengecek IP yang diblokir?
Sebelum mengaktifkan filter buatan sendiri, uji dulu terhadap log nyata:
fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/wordpress-login.conf
Hasilnya menunjukkan berapa baris yang cocok. Setelah itu, systemctl restart fail2ban, dan gunakan perintah berikut untuk pemeriksaan sehari-hari:
fail2ban-client statusmenampilkan daftar jail yang aktif.fail2ban-client status sshdmenampilkan jumlah kegagalan dan daftar IP yang sedang diblokir di jail itu.fail2ban-client set sshd unbanip 198.51.100.7membuka blokir satu IP, misalnya rekan kerja yang terkunci.
Berapa maxretry dan bantime yang wajar?
Tabel berikut membandingkan titik awal pengaturan untuk tiap jail. Angkanya bukan standar, sesuaikan setelah melihat log.
| Jail | maxretry | findtime | bantime | Catatan |
|---|---|---|---|---|
| sshd | 3 sampai 5 | 10m | 1h, naik bertahap | Kurang perlu bila hanya SSH key |
| nginx-http-auth | 5 | 10m | 1h | Untuk halaman dengan basic auth |
| wordpress-login | 6 sampai 10 | 5m | 1h | Filter menghitung login berhasil juga |
| recidive | 3 sampai 5 | 1d | 1w | Untuk IP yang berulang kali diblokir jail lain |
Jail recidive membaca log Fail2ban sendiri dan memberi blokir panjang kepada IP yang berkali-kali diblokir jail lain. Ini cara sederhana menangani bot yang sabar menunggu blokir habis.
Kapan memakai Fail2ban, kapan alat lain?
Fail2ban cocok untuk server tunggal yang ingin perlindungan otomatis berbasis log, dengan konfigurasi teks yang mudah dibaca dan tanpa ketergantungan layanan luar. Ia bereaksi setelah kegagalan terjadi, jadi sangat efektif untuk brute force yang berulang dari IP yang sama.
Rate limiting di Nginx lebih tepat bila tujuanmu membatasi laju request sebelum menyentuh aplikasi, termasuk request yang tidak menghasilkan kegagalan login. Keduanya saling melengkapi: Nginx menahan laju, Fail2ban memblokir IP yang terus mendesak.
Bila kamu mengelola beberapa server dan ingin keputusan blokir dibagi antar server, atau ingin memanfaatkan data serangan dari komunitas, pertimbangkan CrowdSec yang dibahas di CrowdSec: proteksi server berbasis data komunitas. Untuk serangan yang datang dari ribuan IP berbeda dengan sedikit percobaan per IP, blokir per IP mana pun kurang efektif, dan perlindungan di level jaringan atau WAF lebih berperan.
Fail2ban bukan pengganti dasar keamanan
Fail2ban tidak menggantikan dasar keamanan server. Password kuat, SSH key, update rutin, dan firewall yang hanya membuka port perlu tetap jadi pondasi, seperti di cara mengamankan VPS baru.
Pertanyaan yang sering diajukan
Apakah Fail2ban bekerja di server yang di belakang Cloudflare?
Untuk SSH tetap bekerja normal, karena SSH tidak lewat Cloudflare. Untuk jail web, log Nginx harus mencatat IP asli pengunjung, dan blokir di firewall server tidak berpengaruh karena koneksinya datang dari IP Cloudflare. Pakai aksi yang memblokir lewat API Cloudflare (Fail2ban menyertakan aksi cloudflare dan cloudflare-token) atau blokir di level Nginx.
Berapa bantime yang ideal?
Tidak ada angka tunggal. Blokir 1 jam dengan bantime.increment aktif adalah titik awal yang wajar: pengguna yang salah ketik tidak terkunci lama, sementara bot yang berulang mendapat blokir makin panjang.
Bagaimana melihat semua IP yang sedang diblokir?
Jalankan fail2ban-client status <nama-jail> untuk tiap jail. Versi Fail2ban yang lebih baru juga menyediakan fail2ban-client banned untuk menampilkan semuanya sekaligus.
Apakah blokir hilang saat server reboot?
Fail2ban menyimpan data blokir di database lokalnya dan secara bawaan memulihkan blokir yang masih berlaku saat layanan berjalan lagi.


