Fail2ban: konfigurasi perlindungan SSH dari serangan tebak kata sandi
Fail2ban membaca log layanan, menemukan percobaan login gagal yang berulang, dan memblokir sementara IP penyerang melalui firewall. Untuk melindungi SSH cukup memasang paket, membuat /etc/fail2ban/jail.local dengan bagian [sshd] (enabled = true, maxretry, findtime, bantime), lalu me-restart layanan; statusnya diperiksa dengan perintah fail2ban-client status sshd.
Fail2ban adalah daemon yang memantau log layanan, mendeteksi percobaan login gagal yang berulang, dan memblokir sementara IP address asal percobaan tersebut. Untuk SSH, ini adalah perlindungan paling sederhana terhadap serangan tebak kata sandi: bot berhenti mengetuk server setelah beberapa kesalahan. Di bawah ini konfigurasi fail2ban dari instalasi sampai pemeriksaan blokir dan kesalahan umum.
Mengapa perlu fail2ban jika sudah memakai kunci SSH
Setiap server dengan port 22 terbuka mulai menerima percobaan login dari bot dalam hitungan menit setelah dinyalakan. Coba periksa sendiri:
$ sudo journalctl -u ssh --since "1 hour ago" | grep -c "Failed password"
412
Jika login dengan kata sandi dinonaktifkan dan hanya kunci yang dipakai, membobol akses hampir mustahil. Meski begitu, fail2ban tetap berguna: ia mengurangi kebisingan di log, menurunkan beban akibat ribuan koneksi, dan melindungi dari kesalahan konfigurasi ketika login dengan kata sandi tanpa sengaja tetap aktif. Ini adalah lapisan perlindungan kedua, bukan pengganti kunci.
Cara kerja fail2ban
Logikanya terdiri dari tiga bagian:
- Filter — kumpulan ekspresi reguler yang menemukan baris log tentang percobaan gagal dan mengambil IP dari baris tersebut. Filter disimpan di
/etc/fail2ban/filter.d/. - Aksi (action) — tindakan terhadap pelanggar: menambah aturan ke iptables, nftables, ufw, atau firewalld. Aksi disimpan di
/etc/fail2ban/action.d/. - Jail — gabungan filter, aksi, sumber log, dan ambang batas. Misalnya, jail
sshdmemantau log SSH.
Jika dalam jendela findtime dari satu IP terkumpul maxretry kecocokan, alamat itu diblokir selama bantime. Setelah masa itu habis, blokir dicabut otomatis.
Instalasi fail2ban
Di Debian dan Ubuntu:
sudo apt update
sudo apt install fail2ban
Di RHEL, Rocky, AlmaLinux, paketnya ada di repositori EPEL:
sudo dnf install epel-release
sudo dnf install fail2ban
Aktifkan autostart dan periksa status layanan:
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban
Di Debian dan Ubuntu, jail untuk SSH sudah aktif secara default melalui /etc/fail2ban/jail.d/defaults-debian.conf. Di keluarga RHEL, setelah instalasi tidak ada jail yang aktif — jail harus diaktifkan secara manual.
Tempat menyimpan pengaturan: jail.conf dan jail.local
Berkas utama adalah /etc/fail2ban/jail.conf, tetapi berkas ini tidak boleh diedit: saat paket diperbarui, isinya akan tertimpa. Pengaturan sendiri ditaruh di /etc/fail2ban/jail.local atau di berkas terpisah /etc/fail2ban/jail.d/*.local. Fail2ban membaca berkas dalam urutan berikut, dan setiap berkas berikutnya menimpa yang sebelumnya:
jail.confjail.d/*.confjail.localjail.d/*.local
Jangan menyalin seluruh jail.conf ke jail.local — dengan begitu nilai default lama ikut terbekukan. Di jail.local cukup tulis hanya yang Anda ubah.
Konfigurasi fail2ban untuk SSH: jail.local minimal
Buat berkasnya:
sudo nano /etc/fail2ban/jail.local
Lalu tambahkan isi berikut:
[DEFAULT]
# Alamat sendiri yang tidak boleh diblokir
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime = 1h
findtime = 10m
maxretry = 5
# Sumber log: journal systemd atau berkas
backend = systemd
[sshd]
enabled = true
port = ssh
maxretry = 3
Restart layanan dan pastikan jail sudah berjalan:
$ sudo systemctl restart fail2ban
$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
Arti parameter
| Parameter | Arti | Contoh |
|---|---|---|
enabled | apakah jail aktif | true |
port | port yang diblokir untuk pelanggar | ssh, 2222, ssh,2222 |
maxretry | berapa kesalahan yang diizinkan sebelum blokir | 3 |
findtime | jendela waktu untuk menghitung kesalahan | 10m |
bantime | lama blokir; -1 berarti permanen | 1h, 1d |
ignoreip | alamat dan subnet yang tidak pernah diblokir | 10.0.0.0/8 |
backend | sumber log | systemd, auto |
logpath | path ke berkas log untuk backend berbasis berkas | /var/log/auth.log |
banaction | firewall mana yang dipakai untuk memblokir | nftables-multiport, ufw |
Waktu bisa ditulis dengan akhiran: s, m, h, d, w. Angka tanpa akhiran dianggap dalam detik.
backend: systemd atau berkas
Di Debian 12 dan Ubuntu 24.04 yang modern, berkas /var/log/auth.log mungkin tidak ada jika rsyslog tidak terpasang: log SSH hanya tersimpan di journal systemd. Dalam kasus ini diperlukan backend = systemd, jika tidak fail2ban gagal dijalankan dengan error bahwa berkas log tidak ditemukan. Jika rsyslog terpasang, varian berbasis berkas juga bisa dipakai:
[sshd]
enabled = true
backend = auto
logpath = /var/log/auth.log
Di sistem RHEL, berkas yang sejenis adalah /var/log/secure.
SSH di port non-standar
Jika sshd mendengarkan di port 2222, misalnya, tentukan port itu di jail — jika tidak, fail2ban hanya memblokir port 22 dan serangan akan berlanjut di 2222:
[sshd]
enabled = true
port = 2222
Untuk memblokir semua port bagi pelanggar sekaligus, gunakan aksi iptables-allports atau nftables-allports melalui parameter banaction.
Memilih firewall: iptables, nftables, ufw, firewalld
Secara default di Debian dipakai banaction = nftables (pada versi lama, iptables), dan di RHEL dipakai firewalld. Jika di server sudah dikonfigurasi ufw, akan lebih praktis jika blokir juga terlihat di ufw:
[DEFAULT]
banaction = ufw
Untuk firewalld:
[DEFAULT]
banaction = firewallcmd-rich-rules
Untuk memastikan aturannya benar-benar muncul, jalankan sudo nft list ruleset | grep f2b atau sudo iptables -L -n | grep f2b: fail2ban membuat rantai dengan awalan f2b-.
Cara memeriksa kinerja: fail2ban-client status
Alat pengelolaan utama adalah fail2ban-client. Status satu jail:
$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 147
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 4
|- Total banned: 38
`- Banned IP list: 45.148.10.12 92.118.39.7 185.224.128.40 218.92.0.112
Dari sini terlihat berapa kesalahan yang sedang berada dalam jendela waktu, berapa IP yang diblokir, dan alamat mana saja itu. Untuk menguji perlindungan secara langsung, coba login dengan kata sandi salah beberapa kali dari mesin lain (bukan yang ada di ignoreip) — setelah percobaan ketiga, koneksi tidak lagi bisa dibuat.
Log fail2ban sendiri ada di /var/log/fail2ban.log:
$ sudo tail -n 3 /var/log/fail2ban.log
2026-10-14 09:12:41,118 fail2ban.filter [812]: INFO [sshd] Found 218.92.0.112
2026-10-14 09:12:44,302 fail2ban.filter [812]: INFO [sshd] Found 218.92.0.112
2026-10-14 09:12:47,551 fail2ban.actions [812]: NOTICE [sshd] Ban 218.92.0.112
Cara membuka blokir IP di fail2ban
Jika Anda sendiri atau rekan kerja terblokir, cabut blokirnya dari konsol server (lewat panel hosting atau dari IP lain):
sudo fail2ban-client set sshd unbanip 203.0.113.25
Mencabut semua blokir di semua jail:
sudo fail2ban-client unban --all
Memblokir alamat secara manual tanpa menunggu filter bekerja:
sudo fail2ban-client set sshd banip 198.51.100.7
Agar kejadian serupa tidak terulang, tambahkan alamat statis atau subnet kantor Anda ke ignoreip.
Blokir yang meningkat untuk pelanggar berulang
Banyak bot kembali segera setelah blokirnya dicabut. Sejak versi 0.11, fail2ban mendukung kenaikan lama blokir untuk pelanggar berulang:
[DEFAULT]
bantime = 1h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w
Setiap blokir berikutnya untuk IP yang sama akan lebih lama dari sebelumnya, tetapi tidak lebih dari empat minggu. Alternatif untuk versi lama adalah jail recidive, yang membaca log fail2ban sendiri dan memblokir lama alamat yang tertangkap beberapa kali:
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 5
Menguji filter: fail2ban-regex
Jika jail berjalan tetapi tidak ada yang diblokir, periksa apakah filter benar-benar menemukan baris di log. Untuk log berbasis berkas:
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Untuk journal systemd:
sudo fail2ban-regex systemd-journal sshd
Pada keluaran, perhatikan baris Lines: ... matched. Jika kecocokannya nol, filter tidak sesuai dengan format log atau sumber yang ditentukan salah. Sebelum me-restart, ada baiknya memeriksa sintaksis seluruh konfigurasi:
sudo fail2ban-client -t
Kesalahan umum
- Layanan tidak mau berjalan: "Have not found any log file for sshd jail". Berkas
/var/log/auth.logtidak ada. Pasangbackend = systemdatau pasang rsyslog. - Blokir terlihat di status, tetapi serangan terus berlanjut. Port yang ditentukan salah (SSH sudah dipindahkan) atau aturan firewall tertimpa oleh aturan izin yang lebih awal. Periksa
portdan keluarannft list ruleset. - Perubahan tidak berlaku. Yang diedit adalah
jail.conf, sementara dijail.localataujail.d/*.localada nilai lain. Lihat nilai akhirnya:sudo fail2ban-client get sshd maxretry. - Anda memblokir diri sendiri. Cabut blokir lewat konsol dan tambahkan IP Anda ke
ignoreip. - Fail2ban di Docker tidak melihat serangan. Port kontainer dipublikasikan melalui rantai DOCKER, yang melewati INPUT. Untuk layanan seperti ini gunakan
chain = DOCKER-USERpada aksi.
Langkah lain untuk melindungi SSH
Fail2ban bekerja paling baik bersama pengaturan dasar di /etc/ssh/sshd_config:
PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3
Setelah mengubah berkas, periksa konfigurasi dengan sudo sshd -t lalu restart layanan. Jangan tutup sesi yang sedang aktif sebelum Anda memastikan login baru dengan kunci berhasil. Selain itu, Anda bisa membatasi akses SSH di firewall hanya untuk alamat yang memang dibutuhkan.
Kesimpulan
Konfigurasi fail2ban terdiri dari beberapa langkah: pasang paket, buat jail.local dengan bagian [sshd], pilih backend dan port yang tepat, atur maxretry, findtime, dan bantime, tambahkan alamat sendiri ke ignoreip, lalu periksa hasilnya dengan fail2ban-client status sshd. Bersama login hanya dengan kunci, langkah ini cukup andal untuk melindungi SSH dari serangan tebak kata sandi. Pengamanan server dan fail2ban dibahas dalam praktik pada kursus Linux.
Pertanyaan umum
Perlukah fail2ban jika login dengan kata sandi sudah dinonaktifkan?
Tidak wajib, tetapi tetap berguna: ia menghapus ribuan percobaan tidak berguna dari log, mengurangi beban, dan menjadi pengaman jika login dengan kata sandi tanpa sengaja diaktifkan lagi.
Bagaimana cara melihat semua IP yang diblokir di semua jail?
Jalankan sudo fail2ban-client banned — perintah ini menampilkan daftar alamat yang diblokir untuk setiap jail. Untuk satu jail gunakan fail2ban-client status sshd.
Apakah blokir tetap ada setelah server di-reboot?
Ya. Fail2ban menyimpan blokir di basis data SQLite (/var/lib/fail2ban/fail2ban.sqlite3) dan memulihkan blokir yang masih berlaku saat start, kecuali sudah dihapus lebih dulu oleh parameter dbpurgeage.
Bisakah fail2ban melindungi layanan selain SSH?
Bisa. Paket ini sudah menyertakan filter untuk nginx, Apache, Postfix, Dovecot, dan layanan lain. Cukup aktifkan jail yang diinginkan di jail.local, misalnya [nginx-http-auth] dengan enabled = true.
Apa bedanya fail2ban dengan pembatasan di firewall?
Firewall mengizinkan atau melarang alamat secara statis, sedangkan fail2ban memblokir secara dinamis alamat yang berperilaku buruk berdasarkan log. Keduanya sering dikombinasikan: daftar putih di firewall dan fail2ban untuk sisanya.
Topik ini dibahas mendalam dengan praktik di kursus “Linux: с нуля до уверенного администрирования”.
Ke kursus