代理

返回 计算机网络

代理服务器位于客户端与目标服务器之间,转发请求和响应,可用于访问控制、负载均衡、缓存加速和安全防护。


正向代理 vs 反向代理

维度正向代理反向代理
代理对象代理客户端代理服务端
配置位置客户端(浏览器、系统)服务端(Nginx、网关)
对服务端可见服务端看到代理 IP,看不到真实客户端客户端看到代理 IP,看不到真实服务端
对客户端可见客户端主动配置,知道代理存在客户端无感知,以为直连服务器
典型用途突破访问限制、企业出口审计负载均衡、HTTPS 卸载、API 网关

正向代理

客户端(配置代理 IP:Port)→ 正向代理 → 目标服务器

客户端将所有请求发给代理,由代理转发给真实目标:

# 系统级代理(Linux)
export http_proxy=http://proxy.company.com:8080
export https_proxy=http://proxy.company.com:8080
export no_proxy=localhost,127.0.0.1,192.168.0.0/16
 
# curl 指定代理
curl -x http://proxy:8080 https://example.com
 
# Git 使用代理
git config --global http.proxy http://proxy:8080

CONNECT 隧道(HTTPS 代理)

HTTP 代理处理 HTTPS 请求时,使用 CONNECT 方法建立隧道,代理不解密内容:

客户端 → 代理:CONNECT example.com:443 HTTP/1.1
代理  → 客户端:HTTP/1.1 200 Connection Established

之后客户端与 example.com 直接进行 TLS 握手,
代理只是透明转发加密字节流,无法查看内容。

Squid 正向代理配置示例

# squid.conf(企业内网出口代理)
http_port 3128
acl localnet src 192.168.0.0/16
http_access allow localnet
http_access deny all
cache_mem 256 MB
maximum_object_size 50 MB

反向代理

客户端 → 反向代理(Nginx)→ 后端服务 A(:8080)
                           → 后端服务 B(:8081)
                           → 静态资源

Nginx 反向代理完整配置

# /etc/nginx/conf.d/myapp.conf
 
# 上游服务器组(负载均衡)
upstream backend {
    least_conn;                          # 最少连接策略
    server 192.168.1.10:8080 weight=3;  # 权重更高
    server 192.168.1.11:8080 weight=1;
    server 192.168.1.12:8080 backup;    # 备用节点
 
    keepalive 32;                        # 保持到后端的长连接数
}
 
server {
    listen 80;
    server_name example.com;
    # 强制跳转 HTTPS
    return 301 https://$host$request_uri;
}
 
server {
    listen 443 ssl http2;
    server_name example.com;
 
    # TLS 证书(SSL 卸载:客户端与 Nginx 走 HTTPS,Nginx 到后端走 HTTP)
    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    ssl_protocols       TLSv1.2 TLSv1.3;
    ssl_ciphers         ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
 
    # 安全响应头
    add_header Strict-Transport-Security "max-age=31536000" always;
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
 
    # 前端静态资源(SPA 路由兜底)
    location / {
        root /var/www/dist;
        index index.html;
        try_files $uri $uri/ /index.html;  # Vue/React 路由支持
 
        # 静态资源长缓存
        location ~* \.(js|css|png|jpg|ico|woff2)$ {
            expires 1y;
            add_header Cache-Control "public, immutable";
        }
    }
 
    # API 反向代理
    location /api/ {
        proxy_pass http://backend;          # 转发到上游组
        proxy_http_version 1.1;
        proxy_set_header Connection "";     # 开启对后端的 keep-alive
 
        # 传递客户端真实信息
        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_send_timeout    60s;
        proxy_read_timeout    60s;
 
        # 缓冲(防止后端慢响应阻塞 worker)
        proxy_buffering on;
        proxy_buffer_size 16k;
        proxy_buffers 4 32k;
    }
 
    # WebSocket 代理
    location /ws/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_read_timeout 3600s;           # 长连接超时调大
    }
 
    # 文件上传(增大 body 限制)
    location /api/upload {
        proxy_pass http://backend;
        client_max_body_size 50M;
    }
}

X-Forwarded-For 与真实 IP

经过多层代理后,后端获取客户端真实 IP 的方式:

客户端(1.2.3.4) → 代理A → 代理B → 后端

X-Forwarded-For: 1.2.3.4, 代理A的IP

后端代码(Spring Boot):
  String realIp = request.getHeader("X-Real-IP");
  // 或解析 X-Forwarded-For 第一个 IP

注意:X-Forwarded-For 可被客户端伪造,只信任受控代理添加的部分。


负载均衡策略

策略Nginx 指令适用场景
轮询(Round Robin)默认后端性能均等
权重轮询weight=N后端性能不等
最少连接least_conn请求处理时间差异大
IP 哈希ip_hash需要会话保持(Session Sticky)
一致性哈希hash $request_uri consistent缓存场景,相同 URL 打到同一后端

健康检查

# Nginx 开源版:通过 max_fails 和 fail_timeout 被动检测
upstream backend {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}
 
# Nginx Plus / OpenResty:主动健康检查
# check interval=3000 rise=2 fall=3 timeout=1000 type=http;

透明代理

客户端不需配置,网络层强制流量经过代理(iptables/TPROXY):

# 通过 iptables 将 80/443 流量重定向到代理(Linux 网关)
iptables -t nat -A PREROUTING -p tcp --dport 80 \
  -j REDIRECT --to-port 3128
iptables -t nat -A PREROUTING -p tcp --dport 443 \
  -j REDIRECT --to-port 3129

常用于:企业内网流量审计、家长控制、运营商 HTTP 缓存代理。


代理协议

协议层级说明
HTTP 代理L7明文 HTTP 请求转发,可缓存/过滤
HTTPS 代理(CONNECT)L7建立加密隧道,代理不解密内容
SOCKS4L4TCP 代理,不支持 UDP、无认证
SOCKS5L4TCP+UDP,支持认证,更通用
Proxy ProtocolL4在 TCP 连接头传递客户端真实 IP(Nginx、HAProxy 支持)
# Nginx 接收 Proxy Protocol(前面有 LB 传递真实 IP)
listen 443 ssl proxy_protocol;
set_real_ip_from 10.0.0.0/8;
real_ip_header proxy_protocol;

API 网关

API 网关是面向微服务的特殊反向代理,在负载均衡之上增加:

客户端
    │
  API 网关(Spring Cloud Gateway / Kong / APISIX)
    ├── 身份认证(JWT 验证、OAuth 2.0)
    ├── 限流(令牌桶、滑动窗口)
    ├── 熔断降级
    ├── 请求路由(按路径/Header/版本分发)
    ├── 协议转换(HTTP → gRPC)
    ├── 日志与链路追踪
    └── 灰度发布(按比例路由新版本)
         │
    ┌────┴──────┬────────┐
  服务A       服务B    服务C

Spring Cloud Gateway 路由示例

spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service          # lb:// 表示通过注册中心负载均衡
          predicates:
            - Path=/api/user/**
          filters:
            - StripPrefix=1               # 去掉 /api 前缀
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 100
                redis-rate-limiter.burstCapacity: 200

VPN vs 代理

维度代理(HTTP/SOCKS)VPN
工作层L7 / L4L3(IP 层)
流量范围仅代理的应用(浏览器等)所有系统流量
加密视协议而定(SOCKS5 不加密)全程加密
性能开销较高(加解密全部流量)
配置应用内配置系统级,影响全部流量
典型用途特定应用的流量转发整机安全隧道、企业内网接入

服务网格(Service Mesh)中的代理

在微服务架构中,Sidecar 代理(如 Envoy)自动注入每个 Pod 旁:

[服务 A Pod]                      [服务 B Pod]
  应用容器                          应用容器
  Envoy Sidecar  ←── mTLS ──►  Envoy Sidecar

Sidecar 负责:
  ✓ 服务发现(不需要 SDK 集成)
  ✓ 负载均衡
  ✓ mTLS 双向认证加密
  ✓ 熔断/重试
  ✓ 链路追踪(自动注入 Trace Header)
  ✓ 流量镜像/灰度

Istio / Linkerd 等服务网格通过控制平面(Control Plane)统一下发策略给所有 Sidecar。


相关

  • HTTP — 代理主要处理 HTTP/HTTPS 流量
  • TLS — 反向代理承担 TLS 握手(SSL 卸载)
  • HTTPS — 对外 HTTPS 入口
  • 网络安全 — 代理用于访问控制和流量审计
  • IP与路由 — 代理改变数据包的路由路径
  • CDN — CDN 边缘节点本质是反向代理 + 缓存
  • 前后端交互 — Vite/Nginx 开发/生产环境代理配置
  • 网络性能 — 代理层引入的延迟与优化