Fail2ban dan Intrusion Prevention

Fail2ban dan Intrusion Prevention

Bitnesia • Aug 27, 2026 84 •EN

Bab 31 menutup dengan satu titik buta yang sengaja dibiarkan terbuka: firewall serapi apa pun hanya bisa menolak apa yang sudah eksplisit kita larang, tetapi tidak bisa mengenali pola serangan berulang dengan sendirinya. Bagian 31.6.3 bahkan sudah membuktikan sendiri titik buta itu lewat satu baris perintah grep manual untuk menghitung source IP yang paling sering muncul di log blokir, cara yang jujur diakui reaktif dan tidak scalable untuk server yang menerima ribuan percobaan koneksi tiap hari. Bab ini menutup titik buta tersebut lewat Fail2ban, lapisan ketiga pada peta defense in depth yang sudah kita susun di Bagian 30.1.2: alat yang mengotomasi persis proses deteksi dan blokir tadi, membaca log secara terus-menerus, mengenali pola percobaan gagal yang berulang, lalu langsung memerintahkan firewall memblokir IP sumbernya tanpa perlu Sysadmin memelototi log setiap hari.

Kita akan mulai dari konsep intrusion prevention berbasis log dan tiga komponen inti yang membentuk cara kerja Fail2ban, dilanjutkan instalasi serta pola konfigurasi yang aman lewat jail.local, menyelaraskan banaction dengan nftables yang sudah menjadi fondasi firewall kita sejak Bab 31, mengaktifkan jail untuk SSH pada port kustom kita serta Nginx/Apache, dan ditutup dengan cara memeriksa status serta melepas ban IP yang salah sasaran.

32.1 Konsep Intrusion Prevention Berbasis Log

Sebelum masuk ke instalasi, ada baiknya kita pahami dahulu model kerja Fail2ban secara konsep, karena hampir seluruh troubleshooting di bagian-bagian berikutnya kembali ke tiga istilah inti yang dijelaskan di sini.

32.1.1 Dari Grep Manual ke Deteksi Otomatis: Apa Itu Fail2ban

Fail2ban adalah intrusion prevention system berbasis host yang bekerja dengan cara memantau file log atau journal secara terus-menerus, mencocokkan tiap baris baru terhadap pola tertentu, lalu memerintahkan firewall memblokir IP sumber begitu satu IP melewati ambang batas percobaan gagal dalam rentang waktu tertentu. Model kerjanya sederhana sekaligus efektif: Attacker yang menjalankan brute force SSH otomatis, seperti yang sudah kita bahas potensinya di Bagian 31.3.2, pada akhirnya tetap meninggalkan jejak berupa baris Failed password yang berulang di log autentikasi. Fail2ban membaca jejak itu, menghitung berapa kali kegagalan terjadi dari satu IP dalam jangka waktu tertentu, dan begitu ambangnya terlampaui, IP tersebut langsung diblokir untuk durasi tertentu tanpa campur tangan manual.

Perbedaannya dengan rate limiting UFW yang sudah kita pasang di Bagian 31.3.2 terletak pada sumber datanya. Rate limiting UFW bekerja murni dari pola koneksi di level jaringan, tanpa peduli isi log aplikasi, sehingga tidak bisa membedakan percobaan login yang gagal dari percobaan yang berhasil. Fail2ban membaca isi log aplikasi itu sendiri, sehingga jauh lebih presisi mengenali percobaan yang benar-benar gagal autentikasi, sekaligus bisa diperluas ke service apa pun yang punya log terstruktur, tidak terbatas pada SSH.

32.1.2 Anatomi Fail2ban: Filter, Jail, dan Action

Konfigurasi Fail2ban selalu terdiri dari tiga komponen yang saling terhubung. Filter adalah kumpulan pola regex yang menentukan baris log seperti apa yang dihitung sebagai percobaan gagal, disimpan sebagai file terpisah per service di /etc/fail2ban/filter.d/, misalnya sshd.conf untuk mengenali baris Failed password pada log SSH. Jail adalah unit konfigurasi yang mengikat satu filter dengan sumber log, port yang relevan, dan parameter ambang batas seperti jumlah percobaan maksimum, didefinisikan di jail.conf beserta turunannya. Action adalah perintah konkret yang dijalankan saat sebuah IP resmi diban, biasanya berupa perintah nftables atau iptables untuk menolak trafik dari IP tersebut, didefinisikan di /etc/fail2ban/action.d/. Ketiganya saling melengkapi; satu jail tidak berfungsi tanpa filter yang jelas dan action yang tahu cara memblokir.

KomponenFungsiLokasi Konfigurasi
FilterMengenali baris log yang termasuk percobaan gagal lewat pola regex/etc/fail2ban/filter.d/*.conf
JailMengikat filter, sumber log, port, dan ambang batas (maxretry, findtime, bantime) untuk satu servicejail.conf, jail.local, jail.d/*.conf
ActionMenjalankan perintah blokir nyata ke firewall saat sebuah IP diban/etc/fail2ban/action.d/*.conf

Praktisnya, sebagai Sysadmin kita jarang menulis filter atau action dari nol. Fail2ban sudah menyediakan puluhan filter siap pakai untuk service umum, termasuk SSH, Nginx, dan Apache yang menjadi fokus Bagian 32.4. Pekerjaan kita lebih banyak berupa mengaktifkan jail yang relevan dan menyesuaikan parameternya, persis yang akan kita lakukan mulai bagian berikutnya.

32.2 Instalasi dan Konfigurasi Dasar Fail2ban

Bagian ini memasang Fail2ban dan membangun fondasi konfigurasi yang aman dari perubahan yang hilang setiap kali package di-upgrade, sebelum masuk ke penyesuaian yang lebih spesifik di bagian-bagian berikutnya.

32.2.1 Instalasi Package dan Verifikasi Servis

Package fail2ban di Ubuntu Server 26.04 berada di repository universe, yang sudah aktif secara default sejak instalasi seperti dibahas di Bagian 6.2, sehingga tidak perlu langkah tambahan mengaktifkan repository apa pun.

Langkah Praktik

  1. Pasang package fail2ban.
    sudo apt install fail2ban
  2. Package ini menyertakan systemd unit yang otomatis diaktifkan dan dijalankan begitu instalasi selesai. Konfirmasikan statusnya.
    sudo systemctl status fail2ban
  3. Lihat jail yang sudah aktif tanpa konfigurasi tambahan apa pun.
    sudo fail2ban-client status

Verifikasi dan Troubleshooting

  • Output systemctl status yang sehat menampilkan active (running), dan fail2ban-client status pada instalasi baru biasanya sudah menampilkan satu jail bernama sshd tanpa kita mengatur apa pun. Hal ini terjadi karena package Ubuntu menyertakan file /etc/fail2ban/jail.d/defaults-debian.conf yang secara default sudah mengaktifkan jail sshd, sehingga proteksi dasar terhadap brute force SSH sudah berjalan sejak awal instalasi.
  • Jail sshd bawaan ini masih memakai konfigurasi port default yang belum tentu cocok dengan port SSH kustom kita dari Bagian 3.2.4, isu yang kita tuntaskan di Bagian 32.4.1. Jangan berhenti hanya sampai jail aktif; pastikan juga port-nya benar.
  • Fail2ban menyimpan log aktivitasnya sendiri, terpisah dari log service yang dipantaunya, yang berguna untuk troubleshooting Fail2ban itu sendiri.
    sudo tail -f /var/log/fail2ban.log

32.2.2 jail.local: Lapisan Kustomisasi yang Aman

Pola yang sama persis dengan sshd_config di Bab 3 dan applications.d UFW di Bagian 31.3.3 kembali berlaku di sini. File jail.conf adalah file bawaan package yang tidak boleh disunting langsung, karena akan tertimpa setiap kali package fail2ban di-upgrade. Fail2ban membaca konfigurasi dalam urutan tetap, yaitu jail.conf, lalu seluruh file di jail.d/*.conf secara alfabetis, lalu jail.local, dan terakhir jail.d/*.local, dengan nilai yang dibaca belakangan menimpa nilai yang sama dari file sebelumnya. Karena jail.local dibaca setelah seluruh jail.d/*.conf, termasuk defaults-debian.conf yang mengaktifkan jail sshd tadi, file inilah tempat paling aman menampung seluruh kustomisasi kita.

Langkah Praktik

  1. Buat file jail.local, yang sebelumnya kosong karena tidak disediakan package.
    sudo nano /etc/fail2ban/jail.local
  2. Isi dengan blok [DEFAULT] berikut. Subnet kantor 192.168.1.0/24 sengaja ditambahkan ke ignoreip di samping localhost bawaan, agar Sysadmin dan Developer yang sesekali salah ketik password dari jaringan internal tidak pernah ikut terban.
    [DEFAULT]
    ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
    bantime  = 1h
    findtime = 10m
    maxretry = 5
  3. Muat ulang konfigurasi tanpa memutus koneksi yang sedang aktif.
    sudo fail2ban-client reload

Verifikasi dan Troubleshooting

  • Konfirmasikan parameter baru sudah terbaca pada jail sshd.
    sudo fail2ban-client get sshd bantime
    sudo fail2ban-client get sshd maxretry
  • Nilai bantime bawaan Fail2ban hanya 10 menit, cukup singkat sehingga Attacker otomatis bisa saja langsung mencoba lagi begitu masa ban habis. Menaikkannya ke 1 jam seperti di atas sudah jadi praktik umum di lapangan. Untuk pertahanan yang lebih agresif lagi, Fail2ban juga menyediakan bantime.increment = true yang melipatgandakan durasi ban setiap kali IP yang sama terban berulang kali, yaitu opsi yang layak dipertimbangkan untuk server yang sering jadi target scanning otomatis.

32.3 banaction: Menyelaraskan Fail2ban dengan nftables

Bagian ini menuntaskan satu detail teknis yang mudah terlewat, tetapi berdampak nyata pada konsistensi firewall server kita, mengingat seluruh pembahasan Bab 31 sudah menegaskan posisi nftables sebagai fondasi modern di balik UFW.

32.3.1 Default iptables-multiport dan Alasannya Perlu Disesuaikan

Parameter banaction menentukan mekanisme firewall apa yang dipanggil Fail2ban saat memblokir sebuah IP. Meskipun Ubuntu Server 26.04 sepenuhnya berjalan di atas nftables seperti dibahas di Bagian 31.1.2, nilai banaction bawaan pada jail.conf Fail2ban sampai penulisan series ini masih iptables-multiport, bukan nftables. Pilihan ini bukan berarti salah atau rusak, karena binary iptables di server kita sebenarnya adalah iptables-nft seperti sudah dibuktikan di Bagian 31.1.2, sehingga rule yang ditulis Fail2ban lewat iptables-multiport tetap berakhir sebagai entri nftables di kernel lewat jalur terjemahan otomatis.

Meskipun demikian, memakai banaction native nftables tetap lebih konsisten untuk server yang sudah kita bangun sepenuhnya di atas mental model nftables sejak Bab 31. Rule ban yang ditulis lewat action nftables muncul langsung saat kita menjalankan nft list ruleset, yaitu perintah verifikasi yang sama persis dengan yang sudah kita pakai di Bagian 31.4, tanpa perlu berpindah ke iptables -L. Action ini juga membuat table tersendiri bernama f2b-table dengan chain yang di-hook pada titik input memakai prioritas -1, yaitu angka yang sengaja lebih kecil dari prioritas 0 yang lazim dipakai chain UFW maupun ruleset native pada Bagian 31.4.1. Artinya, rule ban dari Fail2ban dievaluasi kernel lebih dahulu dibanding rule UFW, sehingga IP yang sudah diban tetap tertolak walau kebetulan port-nya termasuk yang diizinkan UFW.

32.3.2 Mengalihkan banaction ke nftables Native

Langkah Praktik

  1. Tambahkan baris banaction ke blok [DEFAULT] pada jail.local yang sudah kita buat di Bagian 32.2.2.
    sudo nano /etc/fail2ban/jail.local
    Tambahkan dua baris berikut di dalam blok [DEFAULT] yang sudah ada.
    banaction = nftables
    banaction_allports = nftables[type=allports]
  2. Muat ulang Fail2ban agar action baru diterapkan ke seluruh jail aktif.
    sudo fail2ban-client reload

Verifikasi dan Troubleshooting

  • Pastikan table f2b-table sudah terbentuk di kernel meskipun belum ada IP yang diban.
    sudo nft list table inet f2b-table
  • Jika perintah di atas menampilkan error No such file or directory, table ini baru dibuat saat jail benar-benar start dan action-nya dieksekusi pertama kali, jadi pastikan dahulu fail2ban-client status menunjukkan jail dalam keadaan berjalan, lalu ulangi setelah menjalankan langkah pengujian ban di Bagian 32.5.3.
  • Package fail2ban sudah mensyaratkan salah satu dari nftables atau iptables terpasang sebagai dependency, dan karena keduanya sudah tersedia sejak Bab 31, tidak ada package tambahan yang perlu dipasang untuk mengaktifkan banaction ini.

32.4 Mengaktifkan Jail untuk SSH, Nginx, dan Apache

Fondasi konfigurasi sudah siap. Bagian ini masuk ke jail spesifik yang paling relevan untuk server kita: SSH yang selalu aktif sejak Bab 3, dan web server yang sudah kita pasang di Bab 12 atau Bab 13.

32.4.1 Jail SSH pada Port Kustom

Jail sshd bawaan pada jail.conf memakai port = ssh, yaitu alias yang oleh Fail2ban diterjemahkan lewat /etc/services menjadi port 22 baku. Ini persis kesalahan jebakan yang sama dengan alias ufw limit ssh yang sudah diperingatkan di Bagian 31.3.2: server kita menjalankan SSH di port 2222 sejak Bagian 3.2.4, bukan port 22. Jika port ini tidak disesuaikan, rule ban yang dibuat Fail2ban hanya berlaku untuk port 22 yang sebenarnya sudah tidak listening di server kita, sehingga Attacker yang menyerang port 2222 justru tidak pernah benar-benar terblokir meskipun jail sshd tampak aktif dan sehat.

Langkah Praktik

  1. Tambahkan blok [sshd] ke jail.local, terpisah dari blok [DEFAULT] yang sudah ada.
    sudo nano /etc/fail2ban/jail.local
    Tambahkan blok berikut di bagian bawah file, sejajar dengan [DEFAULT], bukan di dalamnya.
    [sshd]
    enabled = true
    port    = 2222
  2. Muat ulang Fail2ban.
    sudo fail2ban-client reload

Verifikasi dan Troubleshooting

  • Pastikan port yang tercatat pada jail benar-benar 2222, bukan 22.
    sudo fail2ban-client get sshd port
  • Jail sshd di Ubuntu Server 26.04 memakai backend = systemd secara default, artinya Fail2ban membaca log SSH langsung dari journal lewat binding python3-systemd, bukan dari file /var/log/auth.log. Binding ini sudah otomatis terpasang sebagai dependency package fail2ban, sehingga tidak perlu instalasi tambahan apa pun.

32.4.2 Jail Nginx dan Apache untuk HTTP Basic Auth

Fail2ban menyediakan jail siap pakai untuk kedua web server yang sudah kita bahas, yaitu nginx-http-auth untuk Nginx dari Bab 12 dan apache-auth untuk Apache dari Bab 13. Pilih salah satu sesuai web server yang benar-benar berjalan di server kita.

Langkah Praktik

  1. Tambahkan blok jail sesuai web server yang dipakai ke jail.local. Untuk Nginx:
    [nginx-http-auth]
    enabled = true
    Atau untuk Apache:
    [apache-auth]
    enabled = true
  2. Muat ulang Fail2ban.
    sudo fail2ban-client reload

Verifikasi dan Troubleshooting

  • Pastikan jail baru sudah terdaftar dan berjalan.
    sudo fail2ban-client status
  • Catatan jujur yang penting soal batasan jail ini: nginx-http-auth dan apache-auth hanya mengenali kegagalan HTTP Basic Auth, fitur autentikasi bawaan web server yang dipakai lewat directive seperti auth_basic di Nginx atau modul mod_auth_basic di Apache. Situs statis atau reverse proxy sederhana dari Bab 12, 13, dan 16 yang belum memakai proteksi Basic Auth tidak akan pernah memicu jail ini, karena memang tidak ada baris log kegagalan autentikasi yang bisa dicocokkan. Untuk melindungi form login aplikasi web kustom, misalnya halaman login WordPress atau aplikasi Node.js dari Bab 15, diperlukan filter kustom yang membaca log aplikasi tersebut secara spesifik, yaitu topik yang berada di luar cakupan series ini.

32.5 Melihat Status dan Unban IP

Konfigurasi tanpa cara memeriksa dan mengoreksinya sama berisikonya dengan firewall tanpa logging yang sudah kita bahas di Bagian 31.6. Bagian penutup ini melengkapi operasional harian Fail2ban: memeriksa siapa saja yang sedang diban, dan melepas ban yang salah sasaran.

32.5.1 Memeriksa Status Jail dan Daftar IP yang Diblokir

Langkah Praktik

  1. Lihat ringkasan seluruh jail yang aktif.
    sudo fail2ban-client status
  2. Lihat detail satu jail tertentu, termasuk daftar IP yang sedang diban.
    sudo fail2ban-client status sshd

Verifikasi dan Troubleshooting

  • Output status sshd yang sehat menampilkan jumlah percobaan gagal saat ini dan total sepanjang waktu pada bagian Filter, diikuti jumlah IP yang sedang diban dan daftar IP-nya pada bagian Actions, kira-kira berbentuk seperti berikut.
    Status for the jail: sshd
    |- Filter
    |  |- Currently failed: 1
    |  |- Total failed:     14
    |  `- File list:
    `- Actions
       |- Currently banned: 1
       |- Total banned:     1
       `- Banned IP list:   203.0.113.45
  • Baris File list yang kosong pada jail sshd adalah perilaku normal di Ubuntu Server 26.04, bukan tanda kegagalan. Karena jail ini memakai backend = systemd seperti dibahas di Bagian 32.4.1, Fail2ban membaca dari journal, bukan dari file log, sehingga tidak ada path file yang ditampilkan di sana.

32.5.2 Unban IP Secara Manual

IP yang salah sasaran, misalnya IP kantor yang belum sempat ditambahkan ke ignoreip pada Bagian 32.2.2, perlu bisa dilepas kembali tanpa menunggu bantime habis.

Langkah Praktik

  1. Lepas ban satu IP dari jail tertentu, ganti alamat IP berikut sesuai IP yang benar-benar tampil di status sshd.
    sudo fail2ban-client set sshd unbanip 203.0.113.45
  2. Jika IP yang sama ternyata diban di beberapa jail sekaligus, misalnya sshd dan nginx-http-auth bersamaan, lepas dari seluruh jail tanpa perlu menyebut nama jail satu per satu.
    sudo fail2ban-client unban 203.0.113.45

Verifikasi dan Troubleshooting

  • Konfirmasikan IP sudah tidak lagi tercantum di Banned IP list.
    sudo fail2ban-client status sshd
  • Perintah unban hanya melepas ban di level firewall untuk sesi berjalan saat ini. IP yang sama tetap bisa diban ulang secara otomatis begitu kembali melewati maxretry, jadi pastikan akar masalahnya sudah ditangani, misalnya menambahkan IP tersebut ke ignoreip jika memang berasal dari sumber tepercaya, bukan sekadar unban berulang setiap kali insiden sama terjadi.

32.5.3 Menguji Deteksi Tanpa Risiko Mengunci Diri Sendiri

Menguji Fail2ban dengan sengaja memasukkan password salah berkali-kali dari sesi SSH yang sedang kita pakai berisiko nyata: begitu maxretry tercapai, sesi kita sendiri ikut terblokir dari firewall. Fail2ban menyediakan tool fail2ban-regex khusus untuk menguji filter terhadap log yang sudah ada tanpa benar-benar menjalankan action ban apa pun, yaitu cara yang jauh lebih aman untuk memverifikasi filter bekerja sesuai harapan.

Langkah Praktik

  1. Uji filter sshd terhadap isi journal yang sudah ada, tanpa risiko memicu ban nyata.
    sudo fail2ban-regex systemd-journal sshd

Verifikasi dan Troubleshooting

  • Output menampilkan ringkasan jumlah baris log yang cocok dengan failregex pada filter sshd, yang berguna untuk memastikan filter benar-benar mengenali format log SSH di server kita sebelum mengandalkannya di produksi. Jika angka yang cocok selalu nol padahal sudah ada percobaan login gagal yang tercatat di journal, filter kemungkinan tidak cocok dengan format log yang dihasilkan versi openssh-server yang terpasang, dan layak dilaporkan sebagai bug ke proyek Fail2ban di GitHub.
  • Untuk pengujian menyeluruh yang benar-benar melibatkan ban nyata, lakukan dari jaringan lain di luar subnet 192.168.1.0/24 yang sudah masuk ignoreip, atau siapkan jalur akses cadangan seperti console akses dari Bagian 3.4 sebelum mencoba, agar tidak ikut terkunci keluar dari server sendiri.

Sampai di sini kita sudah menuntaskan lapisan ketiga defense in depth dari Bagian 30.1.2: memahami cara kerja Fail2ban lewat tiga komponen filter, jail, dan action, memasangnya dengan pola konfigurasi jail.local yang aman dari upgrade package, menyelaraskan banaction ke nftables native agar konsisten dengan fondasi firewall Bab 31, mengaktifkan jail untuk SSH pada port kustom kita serta Nginx atau Apache, hingga operasional harian memeriksa status dan melepas ban yang salah sasaran. Fail2ban tetap punya batasan yang jujur perlu diakui: ia hanya bereaksi terhadap pola yang sudah dikenali filter-nya, tidak bisa menghentikan Attacker yang bergerak lambat di bawah ambang maxretry, dan begitu Attacker benar-benar berhasil masuk lewat celah lain, Fail2ban tidak lagi berdaya membatasi apa yang bisa dilakukan proses tersebut begitu berjalan di dalam sistem. Bab 33 berikutnya masuk ke lapisan keempat pada peta defense in depth kita, AppArmor, yang bekerja dengan asumsi berbeda: bukan mencegah Attacker masuk, melainkan membatasi kerusakan yang bisa dibuat sebuah proses sekalipun berjalan sebagai root, sekaligus mengunci celah yang belum tentu bisa dideteksi lewat pola log sederhana.