Dashboard & Cloud

Nginx Reverse Proxy: Load Balancing & SSL Termination

TOKEN

Tutorial komprehensif membangun reverse proxy menggunakan Nginx untuk aplikasi IoT — dari konfigurasi dasar hingga load balancing, SSL, caching, dan keamanan lanjutan

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 dilayaniClientServer
Tujuan utamaMenyembunyikan identitas clientMenyembunyikan server backend
KonfigurasiDi sisi clientDi sisi server
Contoh penggunaanVPN, web filter kantorLoad balancer, SSL offloading
Arah requestClient → Proxy → InternetClient → 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:

💡 Contoh Use Case IoT

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.

Diagram: Arsitektur Nginx Reverse Proxy
  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

Terminal — Instalasi Nginx 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

Terminal — Instalasi Nginx 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

Terminal — Jalankan Nginx via 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

Terminal — Struktur File 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.

⚠ Firewall

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

Nginx — /etc/nginx/sites-available/iot-api
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_passAlamat backend yang dituju (bisa IP:port atau upstream)
proxy_http_versionVersi HTTP yang digunakan (1.1 mendukung keep-alive)
proxy_set_header HostMeneruskan header Host asli dari client
X-Real-IPIP asli client (bukan IP proxy)
X-Forwarded-ForDaftar IP yang dilalui request
X-Forwarded-ProtoProtokol asli (http/https) dari client
Upgrade & ConnectionMendukung WebSocket (penting untuk IoT real-time)

Aktifkan Konfigurasi

Terminal — Aktifkan Virtual Host
# 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

Nginx — Multi-Location Reverse Proxy
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";
    }
}
💡 Tips: Trailing Slash

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

Terminal — 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

Nginx — Konfigurasi SSL Lengkap
# 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

Terminal — Auto-Renewal Let's Encrypt
# 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

Nginx — Definisi Upstream Server
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:

Nginx — Round-Robin (Default)
# 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;
}
Nginx — Least Connections
# 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;
}
Nginx — IP Hash (Sticky Sessions)
# 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

Nginx — Weight & Failover
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-RobinBergantian ke setiap serverTraffic merata, request seragam
Least ConnectionsKe server dengan koneksi paling sedikitDurasi request bervariasi
IP HashIP yang sama → server yang samaWebSocket, sticky session
WeightProporsional sesuai bobot yang ditetapkanServer 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.

Nginx — Konfigurasi Proxy Cache
# 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

Nginx — 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.

Nginx — Konfigurasi Rate Limiting
# 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:

⚠ Device IoT dengan IP Sama

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.

Nginx — Security Headers Lengkap
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-OptionsMencegah halaman dimuat dalam iframeClickjacking
X-Content-Type-OptionsMencegah browser menebak tipe kontenMIME Sniffing
X-XSS-ProtectionMengaktifkan filter XSS browserCross-Site Scripting
Content-Security-PolicyMembatasi sumber konten yang diizinkanXSS, Data Injection
Referrer-PolicyMengontrol informasi referrerInformation Leakage
HSTSMemaksa koneksi HTTPSSSL Strip Attack
Permissions-PolicyMembatasi fitur browser (kamera, mic, dll)Unauthorized Access
💡 Cek Security Headers

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:

Pertanyaan 1: Apa perbedaan utama antara forward proxy dan reverse proxy?

a) Forward proxy melindungi server, reverse proxy melindungi client
b) Forward proxy melindungi client, reverse proxy melindungi server
c) Keduanya sama, hanya nama berbeda
d) Forward proxy untuk HTTP, reverse proxy untuk HTTPS

Pertanyaan 2: Apa fungsi dari SSL termination di Nginx?

a) Menghapus semua koneksi SSL
b) Memproses enkripsi/dekripsi HTTPS di Nginx sehingga backend cukup HTTP
c) Mengenkripsi data di database
d) Membuat SSL certificate secara otomatis

Pertanyaan 3: Metode load balancing mana yang paling cocok untuk WebSocket persistent connection dari device IoT?

a) Round-Robin
b) Least Connections
c) IP Hash
d) Random

Pertanyaan 4: Apa fungsi dari direktif proxy_cache_valid 200 5m?

a) Menghapus cache setiap 5 menit
b) Menyimpan response dengan status 200 selama 5 menit
c) Membatasi request hanya 5 per menit
d) Mengatur timeout koneksi 5 menit

Pertanyaan 5: Security header apa yang mencegah serangan clickjacking?

a) Content-Security-Policy
b) X-Content-Type-Options
c) X-Frame-Options
d) Strict-Transport-Security
← Sebelumnya Grafana + InfluxDB Selanjutnya → Firebase Auth & Firestore