Proxy 與 Reverse Proxy 完全解析:正向代理與反向代理 | Networking
Proxy 代理伺服器是網路中的中介節點,代替一方發送或接收請求。Forward Proxy 代替客戶端向伺服器發送請求;Reverse Proxy 代替伺服器接收客戶端請求。本文將從基礎概念出發,深入 Nginx 反向代理配置實戰,涵蓋 負載平衡、SSL 終止、WebSocket 代理、快取策略,並延伸至 API Gateway、Service Mesh 與 Kubernetes 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 Proxy | GUI 工具,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、Privoxy | Nginx、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 無法處理。需要額外設定 Upgrade 和 Connection 標頭:
# 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、HAProxy | Kong、AWS 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 是現代網路架構中不可或缺的中介層。掌握以下核心概念,對於部署、維運和架構設計都至關重要:
- 正向代理 代表客戶端,用於匿名瀏覽、存取控制和企業網路管理
- 反向代理 代表伺服器,用於負載平衡、SSL 終止、快取和安全防護
- Nginx 是最主流的反向代理工具,透過
proxy_pass、upstream、proxy_cache等指令即可完成從基礎到進階的配置 - 負載平衡 策略需根據應用特性選擇:Round Robin 適合通用場景、IP Hash 適合需要 Session 黏著的應用、Least Connections 適合請求處理時間差異大的場景
- 在更大規模的架構中,API Gateway 提供 API 層級的進階管理,Service Mesh 則將網路通訊抽離至基礎設施層
- 在 Kubernetes 環境中,Ingress 就是反向代理的宣告式抽象
無論是單一應用的部署,還是大規模微服務架構,理解 Proxy 的運作原理與實作方式,都是後端工程師和 DevOps 的必備技能。