Pembatasan IP #
Kontrol akses berbasis IP adalah cara paling langsung untuk membatasi siapa yang bisa mengakses bagian tertentu dari server. Nginx menyediakan directive allow dan deny yang sederhana tapi fleksibel, serta modul geo untuk logika yang lebih kompleks.
allow dan deny: Dasar #
server {
location /admin/ {
# Izinkan IP spesifik
allow 203.0.113.10;
# Izinkan subnet
allow 10.0.0.0/8;
allow 192.168.1.0/24;
# Izinkan IPv6
allow 2001:db8::/32;
# Tolak semua yang lain
deny all;
proxy_pass http://admin_backend;
}
}
Nginx memproses aturan allow dan deny secara berurutan dan berhenti di aturan pertama yang cocok. Urutan penulisan penting.
# ANTI-PATTERN: deny all dulu, lalu allow
location /api/ {
deny all; # ← Semua ditolak di sini
allow 10.0.0.0/8; # ← Tidak pernah dieksekusi
}
# BENAR: allow dulu, deny all terakhir
location /api/ {
allow 10.0.0.0/8; # ← Cocok untuk 10.x.x.x → izinkan, stop
deny all; # ← Untuk semua yang lain → tolak
}
Blokir IP Tertentu, Izinkan Semua yang Lain #
Kebalikan dari pola di atas — berguna untuk memblokir IP yang diketahui berbahaya:
server {
location / {
# Blokir IP yang diketahui bermasalah
deny 198.51.100.0/24;
deny 203.0.113.5;
# Izinkan semua yang lain
allow all;
proxy_pass http://backend;
}
}
Modul geo: Logika IP yang Lebih Fleksibel #
geo memungkinkan kamu membuat variabel berdasarkan IP klien. Lebih fleksibel dari allow/deny untuk kasus yang kompleks:
http {
# Buat variabel $is_internal_ip
geo $is_internal_ip {
default 0; # Default: bukan IP internal
10.0.0.0/8 1; # Jaringan internal
172.16.0.0/12 1;
192.168.0.0/16 1;
127.0.0.1 1;
}
# Buat variabel $country_allowed berdasarkan negara (jika punya GeoIP)
# geo $country_allowed {
# default 0;
# id 1; # Indonesia
# sg 1; # Singapura
# }
server {
location /internal-api/ {
# Gunakan variabel dari geo untuk keputusan akses
if ($is_internal_ip = 0) {
return 403;
}
proxy_pass http://internal_backend;
}
}
}
Menangani IP di Balik Proxy: ngx_http_realip_module #
Jika Nginx berada di balik load balancer atau CDN (Cloudflare, AWS ALB, dll.), $remote_addr akan berisi IP proxy, bukan IP klien asli. Modul realip mengatasi ini:
http {
# Daftar IP proxy yang dipercaya (yang bisa meng-override IP)
# Nginx akan membaca IP klien asli dari header X-Forwarded-For
# HANYA dari IP yang ada di daftar ini
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/12;
# Untuk Cloudflare, tambahkan semua IP Cloudflare:
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
# (daftar lengkap di https://www.cloudflare.com/ips/)
# Header yang berisi IP asli klien
real_ip_header X-Forwarded-For;
# Ambil IP paling kanan yang belum diverifikasi
# (lebih aman dari default yang ambil paling kiri)
real_ip_recursive on;
}
Setelah konfigurasi ini, $remote_addr akan berisi IP klien asli, bukan IP proxy. Semua fitur yang bergantung pada IP (rate limiting, geo, allow/deny) akan bekerja dengan benar.
Jangan menambahkan IP yang tidak kamu kendalikan keset_real_ip_from. Siapapun bisa mengirim headerX-Forwarded-Fordengan nilai sembarang. Hanya IP proxy yang benar-benar kamu percaya (load balancer milikmu, Cloudflare) yang boleh di-trust untuk meng-override IP.
Proteksi Endpoint Sensitif #
Pola lengkap untuk mengamankan endpoint internal:
server {
listen 443 ssl;
server_name example.com;
# Site utama — akses terbuka
location / {
proxy_pass http://app_backend;
}
# Admin panel — hanya IP internal
location /admin/ {
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
proxy_pass http://admin_backend;
}
# Nginx status — hanya localhost
location /nginx_status {
stub_status;
allow 127.0.0.1;
deny all;
}
# Metrics Prometheus — hanya monitoring server
location /metrics {
allow 10.0.1.50; # IP monitoring server
deny all;
proxy_pass http://localhost:9090;
}
# Blokir akses ke file sensitif
location ~* \.(env|git|sql|bak|log)$ {
deny all;
return 404;
}
}
Ringkasan #
- Urutan
allow/denypenting — Nginx berhenti di aturan pertama yang cocok.allowspesifik selalu sebelumdeny all.geolebih fleksibel dariallow/denylangsung — buat variabel berdasarkan IP untuk digunakan di berbagai kondisi.- Jika di balik proxy/CDN, gunakan
set_real_ip_from+real_ip_headeragar$remote_addrberisi IP klien asli, bukan IP proxy.- Hanya trust
set_real_ip_fromke IP yang benar-benar kamu kendalikan — mempercayai IP sembarang membuka celah IP spoofing.- Selalu proteksi endpoint sensitif (
/admin,/metrics,/nginx_status) dengan IP allowlist yang ketat.