
Reverse Proxy + TLS:把所有門口集中管理
當服務越來越多,最怕的不是「不會部署」,而是「入口失控」。 反向代理就是讓所有流量先到一個入口,再由入口轉發到正確的服務。TLS 則確保傳輸安全。這一層做對了,後面的服務可以專心處理業務邏輯,不必自己面對公網或憑證管理。
反向代理的價值是「統一治理」,不是只是轉發。 它讓你在最外層就能做:TLS、WAF、Rate Limit、Header 政策、灰度與觀察。
架構概覽
flowchart LR Client[Client / Browser] -->|HTTPS| Nginx[Nginx Reverse Proxy] Nginx -->|HTTP| API[API Service] Nginx -->|HTTP| Admin[Admin Console] Nginx -->|HTTP| Git[GitLab] Nginx -->|WebSocket| WS[Realtime Service] Nginx --> ACME[ACME/Let's Encrypt]
入口的主要責任:
- 統一 TLS 憑證
- 依域名/路徑分流
- 可加上 WAF / Rate Limit / Header 政策
- 對外統一入口、對內保護服務
核心概念
-
TLS 統一治理
- 憑證集中管理,避免每個服務各自申請與續期。
- 在反向代理層做 HSTS、TLS 版本限制與加密套件配置。
- 統一啟用 OCSP Stapling,降低握手延遲並提升安全性。
-
Host/Path Based Routing
- 依據
server_name或location分流至不同服務。 - 例如
api.example.com→ API,admin.example.com→ 管理後台。 - Path-based 常用於「同網域多服務」,但要小心路徑衝突。
- 依據
-
Upstream 與負載平衡
- 多台後端可透過 upstream 分流,支援 round-robin 或權重。
- 能平滑擴充而不改 DNS。
- 可搭配健康檢查與故障自動移除節點。
-
WebSocket 與長連線
- WebSocket 需要
Upgrade與Connectionheader。 - 入口必須正確轉發,否則會造成連線斷線。
- 若有長輪詢或 SSE,也需要適當調整 timeout。
- WebSocket 需要
-
邊緣防護與觀測
- 入口可以加上 Rate Limit、IP allowlist、WAF。
- 把攻擊擋在最外層,避免後端服務直接承受壓力。
- 建議把 access log 與 error log 統一輸出到 log 系統,方便追查。
使用情境(具體場景)
- 多服務入口統一:公司有 API、Admin、GitLab、監控等多個服務,全都集中到一個 Nginx 入口,避免每個服務暴露公網。
- 憑證集中續期:使用 Let’s Encrypt 或 Cloudflare Origin Cert,入口自動續期即可,不需要每個服務更新憑證。
- 切流或灰度:透過 Nginx upstream 權重,將新版本流量導向特定節點,先觀察再擴大。
- 事件防護:在 DDoS 或爆量時,先在入口做 rate limit,避免後端資源被打爆。
實作範例 / 設定範例
1) Nginx 基本站台設定(HTTP→HTTPS + HSTS)
# /etc/nginx/sites-enabled/api.conf
server {
listen 80;
server_name api.example.com;
# 自動轉 HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
location / {
proxy_pass http://api-upstream;
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;
}
}
upstream api-upstream {
server 10.10.10.11:3000;
server 10.10.10.12:3000;
}2) WebSocket 轉發設定
# /etc/nginx/sites-enabled/ws.conf
server {
listen 443 ssl http2;
server_name ws.example.com;
ssl_certificate /etc/letsencrypt/live/ws.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ws.example.com/privkey.pem;
location / {
proxy_pass http://10.10.10.20:4000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_read_timeout 3600;
}
}3) ACME 自動續期(certbot)
# 申請憑證(首次)
certbot certonly --nginx -d api.example.com -d admin.example.com
# 查看續期狀態
certbot renew --dry-run
# 建議加入排程
crontab -l | grep certbot4) 速率限制(防爆量)
# /etc/nginx/conf.d/limit.conf
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
listen 443 ssl;
server_name api.example.com;
location / {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://api-upstream;
}
}5) 安全 Header 與壓縮(基礎強化)
# /etc/nginx/conf.d/security.conf
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
gzip on;
gzip_types text/plain text/css application/json application/javascript;常見問題與風險
-
憑證過期: 憑證到期會導致整站不可用,通常是 ACME 續期排程失效。解法是建立監控與
renew --dry-run定期檢查。- 為什麼會發生:HTTP-01 驗證路徑被改動、80 port 被擋或 DNS 指向錯誤。
-
錯誤的 X-Forwarded-Proto: 後端會以為是 HTTP 而不是 HTTPS,造成 redirect loop。必須確保
X-Forwarded-Proto被正確帶入。- 避免方式:入口統一設定
proxy_set_header X-Forwarded-Proto $scheme;。
- 避免方式:入口統一設定
-
Header 洩漏真實 IP: 如果上游沒有過濾
X-Forwarded-For,攻擊者可偽造來源 IP。應在入口端覆蓋或使用real_ip模組。- 避免方式:只信任自家 LB/Proxy 的
real_ip來源。
- 避免方式:只信任自家 LB/Proxy 的
-
WebSocket 斷線: 未設定
Upgradeheader 或 timeout 太短會導致連線被切斷。需要適當的proxy_read_timeout。- 避免方式:對 WebSocket 服務獨立設定較長 timeout。
-
入口成為單點: 所有流量都經過入口,若入口掛掉就全掛。中期應規劃雙入口或雲端 LB。
- 避免方式:使用 Keepalived/VRRP 或雲端負載平衡器。
優點
- 入口集中,安全與流量策略一致
- TLS 憑證統一管理,降低維運成本
- 可加上快取、壓縮、WAF、Rate Limit 等能力
缺點 / 限制
- 入口成為單點故障,需要額外 HA
- 反向代理設定複雜,錯誤容易影響全站
- TLS 與高併發會帶來 CPU 成本
落地檢查清單
- 是否所有服務都經過入口,不直接暴露公網
- 是否設定 HSTS 與 TLS 版本限制
- 是否有憑證續期監控
- WebSocket 是否正確轉發
- 入口是否有 HA 或 failover 策略