Skip to content

Instantly share code, notes, and snippets.

@phanatagama
Created June 21, 2025 04:22
Show Gist options
  • Select an option

  • Save phanatagama/0a37c36b9894bf8f9ce0a205a3a08314 to your computer and use it in GitHub Desktop.

Select an option

Save phanatagama/0a37c36b9894bf8f9ce0a205a3a08314 to your computer and use it in GitHub Desktop.
Nginx Rate Limit Configuration

Memahami Konfigurasi Dasar Rate Limit Nginx

Nginx menggunakan modul ngx_http_limit_req_module untuk mengimplementasikan rate limiting. Ada dua direktif utama yang akan kita gunakan:

  1. limit_req_zone: Direktif ini mendefinisikan "zona" atau area memori bersama tempat Nginx akan menyimpan status permintaan untuk setiap klien (misalnya, berdasarkan IP address). Ini harus diletakkan di dalam blok http.

    Sintaksnya:

    limit_req_zone $variable zone=name:size rate=rate [sync];
    • $variable: Variabel yang digunakan untuk mengidentifikasi klien. Umumnya kita menggunakan $binary_remote_addr karena ini adalah representasi biner dari alamat IP klien yang lebih hemat memori daripada $remote_addr.
    • zone=name:size: Nama zona (misalnya, mylimit) dan ukuran memori yang dialokasikan (misalnya, 10m untuk 10 megabyte). Ukuran 10m bisa menyimpan sekitar 160.000 entri IP.
    • rate=rate: Tingkat permintaan maksimum yang diizinkan (misalnya, 1r/s untuk 1 permintaan per detik, atau 30r/m untuk 30 permintaan per menit).
    • [sync]: (Opsional) Jika Anda memiliki beberapa instance Nginx dan ingin mensinkronkan status rate limit di antara mereka. Umumnya tidak diperlukan untuk setup sederhana.
  2. limit_req: Direktif ini menerapkan rate limit yang didefinisikan oleh limit_req_zone ke lokasi (endpoint) tertentu. Ini diletakkan di dalam blok http, server, atau location.

    Sintaksnya:

    limit_req zone=name [burst=number] [nodelay | delay=number];
    • zone=name: Merujuk ke nama zona yang telah didefinisikan sebelumnya di limit_req_zone.
    • [burst=number]: (Opsional) Menentukan berapa banyak permintaan diizinkan untuk "meledak" atau tiba secara instan setelah batas tercapai, tanpa langsung diblokir. Permintaan burst ini akan diantrekan dan diproses jika ada kapasitas.
    • [nodelay | delay=number]: (Opsional) Mengontrol bagaimana permintaan dalam burst ditangani.
      • nodelay: Permintaan burst akan diproses secepat mungkin tanpa penundaan, tetapi hanya sampai batas rate reguler. Jika ada banyak permintaan burst, yang melebihi kapasitas rate reguler dan burst, maka permintaan akan langsung ditolak.
      • delay=number: Permintaan dalam burst akan ditunda untuk diproses secara merata. Ini memastikan bahwa server tidak kewalahan oleh burst besar.

Studi Kasus: Rate Limit untuk Endpoint Login

Misalkan Anda memiliki sebuah API atau situs web, dan Anda ingin membatasi upaya login untuk mencegah brute force attacks. Kita akan menerapkan rate limit hanya pada endpoint /api/login.

Langkah 1: Definisikan Zona Rate Limit

Buka file konfigurasi Nginx Anda (biasanya /etc/nginx/nginx.conf atau file konfigurasi virtual host di /etc/nginx/conf.d/ atau /etc/nginx/sites-available/).

Tambahkan direktif limit_req_zone di dalam blok http { ... }:

# /etc/nginx/nginx.conf atau file konfigurasi utama
http {
    # ... konfigurasi http lainnya ...

    # Mendefinisikan zona rate limit untuk login
    # mylimitlogin: nama zona
    # 10m: ukuran memori 10MB
    # 5r/s: 5 permintaan per detik per IP
    limit_req_zone $binary_remote_addr zone=mylimitlogin:10m rate=5r/s;

    server {
        # ... konfigurasi server lainnya ...

        location /api/login {
            # Menerapkan rate limit yang telah didefinisikan
            # zone=mylimitlogin: Menggunakan zona mylimitlogin
            # burst=10: Memungkinkan 10 permintaan burst (diantrekan)
            # nodelay: Permintaan burst diproses secepat mungkin tanpa penundaan
            limit_req zone=mylimitlogin burst=10 nodelay;

            # Menambahkan header untuk informasi rate limit (opsional, tapi bagus untuk debugging)
            add_header X-RateLimit-Limit 5;
            add_header X-RateLimit-Remaining $limit_req_status; # Akan menunjukkan 'OK' atau 'REJECT'
            add_header X-RateLimit-Reset $http_x_ratelimit_reset; # Anda perlu mengimplementasikan ini di aplikasi backend

            proxy_pass http://backend_login_server; # Ganti dengan backend server Anda, misal mendeploy poject REST API berbasis NodeJs dengan pm2 di http://localhost:5000. maka arahkan ke http://localhost:5000
        }

        # ... endpoint lain tanpa rate limit atau dengan rate limit berbeda ...
    }
}

Penjelasan Konfigurasi:

  • limit_req_zone $binary_remote_addr zone=mylimitlogin:10m rate=5r/s;:

    • Kita membuat zona bernama mylimitlogin dengan ukuran 10MB.
    • Nginx akan melacak permintaan berdasarkan alamat IP klien ($binary_remote_addr).
    • Setiap IP hanya diizinkan membuat 5 permintaan per detik.
  • location /api/login { ... }:

    • Blok ini menargetkan endpoint /api/login.
  • limit_req zone=mylimitlogin burst=10 nodelay;:

    • Kita menerapkan rate limit dari zona mylimitlogin ke endpoint ini.
    • burst=10 berarti jika ada lonjakan permintaan (misalnya, lebih dari 5 per detik), Nginx akan mengizinkan hingga 10 permintaan tambahan untuk diantrekan sementara dan diproses secepatnya (sesuai rate 5r/s). Jika ada permintaan ke-11 atau lebih dalam burst tersebut, permintaan tersebut akan ditolak.
    • nodelay memastikan permintaan yang di-burst tidak sengaja ditunda lebih lama dari yang diperlukan oleh antrian Nginx (tetap mengikuti rate 5r/s).
  • add_header X-RateLimit-Limit 5; dll.:

    • Ini adalah header HTTP opsional yang berguna untuk memberi tahu klien tentang batas rate yang berlaku. Saat klien menerima kode 429 Too Many Requests, mereka dapat memeriksa header ini untuk memahami mengapa permintaan mereka ditolak dan kapan mereka bisa mencoba lagi.

Langkah 2: Uji Konfigurasi Nginx

Setelah memodifikasi file konfigurasi, sangat penting untuk menguji sintaks Nginx untuk memastikan tidak ada kesalahan:

sudo nginx -t

Jika outputnya seperti ini, berarti konfigurasi Anda baik-baik saja:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Langkah 3: Muat Ulang Nginx

Jika pengujian berhasil, muat ulang Nginx agar perubahan konfigurasi diterapkan:

sudo systemctl reload nginx

atau

sudo service nginx reload

Langkah 4: Pengujian Rate Limit

Sekarang, Anda bisa mencoba mengirimkan banyak permintaan ke /api/login dari satu IP address dalam waktu singkat. Anda bisa menggunakan curl atau alat lain.

Contoh dengan curl (jalankan ini berulang kali dengan cepat):

curl -v http://your_domain_or_ip/api/login

Setelah beberapa permintaan cepat, Anda akan mulai menerima respons dengan kode status HTTP 429 Too Many Requests. Anda juga akan melihat header X-RateLimit-Limit dan X-RateLimit-Remaining jika Anda menyertakannya dalam konfigurasi.


Konfigurasi Lanjutan (Opsional)

Mengubah Respons Error

Secara default, Nginx akan mengembalikan error 429 Too Many Requests. Anda bisa mengkustomisasi halaman error ini:

http {
    # ...
    limit_req_zone $binary_remote_addr zone=mylimitlogin:10m rate=5r/s;

    server {
        # ...
        error_page 429 /too_many_requests.html; # Mengarahkan ke halaman kustom

        location = /too_many_requests.html {
            internal; # Hanya bisa diakses secara internal oleh Nginx
            return 429 "Ups, terlalu banyak permintaan. Coba lagi nanti!";
            # Atau Anda bisa arahkan ke file HTML statis:
            # root /var/www/html;
            # index too_many_requests.html;
        }

        location /api/login {
            limit_req zone=mylimitlogin burst=10 nodelay;
            proxy_pass http://backend_login_server;
        }
    }
}

Rate Limit Berbeda untuk Beberapa Endpoint

Anda bisa mendefinisikan zona rate limit yang berbeda dan menerapkannya ke endpoint yang berbeda:

http {
    limit_req_zone $binary_remote_addr zone=mylimitlogin:10m rate=5r/s;
    limit_req_zone $binary_remote_addr zone=myapilimit:10m rate=20r/s; # Zona lain untuk API umum

    server {
        location /api/login {
            limit_req zone=mylimitlogin burst=10 nodelay;
            proxy_pass http://backend_login_server;
        }

        location /api/data { # Endpoint lain
            limit_req zone=myapilimit burst=5 nodelay; # Menerapkan limit yang berbeda
            proxy_pass http://backend_data_server;
        }

        location / { # Endpoint umum
            limit_req zone=myapilimit; # Menerapkan limit yang sama atau berbeda tanpa burst
            proxy_pass http://backend_main_server;
        }
    }
}

Dengan mengikuti tutorial ini, Anda dapat secara efektif mengkonfigurasi rate limit Nginx untuk melindungi endpoint spesifik dari penyalahgunaan dan memastikan ketersediaan layanan Anda!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment