Jika Anda perlu memilih arsitektur mitigasi botnet untuk aplikasi web atau backend, pertanyaan utamanya bukan sekadar “mana yang paling aman”, tetapi di mana keputusan pemblokiran paling tepat dilakukan. Secara praktis, ada tiga pola yang paling umum: memblokir di edge/reverse proxy, menaruh logika deteksi di aplikasi, atau memisahkan mitigasi ke service/security pipeline tersendiri.
Jawaban singkatnya: edge cocok untuk pemblokiran cepat dan murah pada pola yang jelas, aplikasi cocok saat keputusan butuh konteks bisnis atau sesi, dan service terpisah cocok saat trafik besar, aturan makin kompleks, atau Anda ingin mengurangi blast radius serta meningkatkan observability. Inspirasi pendekatan ini bisa dilihat dari praktik sysadmin FSF yang memakai Reaction untuk menindak pola berbahaya dari event log, tetapi keputusan arsitekturnya tetap harus disesuaikan dengan bentuk trafik, toleransi false positive, dan kemampuan operasional tim.
Apa yang sebenarnya sedang dihadapi saat bicara botnet
Dalam konteks aplikasi web/backend, “botnet” di sini biasanya berarti jaringan klien otomatis yang menghasilkan trafik merugikan: brute force login, credential stuffing, scraping agresif, spam form, inventory hoarding, request flood ringan yang lolos dari rate limit sederhana, atau probing endpoint internal/API.
Masalahnya bukan hanya volume request. Banyak bot modern terlihat “rapi”: mereka menyebar IP, memalsukan header, mengikuti redirect, dan menjaga rate per-IP tetap rendah agar tidak langsung terlihat sebagai serangan. Karena itu, arsitektur mitigasi yang efektif hampir selalu menggabungkan sinyal jaringan, perilaku aplikasi, dan umpan balik operasional.
Sinyal yang umum dipakai
- IP dan subnet: berguna, tetapi sering tidak cukup jika penyerang memakai pool IP besar atau proxy residential.
- Rate dan burst: efektif untuk pola kasar, kurang akurat untuk serangan low-and-slow.
- User-Agent, header, TLS/client fingerprint: membantu klasifikasi, tetapi mudah dipalsukan jika berdiri sendiri.
- Perilaku sesi: urutan endpoint, kecepatan submit form, kegagalan login berulang, token flow yang tidak wajar.
- Konteks bisnis: misalnya satu akun mencoba ribuan kode kupon, satu device membuat banyak akun, atau checkout terjadi tanpa langkah UI normal.
Dari sini terlihat mengapa lokasi implementasi mitigasi sangat berpengaruh: tidak semua lokasi punya akses ke sinyal yang sama.
Tiga opsi arsitektur mitigasi botnet
1) Rule di edge atau reverse proxy
Pendekatan ini menaruh keputusan sedekat mungkin ke pintu masuk trafik: CDN, WAF, load balancer layer 7, reverse proxy seperti Nginx/HAProxy/Envoy, atau firewall yang bisa bereaksi terhadap event. Ini biasanya menjadi lapisan pertama karena paling murah secara komputasi dan paling cepat menghentikan request sebelum menyentuh aplikasi.
Pola yang cocok untuk edge:
- Rate limit per IP atau per path.
- Blocklist IP/subnet dari feed atau hasil deteksi internal.
- Challenge/deny berdasarkan path sensitif, geografi, ASN, atau reputasi dasar.
- Pemblokiran sementara setelah pola request kasar terdeteksi dari log.
Pendekatan seperti Reaction relevan di sini: log dari service dianalisis, lalu rule pemblokiran dikirim ke komponen enforcement. Kelebihannya, deteksi dan enforcement bisa tetap sederhana namun efektif untuk pola yang jelas.
Kelebihan edge
- Latensi rendah: request berbahaya dihentikan sebelum masuk aplikasi atau database.
- Biaya lebih rendah: beban CPU, koneksi, dan query aplikasi berkurang.
- Blast radius kecil ke layer bawah: jika block bekerja, app dan DB tidak ikut terpapar.
- Cocok untuk mitigasi volumetrik ringan-menengah.
Kekurangan edge
- Akurasi terbatas bila keputusan butuh konteks akun, sesi, atau domain bisnis.
- False positive bisa mahal karena pemblokiran terjadi sebelum user mendapat fallback yang lebih halus.
- Observability sering terpisah dari telemetry aplikasi, sehingga korelasi kejadian tidak selalu mudah.
- Rule mudah membengkak jika terlalu banyak pengecualian khusus aplikasi ditaruh di proxy.
Contoh rule sederhana di reverse proxy
# Contoh konseptual Nginx: batasi burst ke endpoint login per IP
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
server {
location /login {
limit_req zone=login_limit burst=10 nodelay;
proxy_pass http://app_backend;
}
}Contoh di atas berguna untuk brute force kasar, tetapi tidak cukup untuk serangan yang menyebar ke banyak IP atau yang beroperasi per akun. Ini contoh penting bahwa edge bagus untuk proteksi cepat, bukan untuk semua keputusan.
2) Logika mitigasi di dalam aplikasi
Di pendekatan ini, aplikasi sendiri yang memutuskan apakah request diterima, ditantang, diperlambat, atau ditolak. Logika bisa ditempatkan di middleware, filter, interceptor, atau policy layer. Ini sangat berguna ketika bot hanya bisa dibedakan melalui konteks domain yang hanya diketahui aplikasi.
Contoh kasus yang lebih cocok di aplikasi:
- Login gagal dari banyak IP tapi menargetkan akun yang sama.
- Satu sesi mengakses urutan endpoint yang tidak realistis bagi pengguna manusia.
- Proses signup tanpa menjalankan langkah verifikasi yang semestinya.
- API partner internal yang boleh burst lebih tinggi daripada publik.
Kelebihan aplikasi
- Akurasi lebih tinggi karena punya akses ke session, user ID, tenant, device ID, cart, dan aturan bisnis.
- False positive lebih mudah dikelola dengan fallback yang lebih halus, misalnya challenge tambahan atau throttling per akun.
- Observability lebih kaya karena logika dan keputusan bisa ditrace bersama event bisnis.
- Pengujian lebih mudah lewat unit/integration test jika rule ditulis rapi.
Kekurangan aplikasi
- Latensi dan biaya lebih tinggi karena request sudah mencapai aplikasi.
- Blast radius lebih besar: jika serangan naik, app pool, cache, dan DB bisa terdampak sebelum mitigasi bekerja.
- Risiko coupling: kode bisnis dan kode security bisa bercampur jika desainnya buruk.
- Rollback perlu disiplin deployment jika rule tertanam langsung dalam release aplikasi.
Contoh middleware pseudo-code
function botMitigationMiddleware(request, context) {
const actor = {
ip: request.ip,
accountId: context.auth?.accountId,
sessionId: context.session?.id,
path: request.path
}
const signals = collectSignals(request, context)
const score = scoreRequest(signals)
if (score >= 90) {
auditLog('blocked', actor, signals)
return deny(429, 'Too many suspicious requests')
}
if (score >= 70) {
auditLog('challenged', actor, signals)
return requireAdditionalVerification()
}
return next()
}Poin penting dari contoh ini bukan angka skornya, melainkan pola arsitekturnya: kumpulkan sinyal, evaluasi rule/score, audit keputusan, lalu terapkan aksi yang proporsional. Jika Anda menaruh semua ini langsung bercampur dengan controller bisnis, maintainability akan cepat turun.
3) Service atau security pipeline terpisah
Opsi ketiga memisahkan deteksi dan/atau keputusan ke komponen tersendiri. Bentuknya bisa bermacam-macam: service scoring internal, stream processor yang membaca log/event, pipeline SIEM ringan, worker yang mengelola blocklist sementara, atau policy engine yang diakses aplikasi dan edge.
Ini bukan berarti semua request harus melewati network hop tambahan secara sinkron. Praktik yang lebih sehat sering berupa kombinasi:
- Deteksi asinkron dari log, metrics, atau event stream.
- Distribusi keputusan ke edge dan aplikasi melalui cache, shared store, atau control plane.
- Enforcement lokal tetap dilakukan di edge atau app agar jalur request tidak bergantung penuh pada satu service eksternal.
Pola ini dekat dengan ide yang dipakai oleh tim sysadmin yang membangun reaksi dari event operasional: sistem melihat pola dari log, lalu menghasilkan tindakan pemblokiran terkontrol. Bedanya, dalam aplikasi modern biasanya kita perlu menambahkan governance, telemetry, dan mekanisme rollback yang lebih formal.
Kelebihan service terpisah
- Maintainability lebih baik saat aturan makin banyak dan sumber sinyal bertambah.
- Blast radius lebih terkontrol jika deteksi dipisah dari jalur bisnis utama.
- Observability lebih matang: keputusan bisa dipusatkan, dibandingkan, dan diaudit.
- Lebih mudah dipakai lintas banyak aplikasi atau banyak reverse proxy.
Kekurangan service terpisah
- Biaya operasional naik: ada komponen, deployment, monitoring, dan failure mode tambahan.
- Latensi bisa naik bila scoring dilakukan sinkron melalui RPC.
- Kompleksitas rollback dan konsistensi bertambah jika rule didistribusikan ke banyak enforcement point.
- Risiko keputusan stale bila blocklist atau score cache terlambat sinkron.
Perbandingan teknis: latensi, akurasi, blast radius, dan lainnya
Latensi
- Edge: terbaik untuk keputusan sederhana karena request dihentikan sebelum masuk app.
- App: lebih lambat karena parsing, auth, session, dan kadang akses cache/DB sudah terjadi.
- Service terpisah: paling bervariasi; bisa baik jika asinkron dan enforcement lokal, bisa buruk jika setiap request harus memanggil service scoring sinkron.
Prinsip praktis: jangan menambahkan network hop sinkron pada setiap request kecuali benar-benar dibutuhkan. Jika memungkinkan, lakukan scoring berat di luar jalur request dan sebarkan hasilnya ke cache lokal atau reverse proxy.
Akurasi deteksi
- Edge: bagus untuk pola jaringan dan burst sederhana, kurang untuk konteks akun/sesi.
- App: terbaik untuk rule yang memerlukan state dan domain knowledge.
- Service terpisah: bisa paling akurat jika menggabungkan banyak sumber sinyal, tetapi kualitasnya sangat bergantung pada desain pipeline data.
Kesalahan umum adalah berharap WAF atau proxy saja bisa mengenali semua bot “pintar”. Untuk credential stuffing yang menyebar IP tetapi menargetkan akun sama, biasanya aplikasi atau service deteksi yang punya peluang lebih baik.
Blast radius
- Edge: paling kecil terhadap app/DB, tetapi salah konfigurasi bisa memblokir seluruh trafik publik.
- App: blast radius lebih besar pada resource internal karena request telanjur masuk.
- Service terpisah: jika jalur enforcement tetap lokal, blast radius bisa baik; jika service deteksi menjadi dependency sinkron, outage service bisa ikut mengganggu trafik normal.
Best practice: untuk service terpisah, rancang mode gagal yang jelas, misalnya fail-open untuk endpoint non-kritis atau fail-closed untuk endpoint autentikasi berisiko tinggi. Jangan biarkan perilaku default tidak terdefinisi.
Biaya operasional
- Edge: murah di awal, terutama untuk rule sederhana.
- App: biaya sedang; Anda menambah kompleksitas kode dan testing, tetapi belum perlu platform baru.
- Service terpisah: paling mahal secara operasional karena butuh lifecycle sendiri, storage state, dashboard, alerting, dan ownership yang jelas.
Observability
- Edge: sering punya log terpisah; bagus untuk hitungan traffic, kurang kaya untuk konteks bisnis.
- App: bagus untuk tracing dan korelasi dengan user flow.
- Service terpisah: paling kuat jika Anda butuh audit trail keputusan lintas aplikasi.
Untuk mitigasi botnet, observability bukan sekadar “punya log”. Anda perlu bisa menjawab pertanyaan berikut dengan cepat:
- Rule mana yang memblokir request ini?
- Sinyal apa yang memicu keputusan?
- Berapa banyak request sah ikut terkena?
- Apakah insiden ini terlokalisasi pada satu endpoint, satu tenant, atau seluruh sistem?
Rollback
- Edge: rollback biasanya cepat jika rule dikelola terpusat, tetapi human error bisa berdampak besar.
- App: rollback mengikuti deployment atau feature flag; lebih aman bila rule dibungkus konfigurasi, bukan hard-coded.
- Service terpisah: rollback fleksibel jika ada control plane dan versioned policy, tetapi distribusi state bisa membuat hasil rollback tidak instan.
Gunakan mode shadow atau dry run saat meluncurkan rule baru: log keputusan “akan diblokir” tanpa benar-benar memblokir selama beberapa waktu. Ini sangat membantu menekan false positive.
False positive
- Edge: paling berisiko bila rule terlalu kasar, misalnya hanya berdasarkan IP, negara, atau User-Agent.
- App: lebih mudah memberi pengecualian spesifik dan challenge bertahap.
- Service terpisah: tergantung kualitas sinyal dan feedback loop; bisa baik, bisa buruk jika model/aturan tidak tervalidasi.
False positive yang paling sering terjadi:
- NAT perusahaan atau kampus menyebabkan banyak user sah berbagi satu IP.
- Mobile carrier memakai egress IP yang berubah atau dipakai banyak pelanggan.
- API client resmi terlihat “tidak manusiawi” karena memang otomatis, tetapi sah.
- Job internal, health check, dan crawler mesin pencari ikut terkena rule umum.
Maintainability
- Edge: baik untuk sedikit rule stabil; buruk jika penuh pengecualian domain bisnis.
- App: baik jika dibuat modular; buruk jika bercampur dengan controller/service bisnis.
- Service terpisah: terbaik pada skala besar, tetapi berlebihan untuk tim kecil jika rule masih sederhana.
Kapan modular monolith sudah cukup
Banyak tim terlalu cepat memecah mitigasi ke service terpisah. Padahal, untuk banyak aplikasi, modular monolith di dalam aplikasi utama sudah cukup kuat, asal desainnya benar.
Tanda modular monolith masih cukup
- Anda hanya punya satu atau dua aplikasi utama.
- Aturan deteksi sangat bergantung pada konteks bisnis aplikasi itu sendiri.
- Volume trafik belum memaksa pemisahan compute secara independen.
- Tim operasional kecil dan belum siap mengelola komponen kontrol tambahan.
- Anda masih sering mengubah rule dan ingin iterasi cepat dekat dengan kode domain.
Dalam model ini, pisahkan komponen secara internal:
- Signal collectors: mengambil data dari request, sesi, akun, dan event.
- Policy engine: evaluasi rule atau score.
- Enforcement adapters: deny, challenge, throttle, atau audit.
- State store: cache/counter sementara, idealnya bukan langsung ke database transaksi untuk semua hal.
Dengan struktur ini, Anda tetap memperoleh manfaat maintainability tanpa harus memperkenalkan microservice baru terlalu dini.
Kapan perlu komponen terpisah
Service atau pipeline terpisah mulai masuk akal ketika beban organisasi dan teknis tidak lagi cocok ditampung di satu aplikasi.
Indikasi kuat perlu dipisah
- Banyak aplikasi atau banyak ingress membutuhkan rule yang konsisten.
- Sumber sinyal makin beragam: log edge, event auth, API gateway, queue, fraud signal, feed reputasi.
- Aturan berubah independen dari release aplikasi.
- Tim security/platform berbeda dari tim aplikasi dan butuh ownership terpisah.
- Volume event terlalu besar jika semua evaluasi dilakukan inline di aplikasi.
- Kebutuhan audit mengharuskan semua keputusan dapat dilacak dan direplay.
Pola implementasi yang lebih aman daripada “semua sinkron”
- Kumpulkan event dari edge dan aplikasi ke log/event stream.
- Deteksi asinkron menghasilkan indikator seperti blocklist sementara, risk score actor, atau policy recommendation.
- Cache hasil di store cepat yang bisa dibaca edge/app.
- Enforce lokal di reverse proxy atau middleware tanpa RPC wajib per request.
Pola ini menjaga latensi tetap rendah sambil memberi ruang bagi deteksi yang lebih kaya.
Panduan implementasi: mulai dari yang sederhana, tapi jangan buntu
Lapisan minimal yang masuk akal
- Edge: rate limit dasar untuk endpoint sensitif seperti login, reset password, search mahal, dan form publik.
- App: rule berbasis akun/sesi/tenant untuk pola yang tidak terlihat di edge.
- Audit log terstruktur: setiap keputusan block/challenge harus menyimpan alasan yang bisa dibaca manusia dan mesin.
Format log terstruktur yang berguna, misalnya:
{
"decision": "block",
"reason": "too_many_failed_logins_same_account",
"account_id": "acc_123",
"ip": "203.0.113.10",
"path": "/login",
"window_sec": 300,
"signal_count": 17,
"rule_id": "auth-07"
}Tanpa alasan yang eksplisit, Anda akan kesulitan membedakan antara rule yang efektif dan rule yang merusak trafik sah.
Gunakan TTL dan pembatasan scope
Jangan membuat block permanen sebagai default. Untuk banyak pola bot, temporary ban dengan TTL jauh lebih aman. Batasi juga scope tindakan:
- Block per endpoint, bukan seluruh site, jika masalahnya lokal.
- Throttle sebelum hard block jika keyakinan deteksi belum tinggi.
- Naikkan aksi bertahap: log saja → challenge → throttle → block.
Jangan pakai database utama untuk counter panas jika bisa dihindari
Counter rate, sliding window, atau score sementara lebih cocok ditempatkan di cache/in-memory store yang cepat. Jika semua request menulis ke database transaksi hanya untuk menghitung rate, Anda berisiko membuat mekanisme mitigasi justru menjadi sumber bottleneck baru.
Pisahkan policy dari kode bisnis
Kesalahan umum di aplikasi adalah menaruh banyak if-else mitigasi langsung di controller atau service bisnis. Hasilnya sulit diuji dan sulit dibersihkan. Lebih baik buat modul khusus seperti:
BotSignalCollectorBotPolicyEngineMitigationDecisionMitigationEnforcer
Pemisahan ini penting bahkan jika Anda belum memakai service terpisah. Saat nanti perlu dipisah, Anda sudah punya boundary yang jelas.
Kesalahan desain yang sering terjadi
1) Terlalu percaya pada IP
IP tetap berguna, tetapi jarang cukup. NAT, proxy, VPN, dan pool operator membuat identitas berbasis IP saja rentan menimbulkan false positive maupun false negative.
2) Menaruh semua rule di edge
Ini membuat rule cepat, tetapi biasanya proxy mulai penuh pengecualian bisnis yang sulit dipelihara. Saat kondisi ini muncul, pindahkan rule yang butuh konteks domain ke aplikasi atau policy engine.
3) Membuat service terpisah terlalu awal
Jika trafik masih moderat dan aturan belum banyak, service tambahan sering hanya menambah operational burden. Anda perlu on-call, dashboard, deployment, secret management, dan fallback behavior yang belum tentu sepadan dengan manfaatnya.
4) Tidak punya mode observasi sebelum block
Meluncurkan block rule tanpa shadow mode adalah resep false positive. Jalankan observasi dulu, ukur kandidat yang akan terkena, lalu terapkan bertahap.
5) Tidak menentukan siapa owner rule
Mitigasi botnet adalah kombinasi platform, aplikasi, dan operasi keamanan. Tanpa ownership yang jelas, rule cenderung menumpuk, tidak dibersihkan, dan tidak diketahui dampaknya.
Debugging dan evaluasi setelah rule aktif
Pertanyaan investigasi yang wajib bisa dijawab
- Request diblokir di edge, app, atau service mana?
- Rule ID dan alasan apa yang memicu?
- Apakah actor yang sama muncul di banyak endpoint?
- Apakah spike ini datang dari pola burst, low-and-slow, atau target akun tertentu?
- Apakah sistem fallback berjalan saat dependency mitigasi gagal?
Teknik debugging yang berguna
- Korelasi request ID dari edge ke aplikasi.
- Sampling log keputusan untuk request yang diblokir dan yang hampir diblokir.
- Dashboard per rule untuk melihat rule paling agresif dan tingkat kemungkinan false positive.
- Replay aman atas event historis ke policy engine untuk memvalidasi perubahan rule baru.
Jika Anda tidak bisa menjelaskan mengapa sebuah request diblokir, Anda belum punya sistem mitigasi yang benar-benar operasional, hanya kumpulan rule yang sulit dipercaya.
Checklist keputusan: tim kecil vs trafik besar
Untuk tim kecil atau produk tahap awal
- Mulai dengan edge rate limiting untuk endpoint sensitif.
- Tambahkan middleware aplikasi modular untuk sinyal berbasis akun/sesi.
- Simpan audit log terstruktur dan jalankan rule baru dalam shadow mode.
- Gunakan TTL block pendek dan aksi bertahap.
- Hindari service terpisah kecuali ada kebutuhan lintas banyak aplikasi atau bottleneck yang nyata.
Rekomendasi praktis: untuk banyak tim kecil, kombinasi edge + modular monolith sudah cukup dan lebih mudah dipelihara.
Untuk trafik besar, banyak aplikasi, atau kebutuhan security yang matang
- Pertahankan enforcement di edge untuk proteksi cepat.
- Gunakan aplikasi untuk sinyal bisnis yang presisi.
- Bangun pipeline/service terpisah untuk agregasi event, scoring, distribusi rule, dan audit lintas sistem.
- Pastikan semua dependency penting punya mode gagal yang jelas.
- Versioning policy, rollout bertahap, dan rollback terotomasi menjadi kebutuhan, bukan bonus.
Rekomendasi praktis: pada skala ini, arsitektur berlapis biasanya paling efektif: edge untuk memotong noise, aplikasi untuk keputusan kontekstual, dan service terpisah untuk koordinasi serta analitik.
Kesimpulan
Memilih arsitektur mitigasi botnet bukan soal menemukan satu lokasi “terbaik”, melainkan menempatkan keputusan pada layer yang punya sinyal memadai dengan biaya operasional yang masuk akal. Edge unggul untuk pemblokiran cepat dan murah, aplikasi unggul untuk akurasi berbasis konteks bisnis, dan service terpisah unggul saat organisasi, volume, dan kebutuhan audit sudah menuntut pemisahan.
Jika Anda masih berada pada satu aplikasi utama, mulai dari modular monolith sering merupakan pilihan paling rasional. Jika trafik dan kompleksitas meningkat, jangan langsung memindahkan seluruh logika ke service sinkron baru; lebih aman membangun deteksi asinkron + enforcement lokal. Dengan pendekatan itu, Anda mendapatkan latensi yang tetap rendah, observability yang baik, dan jalur evolusi arsitektur yang tidak memaksa rewrite besar di kemudian hari.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!