L
Event-Driven Architecture 📚 Definitive Comprehensive Guide • Literally Web ID

Membangun Arsitektur Event-Driven Berbasis Kafka untuk Log Keamanan Real-Time

⏱️ 15 menit baca • 📅 20 Oct 2026 • 👁️ 2 views
Membangun Arsitektur Event-Driven Berbasis Kafka untuk Log Keamanan Real-Time

1. Titik Awal Masalah: Mengapa Arsitektur Lama Sering Ambruk di Produksi

Ingatkah Anda malam ketika server produksi tiba-tiba hang, CPU melonjak ke 100%, dan disk I/O mengalami kejenuhan total gara-gara lonjakan traffic yang mencurigakan? Di lini depan, kita mengandalkan Nginx, WAF berbasis ModSecurity, Fail2ban, serta sekumpulan backend Go dan PHP-FPM yang melayani jutaan request harian. Namun, mimpi buruk sebenarnya bukan terletak pada aplikasi yang melambat, melainkan pada bagaimana sistem keamanan kita mencoba mencatat setiap kejadian.

Secara tradisional, kita menulis log keamanan langsung ke disk lokal (/var/log/nginx/access.log, /var/log/auth.log), lalu menjalankan skrip rsyslog atau Filebeat untuk mengirimkannya ke tumpukan SIEM (Security Information and Event Management). Ketika serangan DDoS layer 7 atau credential stuffing terjadi, volume log melonjak ribuan persen dalam hitungan detik. Disk lokal langsung kehabisan inodes, proses logging memblokir eksekusi thread utama Nginx, dan aplikasi web kita ikut tumbang bukan karena aplikasinya gagal, melainkan karena kehabisan napas akibat mencatat lognya sendiri.

Pendekatan sinkron atau blocking I/O murni dalam pengumpulan log keamanan adalah bom waktu. Kita butuh sebuah penyangga elastis—sebuah lapisan peredam kejut (shock absorber) yang mampu menelan jutaan event per detik tanpa membuat sistem utama berkedip. Dari sinilah kita mulai melirik Apache Kafka, bukan sebagai tren teknologi semata, tetapi sebagai penyelamat nyawa infrastruktur web kita.

Namun, membuang log secara membabi buta ke Kafka tanpa desain topologi yang matang justru akan menciptakan masalah baru di sisi broker. Mari kita bedah bagaimana pipa data terdistribusi ini bekerja tanpa sihir di balik layar.

2. Di Balik Layar: Bagaimana Sistem Ini Bekerja Tanpa Sihir

Bayangkan Kafka bukan sekadar message broker biasa, melainkan sebuah sistem pencatatan berurutan (append-only log) berbasis disk yang sangat teroptimasi, mirip seperti cara kerja mesin database relasional mencatat transaksi ke dalam Write-Ahead Log (WAL). Data log keamanan dari berbagai lapisan infrastruktur—mulai dari edge proxy Cloudflare, server Nginx, hingga daemon Postfix dan database MySQL—mengalir melalui pipa-pipa kecil tanpa harus peduli apakah sistem SIEM di ujung sana sedang lambat atau bahkan mati.

Di garda terdepan, agen pengumpul log seperti Filebeat atau Vector bertindak sebagai Producer. Mereka memindai file log secara tailing, melakukan batching secara cerdas di memori lokal, lalu mendorongnya ke Kafka Broker. Di sinilah keajaiban arsitektur event-driven terjadi: Zero-Copy Principle. Kafka menggunakan pemanggilan sistem sendfile di tingkat OS, memungkinkan transfer data langsung dari memori page cache ke soket jaringan tanpa melibatkan CPU untuk menyalin data bolak-balik.

[Nginx / Fail2ban / S3] ---> (Filebeat Producer) ---> [Kafka Cluster (Topics)] ---> (Consumer Group / SIEM)

Begitu data masuk ke Kafka Topic, data tersebut dibagi ke dalam beberapa Partition agar bisa diproses secara paralel. Di sinilah Consumer Group mengambil peran utama. Alih-alih satu aplikasi membaca jutaan log sendirian, sekelompok consumer (misalnya layanan berbasis Go atau Python) berbagi beban membaca partisi secara dinamis. Jika salah satu consumer mati, Kafka otomatis melakukan rebalance dan mengalihkan beban ke consumer yang masih hidup tanpa ada log yang tercecer.

[!TIP] Pastikan Anda memahami perbedaan antara at-least-once dan at-most-once delivery. Untuk log keamanan, kehilangan satu baris log otentikasi bisa berarti terlewatnya jejak peretas. Selalu konfigurasi produser Anda dengan acks=all dan aktifkan idempotence di sisi Kafka.

3. Pilihan Pendekatan & Kompromi yang Harus Diambil

Sebelum kita menulis baris konfigurasi pertama, kita harus jujur pada diri sendiri mengenai kompromi arsitektural. Tidak ada sistem yang sempurna; yang ada hanyalah pilihan yang paling sesuai dengan kapasitas tim dan anggaran infrastruktur Anda.

Dalam merancang pipa log Kafka ini, kita dihadapkan pada persimpangan jalan:

  1. Pendekatan A: Filebeat -> Kafka -> Logstash -> Elasticsearch (ELK Stack Tradisional)

    • Kelebihan: Ekosistem matang, plugin berlimpah, mudah melakukan parsing grok pattern yang kompleks di Logstash.
    • Kekurangan: Logstash adalah konsumen memori yang rakus (berbasis JVM). Menambah Logstash di tengah-tengah sering kali menciptakan bottleneck baru sebelum data sampai ke penyimpanan akhir.
  2. Pendekatan B: Vector/FluentBit -> Kafka -> Go Custom Consumers -> ClickHouse / SIEM

    • Kelebihan: Sangat ringan, menggunakan memori minimal (ditulis dalam Rust dan Go), throughput luar biasa tinggi, dan ClickHouse jauh lebih efisien untuk menyimpan data log berbasis time-series dibandingkan Elasticsearch.
    • Kekurangan: Kurangnya plugin siap pakai untuk transformasi data rumit, membutuhkan lebih banyak kode kustom.

Kita akan memilih kombinasi modern yang menggabungkan efisiensi maksimal: Filebeat/Vector di sisi Edge, Apache Kafka sebagai Buffer, dan Consumer Group berbasis Go untuk melakukan deteksi anomali real-time sebelum data diarsipkan ke penyimpanan jangka panjang.

4. Meracik Lingkungan: Persiapan & Prasyarat Lapangan

Mari kita siapkan tangan kita. Kita asumsikan Anda memiliki setidaknya 3 node server broker Kafka untuk memastikan ketersediaan tinggi (High Availability), dengan ZooKeeper (atau Kafka Kraft mode yang lebih modern) mengelola kluster.

Pertama-tama, pastikan sistem operasi Linux (Ubuntu 22.04 LTS atau RHEL 9) telah di-tuning untuk menangani koneksi jaringan skala besar dan file descriptors. Buka file /etc/sysctl.conf dan tambahkan parameter performa jaringan berikut:

# /etc/sysctl.conf - Tuning kernel untuk Kafka dan Web Gateway
fs.file-max = 2097152
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
vm.swappiness = 10
vm.max_map_count = 262144

Terapkan perubahan tersebut tanpa harus reboot server:

sudo sysctl -p

Selanjutnya, pastikan batas file descriptor untuk pengguna layanan (misalnya kafka atau root) di /etc/security/limits.conf dinaikkan:

kafka     soft    nofile    65536
kafka     hard    nofile    65536
kafka     soft    nproc     4096
kafka     hard    nproc     4096

[!IMPORTANT] Jangan pernah menjalankan Kafka di atas mesin dengan swap memory yang aktif. Jika memori fisik habis, Kafka akan mengalami garbage collection pause yang panjang, memicu heartbeat timeout, dan menyebabkan kluster terus-menerus melakukan rebalance yang merusak stabilitas.

5. Langkah Implementasi: Membangun Solusi yang Tangguh

Sekarang kluster Kafka kita sudah siap bernapas dengan lega. Langkah berikutnya adalah membuat topik khusus untuk menampung log keamanan dengan replikasi yang memadai agar tahan terhadap kegagalan perangkat keras.

Jalankan perintah berikut untuk membuat topik security-audit-logs dengan 6 partisi dan faktor replikasi 3:

bin/kafka-topics.sh --create \
  --bootstrap-server kafka-broker-01:9092,kafka-broker-02:9092 \
  --replication-factor 3 \
  --partitions 6 \
  --topic security-audit-logs \
  --config min.insync.replicas=2 \
  --config retention.ms=604800000

Dengan konfigurasi di atas, kita memastikan bahwa setiap pesan wajib ditulis ke setidaknya 2 replika (min.insync.replicas=2) sebelum produsen menerima konfirmasi sukses (acks=all), dan data akan disimpan selama 7 hari (604800000 milidetik) sebelum otomatis dibersihkan oleh sistem.

Kini, saatnya mengonfigurasi pengumpul log di server Nginx web kita menggunakan Filebeat agar mulai mengirimkan data akses dan error ke topik tersebut.

6. Membedah Baris Kode Krusial yang Kerap Menjebak

Berikut adalah konfigurasi valid filebeat.yml yang diinstal pada web server Nginx Anda. Perhatikan bagaimana kita mengatur compression dan bulk size agar jaringan tidak jenuh saat terjadi lonjakan traffic.

# /etc/filebeat/filebeat.yml
filebeat.inputs:
  - type: log
    enabled: true
    paths:
      - /var/log/nginx/access.log
    fields:
      log_type: nginx_access
      environment: production
    fields_under_root: true
    json.keys_under_root: true
    json.add_error_key: true

  - type: log
    enabled: true
    paths:
      - /var/log/auth.log
    fields:
      log_type: system_auth
      environment: production
    fields_under_root: true

output.kafka:
  hosts: ["kafka-broker-01:9092", "kafka-broker-02:9092"]
  topic: "security-audit-logs"
  partition.round_robin:
    reachable_only: false
  client_id: "filebeat_web_cluster_01"
  worker: 2
  compression: gzip
  max_message_bytes: 1000000
  required_acks: 1
  timeout: 30s

Di sisi penerima (Consumer), kita sering kali menemui jebakan klasik berupa kegagalan menangani offset commit. Jika program consumer Anda crash di tengah jalan tanpa melakukan commit offset, pesan yang sama akan dibaca ulang dan menyebabkan duplikasi data di sistem SIEM.

Berikut potongan kode consumer berbasis Go menggunakan pustaka segmentio/kafka-go atau confluent-kafka-go yang menangani komit secara aman:

package main

import (
	"context"
	"fmt"
	"log"
	"github.com/segmentio/kafka-go"
)

func main() {
	// Konfigurasi Consumer Group
	r := kafka.NewReader(kafka.ReaderConfig{
		Brokers:  []string{"kafka-broker-01:9092", "kafka-broker-02:9092\
🏷️ Tags: #Nginx #High Concurrency #Performance #Sysadmin #Web Server