Skip to content

Nginx Reverse Proxy to Self(反向代理回自身)

同一台機器上以兩個 Nginx server block 分離外部入口與內部應用邏輯,透過 Host header 改寫實現路由。

概述

「Reverse Proxy to Self」是一種 Nginx 部署模式:在同一台機器上運行一個對外開放的 Proxy Server,以及一個只接受本機連線的 Backend Server。Proxy 接收外部請求後,改寫 Host header 並轉發至 127.0.0.1,讓 Nginx 依 server_name 匹配到 Backend block。

這個模式常見於:

  • 同一個 Nginx 實例需要同時處理 SSL 終止(外部 Proxy)和應用邏輯(內部 Backend)
  • 搭配 OpenResty / lua-nginx-module:Proxy 處理 TLS,Backend 執行 Lua 業務邏輯
  • 需要在不同的 server block 上套用不同的 header 處理或 middleware

核心內容

架構設計

角色server_name監聽埠可存取來源
外部入口(Proxy)mywebsite.com80 / 443 ssl任何人
內部處理(Backend)mywebsite.local80127.0.0.1

兩個 server block 的串接靠 Host header 完成:Proxy 將 Host 改寫為 mywebsite.local,Nginx 在收到轉發請求時依 server_name 匹配到 Backend block。

Proxy Server:外部入口設定

nginx
server {
    server_name mywebsite.com;
    listen 80;
    listen 443 ssl;

    location / {
        proxy_pass http://127.0.0.1:80;
        proxy_set_header Host mywebsite.local;

        # 保留原始請求資訊供後端判斷
        proxy_set_header X-Original-Host $http_host;
        proxy_set_header X-Original-Scheme $scheme;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

關鍵設定說明:

  • proxy_pass http://127.0.0.1:80:將請求轉回本機 port 80
  • proxy_set_header Host mywebsite.local:觸發 Backend server_name 匹配的核心
  • X-Original-* headers:保留真實的主機名、協定、來源 IP,讓後端應用能正確判斷請求來源

Backend Server:內部應用設定

nginx
server {
    server_name mywebsite.local;
    listen 80;

    # 安全屏障:僅接受本機連線
    allow 127.0.0.1;
    deny all;

    location / {
        # 在此執行應用邏輯(Lua、FastCGI、uWSGI 等)
        content_by_lua_block {
            -- ...
        };
    }
}

關鍵設定說明:

  • server_name mywebsite.local:必須與 Proxy 的 proxy_set_header Host 嚴格一致,否則路由失敗
  • allow 127.0.0.1; deny all;:防止外部繞過 Proxy 直接存取 Backend 的安全屏障,不可省略
  • content_by_lua_block:需要 OpenResty 或 lua-nginx-module;標準 Nginx 請替換為 fastcgi_passuwsgi_pass

請求流程

外部用戶
  → Proxy (mywebsite.com:443 ssl)
  → proxy_pass http://127.0.0.1:80
  → [Host header 改寫為 mywebsite.local]
  → Backend (mywebsite.local:80)
  → 執行應用邏輯
  → 回應逐層回傳至外部用戶

關鍵要點

  • Host header 是 Proxy 與 Backend 溝通的橋樑,兩側必須嚴格一致
  • Backend 的 allow 127.0.0.1; deny all; 是不可省略的安全設計
  • 此模式讓 SSL 終止與應用邏輯在同一個 Nginx 實例內分離,無需額外程序
  • content_by_lua_block 需要 OpenResty 或 lua-nginx-module,純 Nginx 需替換為其他 upstream 設定

實際應用

此模式與 MCP OAuth well-known Subpath Ingress 架構 有類似的設計哲學——都是利用 Nginx 的 server_name 路由,在同一個入口後端分發至不同處理邏輯,實現關切點分離。

適用情境:

  • OpenResty 應用同時需要 HTTPS 與 Lua 邏輯
  • 需要在同一機器上為同一域名設定多層 middleware
  • 測試環境模擬生產環境的反向代理架構

部署設定參考

以下為完整設定,供日後查詢與複製使用。

完整 Nginx 設定(Proxy + Backend)

nginx
# ── 外部入口(Proxy Server)──────────────────────────
server {
    server_name mywebsite.com;
    listen 80;
    listen 443 ssl;

    location / {
        proxy_pass http://127.0.0.1:80;
        proxy_set_header Host mywebsite.local;

        proxy_set_header X-Original-Host $http_host;
        proxy_set_header X-Original-Scheme $scheme;
        proxy_set_header X-Forwarded-For $remote_addr;
    }
}

# ── 內部處理(Backend Server)────────────────────────
server {
    server_name mywebsite.local;
    listen 80;

    allow 127.0.0.1;
    deny all;

    location / {
        content_by_lua_block {
            -- 在此實作應用邏輯
        };
    }
}

相關概念

來源