Proxy 與 Reverse Proxy 完全解析:正向代理與反向代理 | Networking

2026/05/21 2026/05/16
Proxy 與 Reverse Proxy 完全解析:正向代理與反向代理 | Networking

Proxy 代理伺服器是網路中的中介節點,代替一方發送或接收請求。Forward Proxy 代替客戶端向伺服器發送請求;Reverse Proxy 代替伺服器接收客戶端請求。本文將從基礎概念出發,深入 Nginx 反向代理配置實戰,涵蓋 負載平衡SSL 終止WebSocket 代理、快取策略,並延伸至 API GatewayService MeshKubernetes Ingress 等現代架構應用。

什麼是 Proxy?

代理伺服器(Proxy Server) 是位於客戶端與伺服器之間的中間人。所有經過 Proxy 的流量都會先被代理處理,再轉發給目標。這個「中間人」的角色帶來了許多好處:快取加速、安全防護、匿名瀏覽、負載平衡等。

根據代理站在哪一方,可以分為兩大類:

  • 正向代理(Forward Proxy):代表客戶端,幫客戶端向伺服器發送請求
  • 反向代理(Reverse Proxy):代表伺服器,幫伺服器接收客戶端的請求

兩者核心原理都是「中間人」,但服務的對象與部署位置截然不同。


正向代理(Forward Proxy)

正向代理位於客戶端與伺服器之間,代表客戶端 發送請求。客戶端知道代理的存在,並主動配置使用代理;伺服器則不知道真實客戶端是誰。

正向代理(Forward Proxy)

                                    ┌─────────────┐
  ┌──────────┐    ┌───────────┐    │  Web Server  │
  │ Client A ├──→ │           │ ──→│  (google.com)│
  └──────────┘    │           │    └─────────────┘
                  │  Forward  │
  ┌──────────┐    │   Proxy   │    ┌─────────────┐
  │ Client B ├──→ │           │ ──→│  Web Server  │
  └──────────┘    │           │    │  (github.com)│
                  └───────────┘    └─────────────┘
  ← 內部網路 →    ← 代理伺服器 →   ← 外部網路 →

正向代理的常見用途

用途說明
匿名瀏覽隱藏客戶端真實 IP 位址
存取控制企業防火牆限制員工可存取的網站
內容過濾攔截惡意網站或不當內容
快取加速快取常用資源,減少頻寬消耗
突破地理限制透過其他地區的代理存取受限內容
日誌與監控記錄所有出站流量以供稽核

最經典的正向代理場景就是企業內網:公司透過 Squid 這類正向代理工具,統一管控員工的上網行為,同時快取常用網頁資源以節省頻寬。

常見正向代理工具

工具特點
Squid老牌高效能快取代理,支援 HTTP/HTTPS/FTP
Privoxy隱私導向,廣告過濾,常與 Tor 搭配
mitmproxy開發者工具,可攔截並修改 HTTPS 流量
Charles ProxyGUI 工具,API 開發除錯常用

反向代理(Reverse Proxy)

反向代理位於伺服器前方,代表伺服器 接收客戶端請求。客戶端不知道後方有多個伺服器存在,以為自己直接與目標伺服器溝通。

反向代理(Reverse Proxy)

                                        ┌─────────────┐
                    ┌───────────┐   ┌──→│  Backend 1   │
  ┌──────────┐     │           │   │   └─────────────┘
  │  Client  ├──→  │  Reverse  ├───┤
  │(Browser) │     │   Proxy   │   │   ┌─────────────┐
  └──────────┘     │ (Nginx)   ├───┼──→│  Backend 2   │
                   │           │   │   └─────────────┘
                   └───────────┘   │
                                   │   ┌─────────────┐
                                   └──→│  Backend 3   │
                                       └─────────────┘
  ← 外部網路 →    ← 代理伺服器 →    ← 內部網路 →

反向代理的常見用途

用途說明
負載平衡(Load Balancing)將請求分散到多個後端伺服器
SSL/TLS 終止在代理處理加密解密,後端使用 HTTP
快取快取靜態資源或 API 回應
安全防護隱藏後端伺服器、WAF、DDoS 防護
壓縮gzip/brotli 壓縮回應內容
速率限制(Rate Limiting)限制每個 IP 的請求速率

常見反向代理工具

工具特點適用場景
Nginx高效能、靜態檔案、反向代理通用 Web 伺服器
HAProxy專注負載平衡、TCP/HTTP、高可用大規模負載平衡
Envoy現代化、L7 代理、可觀測性Service Mesh、微服務
Caddy自動 HTTPS、簡單配置小型專案、快速部署
Traefik動態配置、Docker/K8s 原生整合容器環境

正向代理 vs 反向代理比較

這是最核心的觀念區分,務必理解兩者的差異:

維度正向代理(Forward Proxy)反向代理(Reverse Proxy)
代表誰客戶端伺服器
誰知道代理存在客戶端知道客戶端不知道
配置方客戶端配置伺服器端部署
主要目的存取控制、匿名、快取負載平衡、安全、快取
隱藏對象隱藏客戶端 IP隱藏後端伺服器
典型工具Squid、PrivoxyNginx、HAProxy、Envoy
典型使用者企業 IT、個人用戶網站運維、DevOps

簡單記憶:正向代理幫客戶端「翻牆」,反向代理幫伺服器「擋在前面」。


透明代理(Transparent Proxy)

透明代理(Transparent Proxy) 是一種客戶端不需要也不知道需要配置的代理。它通常部署在網路閘道或路由器上,自動攔截流量。

客戶端 → 路由器/閘道 → [透明代理] → 目標伺服器
                         │
                    客戶端不知道
                    代理的存在
                    (無需配置)

常見應用場景包括:ISP 流量管理與快取、企業網路監控、內容過濾(家長控制)、DDoS 緩解等。


Nginx 反向代理配置實戰

Nginx 是目前最廣泛使用的反向代理工具。以下從基礎到進階,逐步介紹核心配置。

基礎 proxy_pass 配置

最基本的反向代理只需要 proxy_pass 指令,將請求轉發到後端伺服器:

# /etc/nginx/conf.d/app.conf

# 定義後端伺服器群組
upstream backend {
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

# HTTP → HTTPS 重導向
server {
    listen 80;
    server_name app.example.com;

    return 301 https://$host$request_uri;
}

# HTTPS 伺服器
server {
    listen 443 ssl http2;
    server_name app.example.com;

    # SSL 憑證
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    # 反向代理:將所有請求轉發到後端
    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
    }
}

標頭傳遞(Header Forwarding)

當請求經過反向代理時,後端伺服器預設只看到 Nginx 的 IP。為了讓後端知道原始客戶端資訊,必須透過 HTTP 標頭傳遞:

location / {
    proxy_pass http://backend;

    # 傳遞客戶端真實 IP
    proxy_set_header X-Real-IP       $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # 傳遞原始 Host
    proxy_set_header Host $host;

    # 傳遞原始協定(HTTP 或 HTTPS)
    proxy_set_header X-Forwarded-Proto $scheme;

    # 連線設定
    proxy_set_header Connection "";
    proxy_http_version 1.1;
}

設定之後,後端收到的標頭就能還原客戶端原始資訊:

客戶端 (203.0.113.50) → Nginx (10.0.0.100) → Backend (10.0.0.1:3000)

後端收到的標頭:
  X-Real-IP:         203.0.113.50       (客戶端真實 IP)
  X-Forwarded-For:   203.0.113.50       (代理鏈中的 IP 列表)
  Host:              app.example.com    (原始請求的 Host)
  X-Forwarded-Proto: https              (原始協定)

注意X-Forwarded-For 可被客戶端偽造,在多層代理場景中需謹慎處理。

WebSocket 代理配置

WebSocket 需要 HTTP Upgrade 機制,一般的 proxy_pass 無法處理。需要額外設定 UpgradeConnection 標頭:

# WebSocket 代理
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

upstream websocket_backend {
    server 10.0.0.1:8080;
    server 10.0.0.2:8080;
    ip_hash;  # WebSocket 需要 Sticky Session(固定會話)
}

server {
    listen 443 ssl;
    server_name ws.example.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    location /ws {
        proxy_pass http://websocket_backend;

        # WebSocket 必要設定
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $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;

        # 超時設定(WebSocket 是長連線)
        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
    }
}

關鍵在於 map 指令:當客戶端送出 Upgrade: websocket 標頭時,Nginx 會將 Connection 設為 upgrade,完成 WebSocket 握手。

SSL 終止(SSL Termination)

SSL 終止 是反向代理最常見的功能之一:在 Nginx 處理 TLS 加密解密,後端伺服器只需處理 HTTP 明文流量,大幅降低後端的運算負擔。

              SSL/TLS                    HTTP(明文)
客戶端 ═══════════════ Nginx ──────────────── Backend
       HTTPS (443)            proxy_pass http://
       加密傳輸                  內部網路不加密
server {
    listen 443 ssl http2;
    server_name secure.example.com;

    # SSL 終止設定
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         HIGH:!aNULL:!MD5;

    # HSTS(強制瀏覽器使用 HTTPS)
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;

    # 後端使用 HTTP(SSL 於 Nginx 終止)
    location / {
        proxy_pass http://backend;
        proxy_set_header X-Forwarded-Proto https;
    }
}

負載平衡策略(Load Balancing)

反向代理的核心功能之一就是 負載平衡(Load Balancing)。Nginx 透過 upstream 區塊定義後端伺服器群組,並支援多種分配策略。

四種常見策略

# 1. 輪詢(Round Robin)— Nginx 預設策略
#    依序將請求分配給每個後端伺服器
upstream backend_rr {
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

# 2. 加權輪詢(Weighted Round Robin)
#    依權重比例分配流量,適合伺服器效能不同的情況
upstream backend_weighted {
    server 10.0.0.1:3000 weight=5;   # 50% 流量
    server 10.0.0.2:3000 weight=3;   # 30% 流量
    server 10.0.0.3:3000 weight=2;   # 20% 流量
}

# 3. IP Hash(同一客戶端固定到同一伺服器)
#    適合需要 Session 黏著的應用
upstream backend_iphash {
    ip_hash;
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

# 4. 最少連線(Least Connections)
#    優先將請求分配給當前連線數最少的伺服器
upstream backend_least {
    least_conn;
    server 10.0.0.1:3000;
    server 10.0.0.2:3000;
    server 10.0.0.3:3000;
}

健康檢查與故障轉移

# 健康檢查配置
upstream backend_ha {
    server 10.0.0.1:3000 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:3000 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:3000 backup;  # 備用伺服器,僅在上方伺服器皆故障時啟用
}
  • max_fails=3:連續失敗 3 次後,將該伺服器標記為不可用
  • fail_timeout=30s:標記不可用後,等待 30 秒再重新嘗試
  • backup:備用伺服器,只有當其他伺服器都不可用時才會啟用

Nginx 快取配置(Proxy Cache)

反向代理是實現 HTTP 快取的理想位置,可以大幅減少後端伺服器的負擔:

快取層次

瀏覽器快取 → CDN 邊緣快取 → 反向代理快取 → 應用快取 → 資料庫
  (最快)                                              (最慢)
# 定義快取區域
proxy_cache_path /var/cache/nginx
    levels=1:2                  # 目錄層級
    keys_zone=my_cache:10m      # 快取索引記憶體(10MB ≈ 80,000 keys)
    max_size=10g                # 最大磁碟空間
    inactive=60m                # 60 分鐘未存取則刪除
    use_temp_path=off;          # 直接寫入快取目錄

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

        # 啟用快取
        proxy_cache my_cache;
        proxy_cache_valid 200 10m;      # 200 回應快取 10 分鐘
        proxy_cache_valid 404 1m;       # 404 快取 1 分鐘

        # 後端故障時使用過期快取
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503;

        # 自訂快取 key
        proxy_cache_key "$scheme$request_method$host$request_uri";

        # 回應中加入快取狀態標頭
        add_header X-Cache-Status $upstream_cache_status;
        # HIT     = 快取命中
        # MISS    = 快取未命中
        # EXPIRED = 快取過期(已回源取得新資料)
        # STALE   = 使用過期快取(後端故障時)

        # 不快取含認證標頭的請求
        proxy_no_cache $http_authorization;
        proxy_cache_bypass $http_authorization;
    }
}

Nginx 完整生產配置範例

結合前面所有概念,以下是一份接近真實生產環境的 Nginx 反向代理配置:

# /etc/nginx/conf.d/production.conf

# 速率限制區域
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login_limit:10m rate=1r/s;

# 快取區域
proxy_cache_path /var/cache/nginx levels=1:2
    keys_zone=static_cache:10m max_size=1g
    inactive=60m use_temp_path=off;

# 後端伺服器群組
upstream api_backend {
    least_conn;
    server 10.0.0.1:3000 max_fails=3 fail_timeout=30s;
    server 10.0.0.2:3000 max_fails=3 fail_timeout=30s;
    server 10.0.0.3:3000 max_fails=3 fail_timeout=30s;
    keepalive 32;  # 保持後端連線池
}

server {
    listen 443 ssl http2;
    server_name app.example.com;

    # SSL 設定
    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

    # 安全標頭
    add_header X-Frame-Options DENY always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-XSS-Protection "1; mode=block" always;

    # gzip 壓縮
    gzip on;
    gzip_types text/plain text/css application/json application/javascript
               text/xml application/xml image/svg+xml;
    gzip_min_length 1000;

    # 靜態資源(啟用快取)
    location /static/ {
        proxy_pass http://api_backend;
        proxy_cache static_cache;
        proxy_cache_valid 200 1d;
        proxy_cache_valid 404 1m;
        add_header X-Cache-Status $upstream_cache_status;
    }

    # API 路由(速率限制)
    location /api/ {
        limit_req zone=api_limit burst=20 nodelay;

        proxy_pass http://api_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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_connect_timeout 5s;
        proxy_read_timeout 30s;
        proxy_send_timeout 30s;

        # 後端錯誤頁面
        proxy_intercept_errors on;
        error_page 502 503 504 /50x.html;
    }

    # 登入路由(更嚴格的速率限制)
    location /api/auth/login {
        limit_req zone=login_limit burst=5 nodelay;
        proxy_pass http://api_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    # 健康檢查端點(不記錄日誌)
    location /health {
        access_log off;
        proxy_pass http://api_backend;
    }

    location = /50x.html {
        root /usr/share/nginx/html;
        internal;
    }
}

API Gateway:反向代理的進階特化

API Gateway(API 閘道) 可以視為反向代理的特化版本,專為 API 管理而設計。除了具備反向代理的所有功能外,還提供 API 層級的進階管理能力。

反向代理(通用)
  請求 → [反向代理] → 後端伺服器
         ├── 負載平衡
         ├── SSL 終止
         └── 基本路由

API Gateway(API 特化)
  請求 → [API Gateway] → 微服務 A / B / C
         ├── 所有反向代理功能
         ├── API 認證/授權(OAuth 2.0、JWT、API Key)
         ├── 速率限制/節流(基於 API Key 或用戶)
         ├── 請求/回應轉換
         ├── API 版本管理
         └── API 分析與監控
維度反向代理API Gateway
主要用途通用流量管理API 管理
認證方式基礎(Basic Auth)OAuth 2.0、JWT、API Key
協定轉換HTTP 層HTTP/gRPC、REST/GraphQL
速率限制基於 IP基於 API Key、用戶、方案
典型工具Nginx、HAProxyKongAWS API Gateway

在微服務架構中,API Gateway 幾乎是標配元件,負責統一入口管理、認證、限流等橫切面(Cross-Cutting Concerns)功能。


Service Mesh 中的 Sidecar Proxy

在更大規模的微服務架構中,Service Mesh(服務網格) 使用 Sidecar Proxy 模式,在每個服務旁邊部署一個代理(通常是 Envoy),處理所有入站和出站流量。

Service Mesh 架構(以 Istio 為例)

                Control Plane
                ┌──────────┐
                │  istiod   │
                └─────┬─────┘
                      │ xDS API(配置推送)
         ┌────────────┼────────────┐
         ▼            ▼            ▼
  ┌────────────┐ ┌────────────┐ ┌────────────┐
  │   Pod A    │ │   Pod B    │ │   Pod C    │
  │ ┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐ │
  │ │Service │ │ │ │Service │ │ │ │Service │ │
  │ │   A    │ │ │ │   B    │ │ │ │   C    │ │
  │ └───┬────┘ │ │ └───┬────┘ │ │ └───┬────┘ │
  │ ┌───┴────┐ │ │ ┌───┴────┐ │ │ ┌───┴────┐ │
  │ │ Envoy  │←┼─┼→│ Envoy  │←┼─┼→│ Envoy  │ │
  │ │Sidecar │ │ │ │Sidecar │ │ │ │Sidecar │ │
  │ └────────┘ │ │ └────────┘ │ │ └────────┘ │
  └────────────┘ └────────────┘ └────────────┘

Sidecar Proxy 負責的功能包括:

  • mTLS 加密:服務間零信任通訊
  • 客戶端側負載平衡:不需要額外的負載平衡器
  • 斷路器(Circuit Breaker):防止故障擴散
  • 流量路由:支援 Canary、Blue-Green 部署
  • 可觀測性:自動收集 Metrics、Traces、Logs

Service Mesh 的核心理念是將網路通訊的複雜度從應用程式中抽離,交由基礎設施層統一處理。


Kubernetes Ingress 作為反向代理

Kubernetes 環境中,Ingress 本質上就是反向代理的聲明式配置。Ingress Controller(通常是 Nginx 或 Traefik)負責實際的流量路由:

外部流量 → [Ingress Controller (Nginx/Traefik)] → Service → Pod
           = 反向代理                              = 負載平衡

以下是一個 Kubernetes Ingress 資源的範例,等同於一份反向代理配置:

# Kubernetes Ingress 範例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    # Nginx Ingress Controller 專用 annotation
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"
    nginx.ingress.kubernetes.io/rate-limit-rps: "10"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - app.example.com
    secretName: app-tls
  rules:
  - host: app.example.com
    http:
      paths:
      # /api 路徑導向 API 服務
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-service
            port:
              number: 3000
      # 其餘路徑導向前端服務
      - path: /
        pathType: Prefix
        backend:
          service:
            name: frontend-service
            port:
              number: 80

透過 Ingress,你可以用 YAML 宣告式地定義路由規則、TLS 終止和速率限制,而 Ingress Controller 會自動將這些規則轉換為 Nginx 配置。


總結

Proxy 是現代網路架構中不可或缺的中介層。掌握以下核心概念,對於部署、維運和架構設計都至關重要:

  1. 正向代理 代表客戶端,用於匿名瀏覽、存取控制和企業網路管理
  2. 反向代理 代表伺服器,用於負載平衡、SSL 終止、快取和安全防護
  3. Nginx 是最主流的反向代理工具,透過 proxy_passupstreamproxy_cache 等指令即可完成從基礎到進階的配置
  4. 負載平衡 策略需根據應用特性選擇:Round Robin 適合通用場景、IP Hash 適合需要 Session 黏著的應用、Least Connections 適合請求處理時間差異大的場景
  5. 在更大規模的架構中,API Gateway 提供 API 層級的進階管理,Service Mesh 則將網路通訊抽離至基礎設施層
  6. 在 Kubernetes 環境中,Ingress 就是反向代理的宣告式抽象

無論是單一應用的部署,還是大規模微服務架構,理解 Proxy 的運作原理與實作方式,都是後端工程師和 DevOps 的必備技能。

BenZ Software Developer

熱愛技術的軟體開發者,在這裡分享程式開發經驗與學習筆記。