Proxy Headers

Proxy Headers #

Ketika Nginx meneruskan request ke backend, ia tidak sekadar memforward semua header begitu saja. Ada header yang diubah, ada yang dihapus, dan ada yang perlu ditambahkan secara eksplisit. Memahami perilaku default ini — dan cara mengontrolnya — penting untuk memastikan backend mendapatkan informasi yang ia butuhkan.

Apa yang Terjadi dengan Header Secara Default #

Saat Nginx meneruskan request ke upstream, ada beberapa modifikasi default:

Header yang DIHAPUS secara default:
  - Header dengan underscore (di-nonaktifkan, bisa diaktifkan kembali)
  - Header "Connection" (hop-by-hop header)
  - Header "Keep-Alive"
  - Header "Transfer-Encoding" (dalam beberapa kondisi)

Header yang DIUBAH secara default:
  - "Host" → diubah ke nama server upstream (bukan domain asli klien)

Header yang DITERUSKAN apa adanya:
  - Semua header request lainnya yang tidak masuk kategori di atas

Implikasinya: backend secara default tidak tahu IP asli klien, tidak tahu domain yang diakses klien, dan tidak tahu apakah koneksi asal HTTP atau HTTPS — kecuali kamu secara eksplisit menambahkan header ini.


proxy_set_header: Menambah atau Mengubah Header Request #

Directive ini menambahkan atau menimpa header yang dikirim ke backend:

location / {
    proxy_pass http://backend;

    # Kirim IP asli klien
    proxy_set_header X-Real-IP $remote_addr;

    # Kirim chain IP jika ada proxy sebelum Nginx
    # $proxy_add_x_forwarded_for menggabungkan IP klien dengan
    # header X-Forwarded-For yang sudah ada (jika ada)
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # Kirim skema koneksi asal (http/https)
    proxy_set_header X-Forwarded-Proto $scheme;

    # Pertahankan header Host asli dari klien
    proxy_set_header Host $host;
    # atau $http_host jika butuh port juga: example.com:8080
}

Hapus header yang tidak perlu dikirim ke backend #

location / {
    proxy_pass http://backend;

    # Hapus header Authorization sebelum dikirim ke backend tertentu
    proxy_set_header Authorization "";

    # Hapus header Cookie agar backend tidak terima cookie klien
    proxy_set_header Cookie "";
}

Memberikan nilai kosong ("") pada proxy_set_header berarti header tersebut dihapus dari request ke backend.


Header untuk Kebutuhan Umum: Snippet #

Karena set header proxy yang sama sering digunakan di banyak location, praktik terbaik adalah menaruhnya di snippet:

# /etc/nginx/snippets/proxy-headers.conf
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;
proxy_set_header X-Forwarded-Host   $host;
proxy_set_header X-Forwarded-Port   $server_port;
proxy_http_version 1.1;
proxy_set_header Connection         "";

Lalu gunakan di mana dibutuhkan:

location / {
    proxy_pass http://backend;
    include snippets/proxy-headers.conf;
}

proxy_hide_header: Menyembunyikan Header dari Response Backend #

Secara default Nginx meneruskan semua header dari backend ke klien. Gunakan proxy_hide_header untuk mencegah header tertentu sampai ke klien:

location / {
    proxy_pass http://backend;

    # Sembunyikan header internal yang tidak perlu diketahui klien
    proxy_hide_header X-Powered-By;
    proxy_hide_header X-Runtime;
    proxy_hide_header X-Request-Id;
    proxy_hide_header Server;
}

X-Powered-By khususnya sering mengekspos teknologi backend (“PHP/8.1”, “Express”) — menyembunyikannya adalah praktik keamanan sederhana tapi efektif.


proxy_pass_header: Meneruskan Header yang Biasanya Diblokir #

Ada header tertentu yang Nginx blokir secara default. Gunakan proxy_pass_header untuk meneruskannya:

location / {
    proxy_pass http://backend;

    # Izinkan header Date dari backend melalui
    # (biasanya Nginx override header Date)
    proxy_pass_header Date;

    # Izinkan header Server dari backend melalui
    # (berguna jika kamu ingin custom Server header dari backend)
    proxy_pass_header Server;
}

add_header: Menambah Header ke Response #

add_header menambahkan header ke response yang dikirim ke klien — bukan ke backend:

server {
    location / {
        proxy_pass http://backend;

        # Header keamanan penting
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header Referrer-Policy "strict-origin-when-cross-origin" always;
    }
}

Parameter always memastikan header ditambahkan bahkan untuk response error (4xx, 5xx) — tanpanya, header hanya ditambahkan untuk response 2xx dan 3xx.


Inheritance add_header: Jebakan yang Sering Terjadi #

add_header memiliki perilaku inheritance yang tidak intuitif: jika sebuah context mendefinisikan add_header, ia tidak mewarisi add_header dari parent context-nya.

server {
    # Security headers di level server
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;

    location /api/ {
        # Menambahkan add_header di sini membuat dua header di atas
        # TIDAK diwarisi untuk location ini!
        add_header Cache-Control "no-store";
        proxy_pass http://api_backend;
    }

    # Hanya location yang tidak mendefinisikan add_header sendiri
    # yang mewarisi dari server block
    location / {
        # X-Frame-Options dan X-Content-Type-Options diwarisi ✓
        proxy_pass http://main_backend;
    }
}

Solusinya: definisikan semua header yang dibutuhkan secara lengkap di setiap context yang menggunakan add_header, atau gunakan snippet:

# /etc/nginx/snippets/security-headers.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Di konfigurasi:
location /api/ {
    include snippets/security-headers.conf;
    add_header Cache-Control "no-store" always;
    proxy_pass http://api_backend;
}

Ringkasan #

  • Secara default Nginx mengubah Host dan menghapus beberapa header — backend tidak otomatis tahu IP klien asli atau skema koneksi.
  • Gunakan proxy_set_header untuk menambah/mengubah header request ke backend; nilai "" untuk menghapus header.
  • proxy_hide_header X-Powered-By — sembunyikan header yang mengekspos teknologi backend.
  • add_header menambahkan header ke response klien; selalu gunakan parameter always agar berlaku untuk semua kode status.
  • Jebakan inheritance add_header: jika location mendefinisikan add_header sendiri, ia tidak mewarisi add_header dari parent — gunakan snippet untuk konsistensi.

← Sebelumnya: proxy_pass   Berikutnya: Buffer & Timeout →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact