Reverse Proxy pada sistem operasi Linux bertindak sebagai penghubung antara host (client) dan server.
Reverse proxy membawa request client dan menyalurkannya ke server lain. Begitu juga sebaliknya, Respon dari server akan disalurkan ke client melalui proxy server.
Install Nginx #
sudo apt install nginx
Pastikan service nginx aktif dan running
systemctl enable --now nginx
systemctl status nginx
Disable default VHost #
Setelah nginx terinstall. Selanjutnya disable default virtualhost
sudo unlink /etc/nginx/sites-enabled/default
Setting Reverse Proxy #
Buat file reverse-proxy.conf
sudo nano /etc/nginx/sites-available/reverse-proxy.conf
Lalu tambahkan baris berikut
server {
listen 80;
listen [::]:80;
location / {
proxy_pass http://app;
health_check;
proxy_hide_header 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;
proxy_set_header X-Accel-Internal /internal-nginx-static-location;
access_log off;
}
# opsional, dapat ditambahkan apabila Anda menginstall nginx dan apache pada server yang sama
location ^~ /internal-nginx-static-location/ {
alias /home/web1/public_html/;
internal;
}
}
# Backend server configuration
upstream app {
server 10.10.10.100:8090;
server 10.10.10.101:8090;
}
Atau Anda dapat membuat konfigurasinya seperti berikut.
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;
}
}
Lalu buat file /etc/nginx/proxy_params
dan tambahkan baris berikut.
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;
Selanjutnya agar file konfig reverse-proxy.conf dapat aktif maka perlu membuat symbolic links ke tujaun folder sites-enabled
sudo ln -s /etc/nginx/sites-available/reverse-proxy.conf /etc/nginx/sites-enabled/reverse-proxy.conf
Proxy + Cache #
Langkah ini opsional dan dapat Anda ikuti apabila ingin menggunakan Nginx Cache.
Tambahkan baris berikut pada file nginx.conf
untuk mengonfigurasi nginx cache
## 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];
Dapat Anda sesuaikan lagi bila diperlukan.
Selanjutnya konfigurasi proxy dengan menambahkan beberapa file berikut.
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;
nano /etc/nginx/proxy_params_dynamic
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;
nano /etc/nginx/proxy_params_static
# 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;
nano /etc/nginx/common_http.conf
# 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;
}
Untuk konfigurasi virtualhost seperti berikut.
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;
}
Buat file custom_rules
untuk konfigurasi proxy apabila Anda membangun aplikasi dengan NodeJS atau sejenisnya dari server yang sama ataupun server lain.
nano /etc/nginx/custom_rules
# EXAMPLE
#
# set $PROXY_DOMAIN_OR_IP "XXX.XXX.XXX.XXX";
#
#
# if ($host ~ "example.com") {
# set $PROXY_DOMAIN_OR_IP "XXX.XXX.XXX.XXX";
# }
#
#
# if ($host ~ "mynodeapp.com") {
# set $PROXY_SCHEME "http";
# set $PROXY_TO_PORT 3000;
# }
#
#
# if ($SITE_URI ~* "example.com|example2.com/path|example3.com/some/other/path|subdomain.example4.com") {
# set $CACHE_BYPASS_FOR_DYNAMIC 1; # Disables micro-caching
# set $CACHE_BYPASS_FOR_STATIC 1; # Disables static file caching
# }
Get original visitor IPs #
Jika memakai proxy, maka IP pengakses yang akan muncul di access_log adalah IP dari server proxy tersebut. Jadi untuk mendapatkan real IP visitor maka perlu menambahkan konfiguruasi remoteip pada sisi webserver backend (Apache/HTTPD)
Buat file remoteip.conf
lalu tambahkan konfigurasi berikut.
/etc/httpd/conf.d/remoteip.conf
<IfModule mod_remoteip.c>
RemoteIPInternalProxy XX.XX.XX.XX
RemoteIPHeader X-Forwarded-For
</IfModule>
Selanjutnya edit LogFormat pada file httpd.conf
menjadi
LogFormat "%a %l %u %t \"%r\" %>s %b" common
Restart service Apache
systemctl restart httpd
Test #
Test konfig nginx dengan perintah berikut.
sudo nginx -t
Jika outputnya test is successful
. Selanjutnya reload nginx
sudo nginx -s reload
Purge cache #
Untuk menghapus cache gunakan script berikut
#!/usr/bin/env bash
find /var/cache/nginx/dynamic -type f -exec rm {} \;
find /var/cache/nginx/static -type f -exec rm {} \;
find /var/cache/nginx/temp -type f -exec rm {} \;
systemctl restart nginx
Referensi: