1. Apa Itu Reverse Proxy?
Dalam arsitektur web modern, reverse proxy adalah server yang menerima request dari client (browser), lalu meneruskannya ke satu atau lebih backend server. Client tidak pernah berkomunikasi langsung dengan server aplikasi â semua request melewati proxy terlebih dahulu.
Bayangkan reverse proxy seperti resepsionis di gedung perkantoran. Ketika ada tamu yang datang, resepsionis akan memeriksa identitas, lalu mengarahkan tamu ke ruangan yang tepat. Tamu tidak perlu tahu letak ruangan â mereka cukup datang ke resepsionis.
Forward Proxy vs Reverse Proxy
| Aspek | Forward Proxy | Reverse Proxy |
|---|---|---|
| Siapa yang dilayani | Client | Server |
| Tujuan utama | Menyembunyikan identitas client | Menyembunyikan server backend |
| Konfigurasi | Di sisi client | Di sisi server |
| Contoh penggunaan | VPN, web filter kantor | Load balancer, SSL offloading |
| Arah request | Client â Proxy â Internet | Client â Proxy â Backend Server |
Mengapa Reverse Proxy Penting untuk IoT?
Ketika kamu membangun sistem IoT dengan dashboard web, API server, atau MQTT broker, reverse proxy memberikan banyak keuntungan:
- SSL Termination â Satu sertifikat SSL di proxy, tidak perlu di setiap backend
- Load Balancing â Distribusi traffic ke beberapa server agar tidak overload
- Keamanan â Backend server tidak terekspos langsung ke internet
- Caching â Response statis disimpan di proxy sehingga backend tidak terbebani
- Kompressi â Gzip/Brotli compression untuk mempercepat transfer data
- Single Entry Point â Semua layanan (API, dashboard, MQTT WebSocket) di satu domain
Smart Farming Dashboard: Kamu punya API server Node.js di port 3000 dan Grafana dashboard di port 3000. Dengan Nginx reverse proxy, kamu bisa mengakses keduanya dari satu domain â api.smartfarm.com dan dashboard.smartfarm.com â dengan SSL otomatis dan keamanan yang ketat.
Client (Browser/ESP32)
â
âŒ
âââââââââââââââââââââââ
â Nginx (Port 80/443)â
â Reverse Proxy â
â SSL Termination â
â Rate Limiting â
â Caching â
ââââââââ¬âââââââ¬âââââââââ
â â
ââââââ ââââââ
⌠âŒ
ââââââââââ ââââââââââââ
â Node.jsâ â Grafana â
â API â â Dashboard â
â :3000 â â :3000 â
ââââââââââ ââââââââââââ
2. Instalasi Nginx
Nginx tersedia di hampir semua distribusi Linux. Berikut cara instalasi di berbagai platform:
Instalasi di Ubuntu/Debian
# Update repository sudo apt update # Instalasi Nginx sudo apt install -y nginx # Verifikasi instalasi nginx -v # Output: nginx version: nginx/1.24.0 (Ubuntu) # Jalankan dan enable saat boot sudo systemctl start nginx sudo systemctl enable nginx # Cek status sudo systemctl status nginx
Instalasi di CentOS/RHEL
# Tambah repository Nginx sudo yum install -y epel-release sudo yum install -y nginx # Jalankan service sudo systemctl start nginx sudo systemctl enable nginx
Instalasi dengan Docker
docker run -d \ --name nginx-proxy \ -p 80:80 \ -p 443:443 \ -v ./nginx.conf:/etc/nginx/nginx.conf:ro \ -v ./certs:/etc/nginx/certs:ro \ -v ./conf.d:/etc/nginx/conf.d:ro \ nginx:latest
Struktur Direktori Nginx
# Struktur direktori Nginx di Ubuntu/Debian: /etc/nginx/ âââ nginx.conf # Konfigurasi utama âââ conf.d/ # Konfigurasi tambahan âââ sites-available/ # Virtual host tersedia âââ sites-enabled/ # Virtual host aktif (symlink) âââ mime.types # Tipe MIME âââ modules-enabled/ # Modul aktif # Log: /var/log/nginx/ âââ access.log # Log akses âââ error.log # Log error
Setelah instalasi, buka browser dan akses http://YOUR_SERVER_IP. Kamu akan melihat halaman selamat datang Nginx.
Pastikan port 80 dan 443 dibuka di firewall. Untuk UFW: sudo ufw allow 'Nginx Full'. Untuk iptables: sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT dan sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT.
3. Konfigurasi Reverse Proxy Dasar
Konfigurasi Nginx menggunakan blok server yang mendefinisikan bagaimana Nginx menangani request. Setiap blok server mendengarkan di port tertentu dan meneruskan request ke backend.
Contoh Konfigurasi Sederhana
server {
listen 80;
server_name api.iotkamu.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Penjelasan direktif penting:
| Direktif | Fungsi |
|---|---|
proxy_pass | Alamat backend yang dituju (bisa IP:port atau upstream) |
proxy_http_version | Versi HTTP yang digunakan (1.1 mendukung keep-alive) |
proxy_set_header Host | Meneruskan header Host asli dari client |
X-Real-IP | IP asli client (bukan IP proxy) |
X-Forwarded-For | Daftar IP yang dilalui request |
X-Forwarded-Proto | Protokol asli (http/https) dari client |
Upgrade & Connection | Mendukung WebSocket (penting untuk IoT real-time) |
Aktifkan Konfigurasi
# Buat symlink ke sites-enabled sudo ln -s /etc/nginx/sites-available/iot-api /etc/nginx/sites-enabled/ # Hapus default site (opsional) sudo rm /etc/nginx/sites-enabled/default # Test konfigurasi syntax sudo nginx -t # Output: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok # Output: nginx: configuration file /etc/nginx/nginx.conf test is successful # Reload Nginx (tanpa memutus koneksi yang sedang berjalan) sudo systemctl reload nginx
Multiple Backend dengan Location
server {
listen 80;
server_name iotkamu.com;
# API Server
location /api/ {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Grafana Dashboard
location /dashboard/ {
proxy_pass http://127.0.0.1:3001/;
proxy_set_header Host $host;
}
# Grafana WebSocket
location /dashboard/api/live/ {
proxy_pass http://127.0.0.1:3001/api/live/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# Static files
location /public/ {
alias /var/www/iot/public/;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
Perhatikan perbedaan antara proxy_pass http://127.0.0.1:3000/ (dengan trailing slash) dan tanpa trailing slash. Dengan trailing slash, path /api/users akan diteruskan ke /users di backend. Tanpa trailing slash, path tetap /api/users.
4. SSL Termination dengan Let's Encrypt
SSL Termination berarti proses enkripsi/dekripsi HTTPS dilakukan di Nginx, bukan di backend server. Backend server cukup berjalan di HTTP biasa di jaringan internal. Ini mengurangi beban CPU di server aplikasi.
Instalasi Certbot
# Instalasi Certbot dan plugin Nginx sudo apt install -y certbot python3-certbot-nginx # Dapatkan sertifikat SSL (otomatis mengubah konfigurasi Nginx) sudo certbot --nginx -d api.iotkamu.com -d dashboard.iotkamu.com # Atau tanpa auto-config Nginx: sudo certbot certonly --nginx -d api.iotkamu.com
Konfigurasi Nginx dengan SSL
# Redirect HTTP ke HTTPS
server {
listen 80;
server_name api.iotkamu.com;
return 301 https://$host$request_uri;
}
# HTTPS Server
server {
listen 443 ssl http2;
server_name api.iotkamu.com;
# Sertifikat SSL
ssl_certificate /etc/letsencrypt/live/api.iotkamu.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.iotkamu.com/privkey.pem;
# SSL Security Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS - Paksa browser menggunakan HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
}
Auto-Renewal SSL
# Cek renewal berjalan sudo certbot renew --dry-run # Tambahkan cron job untuk auto-renewal (biasanya sudah terpasang otomatis) sudo crontab -e # Tambahkan baris berikut: 0 3 * * * certbot renew --quiet --post-hook "systemctl reload nginx"
5. Load Balancing: Round-Robin & Least Connections
Ketika aplikasi IoT kamu mulai menerima banyak traffic dari ribuan device, satu server tidak lagi cukup. Load balancing mendistribusikan request ke beberapa backend server sehingga beban merata.
Definisi Upstream
upstream iot_api_servers {
# Round-Robin (default) - request didistribusikan bergantian
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
server {
listen 443 ssl;
server_name api.iotkamu.com;
# ... SSL config ...
location / {
proxy_pass http://iot_api_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Metode Load Balancing
Nginx mendukung beberapa metode load balancing:
# Round-Robin: Request didistribusikan secara bergantian
# Request 1 â Server A
# Request 2 â Server B
# Request 3 â Server C
# Request 4 â Server A (ulang)
upstream backend_roundrobin {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
# Least Connections: Request dikirim ke server dengan koneksi paling sedikit
# Cocok untuk IoT di mana request durasinya bervariasi
# Misalnya upload data sensor lama vs request API cepat
upstream backend_leastconn {
least_conn;
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
# IP Hash: IP yang sama selalu dikirim ke server yang sama
# Cocok untuk WebSocket persistent connection dari device IoT
upstream backend_iphash {
ip_hash;
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
Weight & Health Check
upstream backend_weighted {
least_conn;
# Server utama: menerima 70% traffic
server 192.168.1.10:3000 weight=7;
# Server secondary: menerima 20% traffic
server 192.168.1.11:3000 weight=2;
# Server backup: menerima 10% traffic, aktif hanya jika server lain down
server 192.168.1.12:3000 weight=1 backup;
# Jika server gagal 3x berturut-turut, nonaktifkan selama 30 detik
server 192.168.1.10:3000 max_fails=3 fail_timeout=30s;
}
| Metode | Cara Kerja | Cocok Untuk |
|---|---|---|
| Round-Robin | Bergantian ke setiap server | Traffic merata, request seragam |
| Least Connections | Ke server dengan koneksi paling sedikit | Durasi request bervariasi |
| IP Hash | IP yang sama â server yang sama | WebSocket, sticky session |
| Weight | Proporsional sesuai bobot yang ditetapkan | Server dengan kapasitas berbeda |
6. Caching untuk Performa Optimal
Caching menyimpan response di Nginx sehingga request berikutnya tidak perlu ke backend. Ini sangat berguna untuk data IoT yang sering diakses tapi jarang berubah, seperti konfigurasi device atau data historis.
# Di blok http {} di nginx.conf
# Definisikan zone cache
proxy_cache_path /var/cache/nginx/iot_cache
levels=1:2
keys_zone=iot_cache:10m # 10MB untuk metadata cache
max_size=1g # Maksimal 1GB disk untuk cache
inactive=60m # Hapus cache jika tidak diakses 60 menit
use_temp_path=off;
server {
listen 443 ssl;
server_name api.iotkamu.com;
# Cache untuk API sensor data (tidak berubah setelah ditulis)
location /api/sensors/ {
proxy_pass http://iot_api_servers;
# Aktifkan cache
proxy_cache iot_cache;
proxy_cache_valid 200 5m; # Cache response 200 selama 5 menit
proxy_cache_valid 404 1m; # Cache response 404 selama 1 menit
proxy_cache_use_stale error timeout updating;
proxy_cache_lock on;
# Header X-Cache-Status untuk debugging (HIT, MISS, BYPASS)
add_header X-Cache-Status $upstream_cache_status;
}
# Tidak cache untuk endpoint real-time
location /api/realtime/ {
proxy_pass http://iot_api_servers;
proxy_cache off;
}
}
Gzip Compression
# Di blok http {} - mengurangi ukuran response hingga 70%
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript
image/svg+xml;
gzip_min_length 256;
7. Rate Limiting untuk Keamanan
Rate limiting membatasi jumlah request dari satu IP dalam periode waktu tertentu. Ini sangat penting untuk API IoT agar tidak diserang oleh brute force atau DDoS dari device yang terkompromi.
# Di blok http {}
# Rate limit zone: 10 request per detik per IP (10MB shared memory)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
# Rate limit zone untuk login: 5 request per menit per IP
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=5r/m;
server {
listen 443 ssl;
server_name api.iotkamu.com;
# API endpoint: 10 req/detik, burst 20 tanpa delay
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_req_status 429;
proxy_pass http://iot_api_servers;
proxy_set_header X-Real-IP $remote_addr;
}
# Login endpoint: 5 req/menit (anti brute force)
location /api/auth/login {
limit_req zone=login_limit burst=3 nodelay;
limit_req_status 429;
proxy_pass http://iot_api_servers;
}
}
Penjelasan parameter:
rate=10r/sâ Maksimal 10 request per detik per IPburst=20â Izinkan hingga 20 request sekaligus (untuk traffic spike)nodelayâ Jangan tunda request burst, langsung proseslimit_req_status 429â HTTP status code saat limit terlewati
Jika semua device IoT kamu berada di belakang NAT (satu IP publik), rate limiting per IP bisa memblokir device yang sah. Pertimbangkan untuk menggunakan API key per device di backend, atau whitelist IP tertentu dengan geo module Nginx.
8. Security Headers
Security headers adalah HTTP header yang ditambahkan oleh Nginx untuk melindungi aplikasi dari serangan web umum seperti XSS, clickjacking, dan MIME sniffing.
server {
listen 443 ssl http2;
server_name api.iotkamu.com;
# 1. X-Frame-Options: Cegah clickjacking
add_header X-Frame-Options "SAMEORIGIN" always;
# 2. X-Content-Type-Options: Cegah MIME sniffing
add_header X-Content-Type-Options "nosniff" always;
# 3. X-XSS-Protection: Aktifkan XSS filter di browser
add_header X-XSS-Protection "1; mode=block" always;
# 4. Referrer-Policy: Kontrol informasi referrer
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 5. Content-Security-Policy: Batasi sumber konten yang diizinkan
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' wss:" always;
# 6. Permissions-Policy: Nonaktifkan fitur browser yang tidak perlu
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(self)" always;
# 7. HSTS: Paksa browser menggunakan HTTPS selama 1 tahun
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
# ... proxy_pass config ...
}
| Header | Fungsi | Serangan yang Dicegah |
|---|---|---|
| X-Frame-Options | Mencegah halaman dimuat dalam iframe | Clickjacking |
| X-Content-Type-Options | Mencegah browser menebak tipe konten | MIME Sniffing |
| X-XSS-Protection | Mengaktifkan filter XSS browser | Cross-Site Scripting |
| Content-Security-Policy | Membatasi sumber konten yang diizinkan | XSS, Data Injection |
| Referrer-Policy | Mengontrol informasi referrer | Information Leakage |
| HSTS | Memaksa koneksi HTTPS | SSL Strip Attack |
| Permissions-Policy | Membatasi fitur browser (kamera, mic, dll) | Unauthorized Access |
Setelah menerapkan konfigurasi di atas, cek skor keamanan di https://securityheaders.com. Masukkan domain kamu dan pastikan mendapat skor A atau A+. Perbaiki header yang masih kurang sesuai rekomendasi.
9. Quiz: Uji Pemahamanmu!
Setelah membaca tutorial di atas, jawablah 5 pertanyaan berikut untuk menguji pemahamanmu tentang Nginx Reverse Proxy: