Skip to main content
  1. Posts/

Reverse Proxy dengan Nginx

·7 mins·
nginx linux nginx
Table of Contents

Reverse Proxy berfungsi sebagai perantara antara client dan server backend. Client hanya berinteraksi dengan proxy, sementara proxy yang meneruskan request ke server tujuan lalu mengembalikan respons ke client.

Instalasi Nginx
#

Jalankan perintah berikut untuk menginstal Nginx:

sudo apt update
sudo apt install nginx -y

Pastikan service nginx berjalan otomatis dan dalam keadaan aktif:

sudo systemctl enable --now nginx
sudo systemctl status nginx

Menonaktifkan Virtual Host Default
#

Setelah Nginx terpasang, nonaktifkan konfigurasi virtual host bawaan:

sudo unlink /etc/nginx/sites-enabled/default

Konfigurasi Reverse Proxy
#

Buat file baru bernama reverse-proxy.conf:

sudo nano /etc/nginx/sites-available/reverse-proxy.conf

Tambahkan konfigurasi berikut (contoh dengan upstream server):

server {
    listen 80;
    listen [::]:80;

    location / {
        proxy_pass http://app;
        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-Accel-Internal /internal-nginx-static-location;
        proxy_hide_header Upgrade;
        access_log off;
    }

    # Opsional: jika Nginx dan Apache berjalan pada server yang sama
    location ^~ /internal-nginx-static-location/ {
        alias /home/web1/public_html/;
        internal;
    }
}

# Backend server configuration (upstream)
upstream app {
    server 10.10.10.100:8090;
    server 10.10.10.101:8090;
}

Alternatif Konfigurasi Sederhana (Per Domain)
#

Jika ingin proxy langsung ke satu server backend:

server {
    server_name example.com;

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;

    add_header X-Proxy-Cache $upstream_cache_status;

    location / {
        proxy_pass http://10.10.10.10:80;
        proxy_redirect off;
        include proxy_params;
    }
}

Buat file /etc/nginx/proxy_params untuk menyimpan parameter standar proxy:

proxy_set_header Host              $http_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;

Aktifkan Konfigurasi Reverse Proxy
#

Agar konfigurasi aktif, buat symbolic link ke folder sites-enabled:

sudo ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/

Cek apakah konfigurasi valid:

sudo nginx -t

Jika valid, reload Nginx:

sudo systemctl reload nginx

Proxy + Cache
#

Fitur cache ini opsional. Jika tidak dibutuhkan, Anda bisa lewati bagian ini.

1. Tambahkan Konfigurasi Cache di nginx.conf
#

Edit file nginx.conf lalu tambahkan baris berikut pada blok http { ... }:

    ## Real IP Forwarding ##
    set_real_ip_from 127.0.0.1;

    # Private IPs
    set_real_ip_from 192.168.1.0/24;
    set_real_ip_from 192.168.2.0/24;

    # Replace with correct visitor IP
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    # Proxy Cache Settings
    proxy_cache_path  /var/cache/nginx/dynamic  levels=1:2 keys_zone=dynamic:512m max_size=4g inactive=12h use_temp_path=off;
    proxy_cache_path  /var/cache/nginx/static   levels=1:2 keys_zone=static:512m  max_size=4g inactive=12h use_temp_path=off;
    proxy_temp_path   /var/cache/nginx/temp;

    # Info
    add_header        nginx-cache-status $upstream_cache_status;

    ## DNS Resolver ##
    resolver                       8.8.8.8 8.8.4.4 [2001:4860:4860::8888] [2001:4860:4860::8844];

2. Buat File Parameter Proxy
#

proxy_params_common

sudo nano /etc/nginx/proxy_params_common
# General Proxy Settings
proxy_pass                    $PROXY_SCHEME://$PROXY_DOMAIN_OR_IP:$PROXY_TO_PORT;
proxy_hide_header             Upgrade;
proxy_http_version            1.1;                # Always upgrade to HTTP/1.1
proxy_set_header              Accept-Encoding ""; # Optimize encoding
proxy_set_header              Connection "";      # Enable keepalives
proxy_set_header              Host $host;
proxy_set_header              Proxy "";
proxy_set_header              Referer $http_referer;
proxy_set_header              X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header              X-Forwarded-Host $PROXY_FORWARDED_HOST;
proxy_set_header              X-Forwarded-Port $server_port;
proxy_set_header              X-Forwarded-Proto $scheme;
proxy_set_header              X-Forwarded-Server $host;
proxy_set_header              X-Real-IP $remote_addr;
proxy_set_header              CF-Connecting-IP $http_cf_connecting_ip;
proxy_set_header              CF-Visitor $http_cf_visitor;

# Buffers
proxy_buffers                 256 16k;
proxy_buffer_size             128k;
proxy_busy_buffers_size       256k;
proxy_temp_file_write_size    256k;

# Timeouts
proxy_connect_timeout         300s;
proxy_read_timeout            300s;
proxy_send_timeout            300s;
send_timeout                  300s;

proxy_params_dynamic

sudo nano /etc/nginx/proxy_params_dynamic

Konfigurasi untuk konten dinamis (HTML, CMS, dll.) dengan aturan bypass cache:


set $EXPIRES_FOR_DYNAMIC 1m;

#############################################################################################

# Allow separate cache entries for mobile devices (smartphones & tables)
set $MOBILE "";
if ($http_user_agent ~* "(iPhone|iPod|iPad|Android|Mobile|Tablet)") {
    set $MOBILE "m_";
}

# CMS (& CMS extension) specific cookies (e.g. Joomla, K2 for Joomla, WordPress, WooCommerce, PrestaShop, Magento etc.)
if ($http_cookie ~* "(joomla_[a-zA-Z0-9_]+|userID|wordpress_(?!test_)[a-zA-Z0-9_]+|wp-postpass|comment_author_[a-zA-Z0-9_]+|woocommerce_cart_hash|woocommerce_items_in_cart|wp_woocommerce_session_[a-zA-Z0-9]+|wordpress_logged_in_[a-zA-Z0-9]+|sid_customer_|sid_admin_|PrestaShop-[a-zA-Z0-9]+|SESS[a-zA-Z0-9]+|SSESS[a-zA-Z0-9]+|NO_CACHE|external_no_cache|adminhtml|private_content_version)") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $EXPIRES_FOR_DYNAMIC 0;
}

# Invision Power Board (IPB) v3+
if ($cookie_member_id ~ "^[1-9][0-9]*$") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $EXPIRES_FOR_DYNAMIC 0;
}

# Invision Power Board (IPB) v4+
if ($cookie_ips4_member_id ~ "^[1-9][0-9]*$") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $EXPIRES_FOR_DYNAMIC 0;
}
if ($http_cookie ~ "ips4_IPSSessionFront") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $EXPIRES_FOR_DYNAMIC 0;
}

# Admin sections & generic entry points for CMSs (incl. Joomla, WordPress, phpBB, Drupal, Craft)
if ($request_uri ~* "(/administrator|com_user|com_users|com_contact|com_mailto|/component/user|/component/users|/component/contact|/component/mailto|/installation|/wp-admin|/wp-login.php|/cart|/my-account|/checkout|/wc-api|/addons|/lost-password|\?add-to-cart=|\?wc-api=|/ucp.php|^/status\.php|^/update\.php|^/install\.php|^/apc\.php$|^/apcu\.php$|^/admin|^/admin/.*$|^/user|^/user/.*$|^/users/.*$|^/info/.*$|^/flag/.*$|^.*/ajax/.*$|^.*/ahah/.*$|^/system/files/.*$|p=admin|/actions|/login|/logout|/connect|/signin|/signup|/register)") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $EXPIRES_FOR_DYNAMIC 0;
}

# Disable caching when the "Cache-Control" header is set to "private"
if ($http_cache_control ~* "private") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $EXPIRES_FOR_DYNAMIC 0;
}

# Proxy cache settings
proxy_no_cache                 $CACHE_BYPASS_FOR_DYNAMIC;
proxy_cache_bypass             $CACHE_BYPASS_FOR_DYNAMIC;

proxy_cache                    dynamic;
#proxy_cache_background_update on;
proxy_cache_key                "$MOBILE$scheme$host$request_uri";
proxy_cache_lock               on;
proxy_cache_methods            GET HEAD;
proxy_cache_use_stale          error timeout invalid_header updating http_429 http_500 http_502 http_503 http_504; # Additional options: http_403 http_404
proxy_cache_valid              200 1s;

# Ignore all headers but "Cache-Control" to determine whether to cache the upstream response or not
proxy_ignore_headers           Expires Set-Cookie Vary;

# Force client-side caching for dynamic content (commented by default)
# See "ADVANCED USERS ONLY" note at the top of this file
#expires                       $EXPIRES_FOR_DYNAMIC;
#proxy_hide_header             Cache-Control;
#proxy_hide_header             Expires;
#proxy_hide_header             Pragma;
#proxy_hide_header             Set-Cookie;
proxy_hide_header              Vary;

proxy_params_static

sudo nano /etc/nginx/proxy_params_static

Konfigurasi untuk file statis (CSS, JS, gambar, font, dll.):

# Admin sections for CMSs
if ($request_uri ~* "(/administrator|/wp-admin|/wp-login.php)") {
    set $CACHE_BYPASS_FOR_STATIC 1;
}

# Proxy cache settings
proxy_no_cache                 $CACHE_BYPASS_FOR_STATIC;
proxy_cache_bypass             $CACHE_BYPASS_FOR_STATIC;

proxy_cache                    static;
proxy_cache_background_update  on;
proxy_cache_key                "$host$request_uri";
proxy_cache_lock               on;
proxy_cache_methods            GET HEAD;
proxy_cache_min_uses           1;
proxy_cache_revalidate         on;
proxy_cache_use_stale          error timeout invalid_header updating http_429 http_500 http_502 http_503 http_504; # Additional options: http_403 http_404
proxy_cache_valid              200 10s;

# Allow rewriting HTTP headers for static assets
proxy_ignore_headers           Cache-Control Expires Set-Cookie Vary;
proxy_hide_header              Cache-Control;
proxy_hide_header              Expires;
proxy_hide_header              Pragma;
proxy_hide_header              Set-Cookie;
proxy_hide_header              Vary;

# Disable logging
access_log                     off;

common_http.conf

sudo nano /etc/nginx/common_http.conf

Konfigurasi umum untuk semua request:

# Common definitions for HTTP content

# Initialize important variables
set $CACHE_BYPASS_FOR_DYNAMIC 0;
set $CACHE_BYPASS_FOR_STATIC 0;
set $PROXY_DOMAIN_OR_IP $host;
set $PROXY_FORWARDED_HOST $host;
set $PROXY_SCHEME $scheme;
set $SITE_URI "$host$request_uri";

# Generic query string to request a page bypassing Nginx's caching entirely for both dynamic & static content
if ($query_string ~* "nocache") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $CACHE_BYPASS_FOR_STATIC 1;
}

# Proxy requests to "localhost"
if ($host ~* "localhost") {
    set $PROXY_DOMAIN_OR_IP "127.0.0.1";
}

# Disable caching for cPanel specific subdomains
if ($host ~* "^(webmail|cpanel|whm|webdisk|cpcalendars|cpcontacts)\.") {
    set $CACHE_BYPASS_FOR_DYNAMIC 1;
    set $CACHE_BYPASS_FOR_STATIC 1;
}

# Fix Horde webmail forwarding
if ($host ~* "^webmail\.") {
    set $PROXY_FORWARDED_HOST '';
}

# Set custom rules like domain/IP exclusions or redirects here
include custom_rules;

location / {
    try_files $uri $uri/ @backend;
}

location @backend {
    include proxy_params_common;
    # === MICRO CACHING ===
    # Comment the following line to disable 1 second micro-caching for dynamic HTML content
    include proxy_params_dynamic;
}

# Enable low duration browser cache for static data files (TTL is 1 min)
location ~* \.(?:csv|json|xml|rss|atom)$ {
    include proxy_params_common;
    include proxy_params_static;
    expires 1m;
}

# Enable browser cache for CSS / JS (TTL is 30 days)
location ~* \.(?:css|js)$ {
    include proxy_params_common;
    include proxy_params_static;
    expires 30d;
}

# Enable browser cache for images (TTL is 60 days)
location ~* \.(?:ico|jpg|jpeg|gif|png|webp)$ {
    include proxy_params_common;
    include proxy_params_static;
    expires 60d;
}

# Enable browser cache for fonts & fix @font-face cross-domain restriction (TTL is 60 days)
location ~* \.(eot|ttf|otf|woff|woff2|svg|svgz)$ {
    include proxy_params_common;
    include proxy_params_static;
    expires 60d;
}

# Prevent logging of favicon and robot request errors
location = /favicon.ico {
    include proxy_params_common;
    include proxy_params_static;
    expires 60d;
    log_not_found off;
}

location = /robots.txt  {
    include proxy_params_common;
    include proxy_params_static;
    expires 1d;
    log_not_found off;
}

# Deny access to files like .htaccess or .htpasswd
location ~ /\.ht {
    deny all;
}

3. Virtual Host dengan Cache
#

sudo nano /etc/nginx/conf.d/example.com.conf
server {
    listen 80;
    listen [::]:80;
    server_name example.com;

    set $PROXY_TO_PORT 8080;

    include common_http.conf;
}

4. Custom Rules (Opsional)
#

Jika ada aplikasi tambahan (misalnya Node.js di port 3000), tambahkan aturan di custom_rules:

sudo nano /etc/nginx/custom_rules
# Contoh custom rule

if ($host ~ "mynodeapp.com") {
    set $PROXY_SCHEME "http";
    set $PROXY_TO_PORT 3000;
}

5. Test Konfigurasi & Reload
#

Cek konfigurasi:

sudo nginx -t

Reload service:

sudo systemctl reload nginx

Get Original Visitor IP (Real IP) di Apache
#

Saat menggunakan proxy atau reverse proxy, IP yang tercatat di access_log backend (Apache/HTTPD) biasanya adalah IP dari proxy server, bukan IP asli visitor. Untuk mengatasinya, kita bisa menggunakan mod_remoteip agar Apache membaca header X-Forwarded-For.

1. Buat File Konfigurasi remoteip.conf
#

Buat file baru di /etc/httpd/conf.d/remoteip.conf:

sudo nano /etc/httpd/conf.d/remoteip.conf

Tambahkan konfigurasi berikut:

<IfModule mod_remoteip.c>
    RemoteIPInternalProxy XX.XX.XX.XX
    RemoteIPHeader X-Forwarded-For
</IfModule>
Ganti XX.XX.XX.XX dengan IP server proxy (Nginx) Anda.

2. Edit LogFormat di httpd.conf
#

Agar log menampilkan real IP visitor, ubah format log:

LogFormat "%a %l %u %t \"%r\" %>s %b" common

📌 Anda juga bisa mengubah semua LogFormat dari %h menjadi %a.

3. Restart Apache
#

Setelah konfigurasi selesai, restart service Apache:

sudo systemctl restart httpd

Purge Cache Nginx
#

Kadang kita perlu menghapus cache Nginx, misalnya setelah melakukan update aplikasi atau mengganti aset statis. Untuk melakukannya, Anda bisa menggunakan script berikut:

#!/usr/bin/env bash

# Hapus cache dynamic
find /var/cache/nginx/dynamic -type f -exec rm -f {} \;

# Hapus cache static
find /var/cache/nginx/static -type f -exec rm -f {} \;

# Hapus cache temp
find /var/cache/nginx/temp -type f -exec rm -f {} \;

# Restart service nginx
systemctl restart nginx

Simpan script ini dengan nama, misalnya:

sudo nano /usr/local/bin/nginx-purge-cache.sh

Kemudian beri permission agar bisa dieksekusi:

sudo chmod +x /usr/local/bin/nginx-purge-cache.sh

Sekarang Anda dapat menghapus cache Nginx dengan mudah:

sudo nginx-purge-cache.sh

Referensi:

Related

Install Uptime Kuma sebagai Monitoring
·2 mins
linux docker linux monitoring nodejs uptime kuma
Setting Shell variables Saat Menggunakan Sudo di Linux
·1 min
linux linux
Migrasi CentOS 8 ke Almalinux 8
·2 mins
linux linux
Setting Network Ubuntu dengan Netplan
·1 min
ubuntu ubuntu linux
Backup dan Restore Partisi table di Linux
·3 mins
linux linux
Cara membuat Logical Volume (LVM)
·3 mins
lvm linux lvm