L
Linux β€’ Literally Web ID

Mitigasi Serangan DDoS Layer 7 dan Rate Limiting Tingkat Lanjut di Nginx

⏱️ 15 menit baca β€’ πŸ“… 12 Oct 2026 β€’ πŸ‘οΈ 1 views
Mitigasi Serangan DDoS Layer 7 dan Rate Limiting Tingkat Lanjut di Nginx

1. Konteks Industri & Analisis Akar Masalah

Dalam lanskap arsitektur web modern, ancaman terhadap ketersediaan layanan (availability) telah bergeser secara signifikan. Serangan Distributed Denial of Service (DDoS) tidak lagi didominasi oleh banjir volume jaringan mentah di Layer 3 (Network) atau Layer 4 (Transport) yang menghabiskan bandwidth uplink, melainkan bermutasi menjadi serangan canggih di Layer 7 (Application). Serangan Layer 7 meniru pola traffic HTTP/HTTPS yang sah, menargetkan titik-titik krusial aplikasi web seperti endpoint autentikasi, mesin pencari database, prosesor pembayaran, atau skrip back-end yang intensif secara CPU dan I/O.

Bottleneck Performa dan Keamanan di Dunia Nyata

Ketika sebuah aplikasi web dibangun di atas tumpukan standarβ€”misalnya memadukan Nginx sebagai reverse proxy, PHP-FPM atau Node.js sebagai application runtime, serta MySQL/MariaDB dan Redis sebagai tier dataβ€”serangan HTTP flood berukuran kecil sekalipun (misalnya 10.005 request per detik pada URI /login atau /search) dapat dengan cepat melumpuhkan sumber daya sistem. Alokasi worker proses PHP-FPM atau thread event loop Node.js akan jenuh dalam hitungan detik. Koneksi TCP menumpuk di buffer kernel, memori sistem terkuras untuk mempertahankan status koneksi, dan database mengalami kelebihan beban (connection pool exhaustion) karena setiap request palsu memicu query disk I/O yang berat.

Masalah utamanya adalah arsitektur web tradisional memperlakukan setiap request masuk sebagai entitas yang setara hingga mencapai lapisan aplikasi. Tanpa pertahanan yang ketat di gerbang terdepan (Nginx), infrastruktur pendukung seperti server database, sistem cache Redis, penyimpanan S3/MinIO, hingga layanan antrean pesan (Supervisor/Cron) akan ikut terimbas, menyebabkan efek domino kegagalan sistem (cascading failure).

Kondisi Sebelum vs Sesudah Penerapan Mitigasi

Metrik / Aspek Sebelum Mitigasi (Tanpa Rate Limiting Lanjutan) Sesudah Implementasi Nginx L7 Mitigation
Respon terhadap HTTP Flood Aplikasi down; proses PHP-FPM / Node.js mencapai batas maksimal (Max Children Reached). Request berlebih langsung ditolak di Nginx dengan status HTTP 503 Service Temporarily Unavailable atau 429 Too Many Requests.
Penggunaan CPU & RAM Lonjakan drastis pada CPU (mencapai 100%) dan memori swap penuh akibat alokasi worker thread. Penggunaan sumber daya stabil; CPU dan memori hanya terpakai untuk melayani traffic yang sah (legitimate traffic).
Dampak pada Database Koneksi MySQL habis (Too many connections), query lambat, replikasi lag. Database terlindungi; query hanya dieksekusi untuk pengguna yang lolos validasi rate limit dan autentikasi.
Respon Penyerang Penyerang berhasil menghabiskan sumber daya infrastruktur dengan biaya komputasi rendah. Alamat IP penyerang otomatis diblokir melalui integrasi Nginx log dan Fail2ban dalam hitungan detik.

2. Konsep Inti & Deep Dive Arsitektur

Untuk merancang pertahanan yang tangguh, kita harus memahami bagaimana Nginx memproses request masuk dan bagaimana modul pembatasan laju (rate limiting) bekerja di balik layar (under the hood).

Cara Kerja Modul limit_req dan limit_conn di Nginx

Nginx menggunakan modul ngx_http_limit_req_module untuk membatasi tingkat permintaan berdasarkan kunci tertentu (biasanya alamat IP klien, $binary_remote_addr) menggunakan algoritma Leaky Bucket.

Bayangkan sebuah ember dengan lubang di bagian bawahnya. Air yang masuk merepresentasikan request HTTP, sedangkan air yang keluar merepresentasikan pemrosesan request oleh server pada kecepatan konstan. Jika air masuk terlalu cepat dan kapasitas ember (parameter burst) terlampaui, air sisanya akan tumpah (request ditolak).

Di sisi lain, modul ngx_http_limit_conn_module membatasi jumlah koneksi aktif secara bersamaan (concurrent connections) dari kunci yang sama. Ini sangat efektif untuk mencegah serangan slowloris atau pengunduhan file berukuran besar secara simultan.

Alur Eksekusi Data & Visualisasi Arsitektur

Berikut adalah diagram ASCII flow chart yang menggambarkan bagaimana traffic disaring sebelum mencapai lapisan aplikasi dan database:

[ Internet Traffic / Botnets ]
              β”‚
              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Cloudflare CDN       β”‚ (Edge Caching, WAF Dasar, DDoS L3/L4)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      Nginx Reverse Proxy  β”‚ ──► [ Modul limit_conn ] (Cek Koneksi Bersamaan)
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚
              β–Ό
        [ Modul limit_req ]   ──► (Cek Frekuensi Request / Algoritma Leaky Bucket)
              β”‚
              β”œβ”€β”€ [ Jika Melebihi Batas ] ──► Return HTTP 429 / 503
              β”‚
              └── [ Jika Valid ]
                        β”‚
                        β–Ό
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚ App Backend (Node/PHP/Go) β”‚
          β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
                β”‚               β”‚
                β–Ό               β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚ MySQL/MariaDBβ”‚ β”‚ Redis Cache β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                β–²
                β”‚ (Log Akses)
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
        β”‚   Fail2ban   β”‚ ──► [ Update Firewall / IPTables / NFTables ]
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3. Perbandingan Komparatif / Analisis Pendekatan

Dalam dunia infrastruktur enterprise, pemilihan strategi pembatasan akses memiliki konsekuensi langsung terhadap performa sistem, konsumsi sumber daya, dan pengalaman pengguna (User Experience).

Pendekatan Mitigasi Kelebihan Kekurangan Trade-off Sumber Daya (CPU/RAM/Latency)
A. Rate Limiting di Nginx (limit_req) Sangat cepat, memproses di tingkat memori bersama (shared memory zone), tidak membebani backend. Kurang fleksibel untuk logika bisnis yang kompleks (misal: membedakan user login vs guest). CPU: Sangat rendah.
RAM: Rendah (tergantung ukuran zona memori).
Latency: Minimal (< 1ms).
B. WAF Berbasis Cloud (Cloudflare/AWS WAF) Menyerap serangan volume besar sebelum mencapai server asal; fitur AI/ML untuk deteksi bot cangkang. Bergantung pada pihak ketiga; biaya langganan tinggi; potensi latensi tambahan jika routing tidak optimal. CPU/RAM Server Asal: Sangat hemat.
Latency: Tergantung lokasi edge CDN.
C. Intrusion Prevention (Fail2ban + Nginx Log) Efektif memblokir IP penyerang secara permanen/temporer di level firewall OS (iptables/nftables). Reaksi berbasis reaktif (harus membaca log terlebih dahulu); potensi false positive yang memblokir pengguna sah. CPU: Sedikit meningkat saat parsing log besar.
RAM: Rendah.
Latency: Tidak berdampak langsung pada request HTTP.
D. Application-Level Rate Limiting (Redis + Middleware) Sangat fleksibel; dapat mendasarkan limit pada token JWT, role pengguna, atau parameter payload POST. Menambah beban pada database/Redis dan menambah siklus eksekusi kode backend. CPU/RAM Backend: Tinggi.
Latency: Meningkat karena tambahan round-trip ke Redis.

[!TIP] Rekomendasi Arsitek: Gunakan pendekatan hibrida. Terapkan mitigasi lapis pertama di Cloudflare (WAF/Challenge), lapis kedua di Nginx (limit_req & limit_conn) untuk melindungi server dari botnet yang lolos, dan lapis ketiga (Fail2ban) untuk menindak tegas IP yang persisten melakukan brute-force.


4. Prasyarat Sistem & Persiapan Lingkungan

Sebelum menerapkan konfigurasi lanjutan, pastikan lingkungan server Anda memenuhi spesifikasi dan prasyarat berikut:

  1. Sistem Operasi: Ubuntu 22.04 LTS / Debian 12 Bookworm (atau RHEL 9 / AlmaLinux 9).
  2. Web Server: Nginx Versi 1.22 atau yang lebih baru (dikompilasi dengan dukungan modul HTTP limit).
  3. Keamanan Sistem: Fail2ban terinstal (sudo apt install fail2ban).
  4. Keluaran Hak Akses: Akses root atau sudo ke seluruh node infrastruktur.

Verifikasi instalasi Nginx dan modul dasarnya melalui terminal:

nginx -v
nginx -V 2>&1 | grep --color=auto -oE "http_limit_req_module|http_limit_conn_module"

Jika output menampilkan nama modul tersebut, sistem Anda siap melangkah ke tahap implementasi.


5. Panduan Implementasi Langkah demi Langkah

Berikut adalah konfigurasi tingkat produksi untuk Nginx yang mencakup zona memori bersama, pembatasan koneksi, aturan rate limiting untuk endpoint sensitif, serta integrasi dengan Fail2ban.

Langkah 1: Konfigurasi Global Nginx (/etc/nginx/nginx.conf)

Buka file konfigurasi utama Nginx dan tambahkan zona memori bersama di dalam blok http:

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}
mathrm http {

    ## Pengaturan Dasar
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ## =========================================================================
    ## ZONA RATE LIMITING & CONNECTION LIMITING
    ## =========================================================================

    # 1. Zona untuk membatasi jumlah koneksi per IP
    # Menampung 10MB data status (sekitar 160.000 alamat IP)
    limit_conn_zone $binary_remote_addr zone=addr_conn:10m;

    # 2. Zona umum untuk request umum (maksimal 10 request per detik)
    limit_req_zone $binary_remote_addr zone=general_limit:20m rate=10r/s;

    # 3. Zona ketat untuk endpoint autentikasi / login (maksimal 1 request per detik)
    limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;

    # 4. Zona untuk API berat (maksimal 5 request per detik)
    limit_req_zone $binary_remote_addr zone=api_limit:20m rate=5r/s;

    # Format Log Khusus untuk Keamanan & Fail2ban
    log_format security_log '$remote_addr - $remote_user [$time_local] '
                            '"$request" $status $body_bytes_sent '
                            '"$http_referer" "$http_user_agent" '
                            'rt=$request_time uct="$upstream_connect_time"';

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Langkah 2: Konfigurasi Virtual Host / Server Block (/etc/nginx/sites-available/production-app.conf)

Terapkan zona-zona tersebut pada server block aplikasi Anda:

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    root /var/www/html/public;
    index index.php index.html index.htm;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    access_log /var/log/nginx/example_access.log security_log;
    error_log /var/log/nginx/example_error.log warn;

    # Batasi maksimal 20 koneksi simultan per IP
    limit_conn addr_conn 20;

    # Halaman kustom saat terkena rate limit
    limit_req_status 429;
    error_page 429 /custom_429.html;

    location = /custom_429.html {
        root /var/www/html/public;
        internal;
    }

    # Lokasi utama web dengan rate limit umum
    location / {
        limit_req zone=general_limit burst=20 nodelay;
        try_files $uri $uri/ /index.php?$query_string;
    }

    # Endpoint Login / Autentikasi (Sangat Ketat)
    location = /api/v1/auth/login {
        limit_req zone=login_limit burst=3 nodelay;
        
        # Meneruskan ke backend PHP-FPM / Node.js
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Endpoint API Umum
    location /api/ {
        limit_req zone=api_limit burst=10 nodelay;
        
        try_files $uri $uri/ /index.php?$query_string;
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_prm SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

# Redirect HTTP ke HTTPS
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

Langkah 3: Konfigurasi Fail2ban untuk Nginx

Agar penyerang yang terus-menerus memicu error rate limit atau brute-force diblokir di tingkat firewall OS, buat custom filter dan jail.

  1. Buat filter Nginx limit di /etc/fail2ban/filter.d/nginx-limit.conf:
[Definition]
failregex = ^<HOST> -.*"(GET|POST).* HTTP/.*" 429
ignoreregex =
  1. Tambahkan konfigurasi Jail di /etc/fail2ban/jail.local:
[nginx-limit]
enabled = true
filter = nginx-limit
action = iptables-multiport[name=HTTP, port="http,https", protocol=tcp]
logpath = /var/log/nginx/example_access.log
findtime = 60
maxretry = 10
bantime = 3600
  1. Restart layanan Fail2ban:
sudo systemctl restart fail2ban
sudo fail2ban-client status nginx-limit

6. Bedah Kode & Penjelasan Detail Baris Kunci

Analisis mendalam terhadap parameter-parameter krusial dalam konfigurasi di atas:

  • limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;

    • $binary_remote_addr: Menggunakan representasi biner dari alamat IP (panjang 4 byte untuk IPv4 atau 16 byte untuk IPv6) guna menghemat memori zona dibandingkan menggunakan string teks IP.
    • zone=login_limit:10m: Alokasi memori bersama sebesar 10 Megabita yang dapat menampung sekitar 160.000 rekam jejak IP aktif.
    • rate=1r/s: Membatasi kecepatan rata-rata maksimal 1 request per detik per alamat IP.
  • limit_req zone=login_limit burst=3 nodelay;

    • burst=3: Memberikan toleransi lonjakan (burst) hingga 3 request tambahan yang diizinkan masuk secara instan jika pengguna melakukan klik berulang kali dalam waktu singkat.
    • nodelay: Parameter krusial. Tanpa nodelay, Nginx akan menunda (delay) pemrosesan request yang masuk dalam rentang burst agar sesuai dengan kecepatan rata-rata rate=1r/s. Dengan nodelay, request dalam batas burst akan langsung dieksekusi atau langsung ditolak jika melewati batas burst, mencegah penumpukan koneksi di antrean.

7. Skenario Produksi & Studi Kasus Dunia Nyata

Studi Kasus: Menghadapi Kampanye Botnet Credential Stuffing

Sebuah portal e-commerce enterprise mengalami serangan credential stuffing di mana 50.000 IP botnet unik mencoba melakukan login secara bersamaan ke endpoint /api/v1/auth/login dengan kecepatan 5 request per detik per IP.

Solusi Penerapan:

  1. Cloudflare WAF memblokir signature User-Agent yang mencurigakan dan memberlakukan tantangan JavaScript (JS Challenge).
  2. Botnet yang berhasil melewati Cloudflare langsung berhadapan dengan Nginx pada direktif location = /api/v1/auth/login yang menerapkan zone=login_limit dengan rate=1r/s burst=3 nodelay.
  3. Request ke-4 dari IP yang sama langsung menghasilkan HTTP status 429 Too Many Requests.
  4. Log Nginx mencatat baris dengan status 429. Filter Fail2ban (nginx-limit) mendeteksi lebih dari 10 request berstatus 429 dalam waktu 60 detik dari IP yang sama.
  5. Fail2ban secara otomatis mengeksekusi aturan iptables untuk memblokir IP tersebut selama 1 jam penuh (bantime = 3600). Hasilnya, beban pada backend PHP-FPM dan database MySQL turun drastis, menjaga stabilitas layanan bagi pelanggan sah.

8. Common Pitfalls, Anti-Patterns & Solusi

  1. Anti-Pattern: Menggunakan $remote_addr di balik Reverse Proxy / CDN tanpa set_real_ip_from

    • Masalah: Jika Nginx berada di belakang Cloudflare atau Load Balancer eksternal, $remote_addr akan selalu mencatat alamat IP Cloudflare, bukan alamat IP asli pengguna. Akibatnya, seluruh pengguna internet akan berbagi satu kuota rate limit yang sama.
    • Solusi: Selalu konfigurasikan modul ngx_http_realip_module di Nginx:
      set_real_ip_from 173.245.48.0/20;
      set_real_ip_from 103.21.244.0/22;
      # ... (daftar subnet IP Cloudflare lainnya)
      real_ip_header CF-Connecting-IP;
      
  2. Kesalahan Alokasi Ukuran Zona Memori (zone=...:Xm)

    • Masalah: Mengalokasikan memori terlalu kecil untuk zona rate limit pada situs ber-traffic sangat tinggi akan menyebabkan Nginx mengabaikan (drop) data tracking IP lama sebelum waktunya.
    • Solusi: Hitung kebutuhan memori. Setiap catatan IP membutuhkan sekitar 64 atau 128 byte di memori bersama. Zona 10MB cukup untuk Β±160.000 IP unik.

9. Benchmark, Metrik Kinerja & Tuning Performa

Untuk memvalidasi ketahanan konfigurasi rate limiting, lakukan pengujian beban (load testing) menggunakan tool modern seperti k6 atau wrk.

Skrip Pengujian K6 (load-test.js)

import http from 'k6/http';
import { check, sleep } from 'k6';

export const options = {
  stages: [
    { duration: '30s', target: 50 },  // Ramp-up ke 50 virtual users
    { duration: '1m', target: 200 },  // Beban tinggi 200 virtual users
    { duration: '30s', target: 0 },   // Ramp-down
  ],
};

export default function () {
  const res = http.get('https://example.com/api/v1/auth/login');
  check(res, {
    'status is 200 or 429': (r) => r.status === 200 || r.status === 429,
  });
  sleep(0.1);
}

Jalankan pengujian melalui terminal:

k6 run load-test.js

Interpretasi Hasil & Tuning Lanjutan

  • Jika persentase status 429 meningkat seiring bertambahnya virtual users sementara penggunaan CPU server tetap di bawah 20%, maka konfigurasi rate limiting berfungsi optimal.
  • Lakukan tuning pada parameter kernel Linux (/etc/sysctl.conf) untuk menangani lonjakan koneksi TCP:
    net.core.somaxconn = 65535
    net.ipv4.tcp_max_syn_backlog = 16384
    net.ipv4.ip_local_port_range = 1024 65535
    
    Terapkan perubahan dengan perintah sudo sysctl -p.

10. Checklist Penerapan Produksi & Kesimpulan

Sebelum meluncurkan konfigurasi ini ke lingkungan produksi, pastikan Anda telah melewati checklist validasi berikut:

  • Sintaks Nginx telah diverifikasi (sudo nginx -t) tanpa ada error peringatan.
  • Modul ngx_http_realip_module sudah aktif dan dikonfigurasi dengan benar untuk mengenali IP asli di balik CDN/Load Balancer.
  • Zona memori limit_req_zone dan limit_conn_zone telah dialokasikan dengan ukuran memori yang memadai.
  • Endpoint sensitif (/login, /register, /api/) telah dipisahkan dengan zona limit yang lebih ketat dibanding halaman statis atau umum.
  • Fail2ban terintegrasi dengan log Nginx dan aturan pembatokan IP (iptables/nftables) aktif berjalan.
  • Halaman kustom error 429 Too Many Requests telah disiapkan untuk memberikan pengalaman pengguna yang profesional.

Dengan mengimplementasikan arsitektur mitigasi Layer 7 berbasis Nginx ini, infrastruktur web Anda kini memiliki benteng pertahanan berlapis yang tidak hanya melindungi server dari kelumpuhan akibat serangan DDoS aplikasi, tetapi juga menjaga integritas data backend, stabilitas database, dan ketersediaan layanan secara keseluruhan bagi pengguna sah.

🏷️ Tags: #Nginx #High Concurrency #Performance #Sysadmin #Web Server