Saat Nginx dijalankan di balik NAT, reverse proxy, atau container (Docker), sering muncul masalah:
Semua request terlihat datang dari IP yang sama (proxy / NAT IP)
Seolah semua user punya IP yang sama
Ini menyebabkan masalah nyata:
- Rate limiting salah target
- Logging IP asli salah
- GeoIP & analytics rusak
- Security rules tidak efektif
Masalah ini dikenal sebagai Real IP Problem.
Contents
- 1 1. Apa yang Terjadi Sebenarnya?
- 2 2. Header Penting: X-Forwarded-For dan X-Real-IP
- 3 3. Module Nginx Penting
- 4 4. Contoh Konfigurasi di Docker
- 5 5. Kesalahan Fatal yang Sering Terjadi
- 6 6. Real Case: Rate Limit Salah Target
- 7 7. GeoIP & Analytics
- 8 8. Multi-layer Proxy
- 9 9. Logging yang Akurat
- 10 10. Checklist Aman Real IP di Docker/NAT
- 11 11. Kesimpulan
- 12 Related Posts
1. Apa yang Terjadi Sebenarnya?
Contoh arsitektur Docker:
Internet → Load Balancer → Docker Nginx → Backend
- Semua request ke Nginx berasal dari LB internal
$remote_addrNginx = LB IP, bukan client asli
Jika tidak ditangani:
limit_req/limit_conn→ salah target- Log → semua user sama IP
- GeoIP → semua traffic di satu kota (LB)
2. Header Penting: X-Forwarded-For dan X-Real-IP
- Proxy modern (LB, CDN, Nginx) menyisipkan header IP asli:
X-Forwarded-For: 203.0.113.25, 10.0.0.1
X-Real-IP: 203.0.113.25
- Client asli = IP pertama (
203.0.113.25) - IP proxy / NAT = IP berikutnya (
10.0.0.1)
Nginx perlu tahu agar $remote_addr merefleksikan client asli.
3. Module Nginx Penting
ngx_http_realip_module
Directive utama:
set_real_ip_from <trusted_proxy_ip>;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
set_real_ip_from→ hanya trust proxy tertentureal_ip_header→ baca headerreal_ip_recursive→ ambil IP pertama dari list
4. Contoh Konfigurasi di Docker
http {
real_ip_header X-Forwarded-For;
set_real_ip_from 172.18.0.0/16; # subnet Docker internal
real_ip_recursive on;
server {
listen 80;
location / {
proxy_pass http://backend;
# Rate limiting berdasarkan $remote_addr sekarang valid
}
}
}
Efek:
$remote_addr= client asli- Rate limit → tidak “semua user satu IP”
- Logs → akurat
5. Kesalahan Fatal yang Sering Terjadi
- Tidak menambahkan
set_real_ip_from
→ Nginx tetap mencatat IP proxy real_ip_recursiveoff
→$remote_addr= IP terakhir (proxy) bukan client- Menaruh subnet salah
→ IP internal yang tidak trusted bisa memalsukan IP client - Menggunakan
$http_x_forwarded_forlangsung di config
→ Bisa di-spoof
→ Tidak aman untuk rate limiting / security
6. Real Case: Rate Limit Salah Target
limit_req_zone $remote_addr zone=api:10m rate=5r/s;
- Semua request Docker LB →
$remote_addr = 10.0.0.5 - 1000 user → Nginx pikir 1 user → throttle → banyak 429
- Solusi:
real_ip_module→$remote_addr = client asli
7. GeoIP & Analytics
Tanpa real_ip_module:
- Semua traffic terlihat dari server / LB IP
- Analitik & GeoIP rusak
- Security tools → false alert
8. Multi-layer Proxy
Jika ada:
Client → CDN → LB → Nginx → Backend
- Gunakan
real_ip_recursive on set_real_ip_from→ trust semua layer yang sah- Ambil IP pertama yang sah sebagai
$remote_addr
9. Logging yang Akurat
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
- Masih simpan header asli untuk debugging
$remote_addr→ bisa dipakai rate limit & analytics
10. Checklist Aman Real IP di Docker/NAT
- Gunakan
ngx_http_realip_module - Tentukan subnet trusted (
set_real_ip_from) - Aktifkan
real_ip_recursive on - Jangan gunakan
$http_x_forwarded_formentah-mentah untuk security - Uji dengan
curl --header "X-Forwarded-For: 1.2.3.4"→ pastikan$remote_addrbenar
11. Kesimpulan
Jika Nginx dijalankan di balik NAT atau container, real IP tidak otomatis.
Kalimat kuncinya:
Tanpa real_ip_module, rate limit, logging, dan security bisa salah kaprah, meski semua traffic berjalan normal.