一句话记住代理

正向代理帮客户端出去,反向代理帮服务端接客。
搞混了就白学。

代理(Proxy)是网络架构中最容易被混淆的概念之一。正向代理、反向代理、HTTP 代理、HTTPS 代理、SOCKS5 代理……名词虽多,但只要抓住三条主线,一切就清晰了:


谁在发起连接?
客户端主动 or 被动?


工作在哪一层?
L4 传输层 or L7 应用层?


看到什么流量?
明文 HTTP or TLS 隧道?

本文将从概念本质出发,逐步拆解到 Nginx 的代理能力边界,最后给出主流正向代理容器镜像的硬核对比与可落地的部署配置。


一、正向代理 vs 反向代理

1.1 正向代理(Forward Proxy)

客户端 明确知道 要走代理,把请求”交给代理”,由代理代表客户端去访问目标服务器。

1
2
客户端 ──→ [正向代理] ──→ 目标服务器
(客户端配置代理地址)

关键特征

  • 客户端主动配置代理地址(浏览器 / http_proxy / https_proxy 环境变量)
  • 目标服务器看到的是 代理的 IP,不知道真实客户端是谁
  • 正向代理为 客户端群体 服务

企业出口管控
内网流量经代理出网,统一审计、缓存、ACL 过滤

绕过网络限制
VPN / 代理上网,隐藏真实来源

常见协议形态:

  • HTTP 正向代理 — 处理 GET / POST / CONNECT
  • SOCKS 正向代理 — 更底层,转发任意 TCP/UDP

1.2 反向代理(Reverse Proxy)

客户端 以为 自己在连”真实服务器”,实际上前面挡了一层代理,由代理把请求转给背后的上游服务。

1
2
客户端 ──→ [反向代理] ──→ 上游服务器集群
(客户端以为代理就是目标)

关键特征

  • 客户端 不知道 背后有代理(DNS 指向反向代理)
  • 反向代理为 服务端集群 服务
  • 上游服务器可以完全隐藏在内网

统一入口
域名收敛、SSL/TLS 终结

负载均衡
分发请求、高可用

安全防护
缓存、WAF、限流、鉴权

1.3 面试一句话

核心区别

正向代理 — 代理的是客户端(帮客户端出去)
反向代理 — 代理的是服务端(帮服务端接客)


二、HTTP / HTTPS / SOCKS5 代理

2.1 HTTP 代理(应用层 L7)

最常见的正向代理形态,代理协议本身就是 HTTP。

1
2
GET http://example.com/ HTTP/1.1
Host: example.com

代理直接帮你去拿资源,可以看到完整的 HTTP 头和内容,可以做缓存、过滤、头改写。

1
CONNECT example.com:443 HTTP/1.1

收到 CONNECT 后建立一条 TCP 隧道,之后是客户端与目标服务器之间的 TLS 加密通信。代理只能看到 域名/端口(SNI),看不到 HTTP 明文 body。

适用: 企业内网出口(Squid)、让客户端统一走一个出口 IP

局限: 只能代理”支持代理语义”的流量;对 HTTPS 不破解 TLS 则看不到明文

2.2 HTTPS 代理(两种含义,别搞混)

注意区分

很多人把”HTTPS 代理”混为一谈,实际上有两种完全不同的含义。

含义一:客户端到代理走 HTTPS

1
浏览器 → [HTTPS加密] → 代理:8443 → CONNECT → 真正目标

解决的是 客户端到代理这段链路加密(防止内网偷看认证密码/请求头)。代理对外仍是标准 HTTP CONNECT 正向代理。

含义二:中间人解密(MITM / SSL Inspection)

代理自己签发证书、客户端装根证书、代理 终止 TLS 再发起新 TLS,从而可以看到/修改 HTTPS 明文内容。

  • 合规场景叫 SSL Inspection(企业安全审计)
  • 非合规场景属于 攻击模型

Nginx 不内置 MITM CA 逻辑 — 不要把”HTTPS 反代/SSL 终止”等同于”能看 HTTPS 内容”。

2.3 SOCKS5 代理(传输层 L4-L5)

SOCKS5 是 套接字级别 的代理协议,不关心上层是什么协议。

1
2
3
① 客户端与 SOCKS5 握手/认证
② 告诉代理:"帮我连 host:port"
③ 代理建立 TCP/UDP,之后就是透传

优点

通用性强 — SSH、HTTP、SMTP、自定义 TCP 协议全能穿

缺点

不解析 HTTP 头 — 无法基于 path/host 做七层路由/缓存

2.4 三种协议一图对比

维度HTTP 代理HTTPS (CONNECT)SOCKS5
工作层级L7L7 隧道L4-L5
代理什么HTTP 请求HTTPS 隧道任意 TCP/UDP
看 HTTP 头不能不能
能缓存不能不能
客户端配置http_proxyhttps_proxySOCKS5 代理框
典型工具Squid、TinyProxySquid、TinyProxyDante、go-socks5

三、Nginx 能做什么代理?

Nginx 是最流行的代理服务器之一,但它 不是万能的。先搞清楚边界,再谈部署。

3.1 能力边界一览

HTTP/HTTPS 反向代理(L7)

http { server { location { proxy_pass ... } } }

Web 入口、负载均衡、SSL 终止、路由到多 upstream

TCP/UDP 代理(L4)

stream { server { proxy_pass ... } }

端口转发、数据库/SSH/SMTP 等四层转发

Nginx 能力速查

能力说明
✅ 最核心反向代理 HTTP/HTTPS
✅ 可以做TCP/UDP 端口转发(stream)
❌ 不原生HTTP 正向代理(带 CONNECT/缓存)
❌ 不能做SOCKS5 代理(协议不对)
想部署"客户端出口上网"的正向代理?用 Squid / TinyProxy / Dante 等专用工具,不是 Nginx。

3.2 Nginx 代理能力总结表

你听到的名词本质Nginx 能做?
正向代理(HTTP)客户端配置代理,代理替客户端出去
反向代理(HTTP/HTTPS)前端入口挡在服务器前
HTTPS 代理(SSL 终止)TLS 终结在代理层
SOCKS5 代理TCP/UDP 套接字级隧道
TCP/UDP 端口转发L4 转发

Nginx HTTP 反代配置模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
http {
upstream app {
server 127.0.0.1:8080;
# server 127.0.0.1:8081; # 多后端负载均衡
}

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://app;
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;
}
}
}

Nginx HTTPS 反代配置模板(SSL Termination)

思路

证书放在 Nginx,对外 HTTPS,内网回源可以是 HTTP。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
http {
upstream app {
server 127.0.0.1:8080;
}

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

ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;

location / {
proxy_pass http://app;
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 https;
}
}

# HTTP 自动跳转 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
}

回源也走 HTTPS 时:

1
2
proxy_pass https://app;
proxy_ssl_verify off; # 或配证书校验

Nginx 四层 TCP 代理(stream)

比如暴露内网的 MySQL / SSH / SMTP:

1
2
3
4
5
6
7
# 注意:stream 与 http 平级,不在 http{} 内
stream {
server {
listen 3306;
proxy_pass 10.0.0.20:3306;
}
}
注意

stream 不认识 HTTP,只是 TCP 转发。SOCKS5 也是 TCP 但协议不同,别以为这就变 SOCKS5 了。


四、正向代理容器镜像选型

Nginx 做不了正向代理,那该用什么?下面对主流容器镜像做一次硬核横评。

4.1 各赛道选手速览

Squid — 工业级天花板

ACL 极强 — 按 IP/域名/MIME/时间/用户过滤,CONNECT 隧道、分层缓存、ICAP 扩展、审计完善

弱项: 配置最重、镜像 ~80-200MB

镜像: gissehel/squidsameersbn/squid

TinyProxy — 最流行轻量 HTTP 代理

极轻 — 内存 ~2MB、CONNECT 隧道、BasicAuth、ACL

弱项: 无缓存、ACL 不如 Squid 精细

镜像: vimagick/tinyproxy

yegor256/squid-proxy — 一键 Squid

环境变量驱动的账号密码 Squid 包装,适合快速起带认证的出口

Privoxy — 内容过滤网关

广告/跟踪头清洗,常跟 Tor 链用。不支持 CONNECT,不适合通用 HTTPS 出口

Dante (sockd) — SOCKS5 里的 Squid

RFC 1928 合规最硬 — UDP relay、详细日志、PAM 认证、细粒度 ACL

弱项: 配置语法偏老派

镜像: wernicht/dante

go-socks5-proxy — 最轻量 SOCKS5

~2MB 镜像(scratch + Go 静态二进制)、env 驱动、IP/FQDN 白名单、多架构

Docker Hub Pulls: 10M+

microsocks — 极简主义

代码 < 500 行,几乎不可能藏后门。无认证,靠防火墙/IP 白名单兜底

3proxy — 老牌全协议代理

HTTP/HTTPS + SOCKS4/5 + FTP + 限速 + 日志 + 认证,一个容器全给

推荐镜像: ghcr.io/tarampampam/3proxy:1

ozcho/proxy — 两口合一

tinyproxy(HTTP :8888) + microsocks(SOCKS5 :8889),超小 Alpine

适合内网 sidecar、开发环境

mitmproxy — 拦截型代理

可拦截/记录/修改 HTTPS(需客户端装 CA),有 Web UI,Python 脚本化

≠ 匿名出口! 适合开发调试、安全测试

4.2 完整对比大表

#名字 / 镜像协议定位大小难度认证ACLGitHub
1Squid (gissehel/squid)HTTP企业级天花板~80-200MB★★★★✅✅✅GitHub
2TinyProxy (vimagick/tinyproxy)HTTP最流行轻量~10MB★☆⚠️GitHub
3go-socks5-proxySOCKS5最轻量~2MB⚠️GitHub
4Dante (wernicht/dante)SOCKS5标准合规~15-30MB★★★✅✅官网
53proxyHTTP+SOCKS5全协议~10-20MB★★GitHub
6microsocksSOCKS5极简主义~5MBGitHub
7squid-proxyHTTP一键带密码~100MB★☆⚠️GitHub
8PrivoxyHTTP+过滤隐私清洗~20MB★★⚠️URL官网
9mitmproxy拦截型HTTPS 可解~200MB+★★CAGitHub
10ozcho/proxyHTTP+SOCKS5两口合一~20MB★☆⚠️⚠️Docker Hub

4.3 场景化选型速查

爬虫 / CI / apt / yum / npm 设 http_proxy

推荐选择理由
🥇Squid要审计 / ACL / 可扩展
🥈TinyProxy最平衡:轻、标准、好容器化
🥉squid-proxy只想 docker run + 账密

SSH / git / 任意 TCP、客户端支持 SOCKS5

推荐选择理由
🥇Dante标准 / ACL / UDP / 审计
🥈go-socks5-proxy最省事:env 驱动、白名单
🥉microsocks代码极少、绝对最小

一个容器一套配置全管

推荐选择理由
🥇3proxy全协议 + 限速 + 认证
🥈ozcho/proxytinyproxy + microsocks 合体

五、部署实战

下面详细给出 TinyProxy(HTTP 正向代理)go-socks5-proxy(SOCKS5 代理) 两个最常用镜像的完整部署教程。

5.1 vimagick/tinyproxy — HTTP 正向代理

TinyProxy 是最流行的轻量 HTTP 正向代理,内存仅 ~2MB,支持 CONNECT 隧道、BasicAuth 认证、IP ACL,对 http_proxy 环境变量非常友好。

第一步:创建目录和配置文件

1
2
mkdir -p ~/proxy/tinyproxy
cd ~/proxy/tinyproxy

编写 tinyproxy.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# ===== 基础配置 =====
Port 8888
Listen 0.0.0.0
Timeout 600

# ===== 访问控制(生产必配!)=====
Allow 127.0.0.1
Allow 192.168.0.0/16
Allow 10.0.0.0/8
# Allow 172.16.0.0/12

# ===== 可选:Basic 认证 =====
# BasicAuth myuser 'MyStr0ngP@ss'

# ===== 日志 =====
LogLevel Info
LogFile "/var/log/tinyproxy/tinyproxy.log"
LogFormat "%t %r %>s %b"

# ===== 性能 =====
MaxClients 100
MinSpareServers 5
MaxSpareServers 20
StartServers 10

# ===== 安全 =====
DisableViaHeader Yes # 隐藏代理痕迹
ConnectPort 443 # CONNECT 只允许 443
ConnectPort 563 # 和 563 (NNTPS)

第二步:docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
version: '3.8'
services:
tinyproxy:
image: vimagick/tinyproxy:latest
container_name: tinyproxy
restart: unless-stopped
ports:
- "8888:8888"
volumes:
- ./tinyproxy.conf:/etc/tinyproxy/tinyproxy.conf:ro
- ./logs:/var/log/tinyproxy

第三步:启动并测试

1
2
3
4
5
6
7
8
9
10
11
# 启动
docker compose up -d

# 查看日志确认运行正常
docker logs tinyproxy

# 测试 HTTP 代理
curl -v -x http://127.0.0.1:8888 http://httpbin.org/ip

# 测试 HTTPS 代理(CONNECT 隧道)
curl -v -x http://127.0.0.1:8888 https://httpbin.org/ip

正常返回示例:

1
2
3
{
"origin": "你的代理服务器公网 IP"
}

第四步:客户端使用

Linux 环境变量

1
2
3
4
5
6
7
export http_proxy=http://代理IP:8888
export https_proxy=http://代理IP:8888
export no_proxy=localhost,127.0.0.1

# 之后 apt/wget/curl/pip/npm 都走代理
wget https://example.com
pip install requests

Docker 容器内使用

1
2
3
4
5
6
7
8
9
# 其他容器的 docker-compose.yml
services:
myapp:
image: myapp:latest
environment:
- http_proxy=http://tinyproxy:8888
- https_proxy=http://tinyproxy:8888
networks:
- proxy-net

5.2 serjs/go-socks5-proxy — SOCKS5 代理

go-socks5-proxy 是最轻量的 SOCKS5 代理,镜像仅 ~2MB(scratch + Go 静态二进制),通过环境变量即可配置认证和白名单,支持 amd64/arm64/armv7 多架构。

第一步:最简单 — 一行启动

1
2
3
4
5
6
7
docker run -d --name socks5 \
-p 1080:1080 \
-e PROXY_USER=myuser \
-e PROXY_PASSWORD='Str0ng!@#' \
-e ALLOWED_IPS=192.168.1.0/24,127.0.0.1 \
--restart unless-stopped \
serjs/go-socks5-proxy:latest

第二步(推荐):docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
version: '3.8'
services:
socks5:
image: serjs/go-socks5-proxy:latest
container_name: socks5
restart: unless-stopped
ports:
- "1080:1080"
environment:
# 认证(强烈建议设置)
PROXY_USER: myuser
PROXY_PASSWORD: 'Str0ng!@#'
# IP 白名单(逗号分隔)
ALLOWED_IPS: 192.168.1.0/24,10.0.0.0/8
# 可选:限制目标域名(正则)
# ALLOWED_DEST_FQDN: '.*\.example\.com'
1
docker compose up -d

第三步:测试

1
2
3
4
5
# 测试 SOCKS5 代理
curl -v --socks5 myuser:'Str0ng!@#'@127.0.0.1:1080 https://httpbin.org/ip

# 测试无认证模式(不推荐)
# 设置 PROXY_USER 和 PROXY_PASSWORD 为空即可

第四步:客户端使用

SSH 通过 SOCKS5 代理

1
2
3
4
5
6
7
# 方法一:ProxyCommand
ssh -o ProxyCommand="nc -x 代理IP:1080 -X 5 -P myuser %h %p" \
user@target-server

# 方法二:SSH 配置文件 ~/.ssh/config
Host jump-*
ProxyCommand nc -x 192.168.1.100:1080 -X 5 -P myuser %h %p

Git / 其他 TCP 工具

1
2
3
4
5
6
# Git 使用 SOCKS5 代理
git config --global http.proxy socks5://myuser:Str0ng\!@#@192.168.1.100:1080
git config --global https.proxy socks5://myuser:Str0ng\!@#@192.168.1.100:1080

# Python requests(需安装 pysocks)
pip install pysocks
1
2
3
4
5
6
import requests
proxies = {
'http': 'socks5://myuser:Str0ng!@#@proxy:1080',
'https': 'socks5://myuser:Str0ng!@#@proxy:1080'
}
requests.get('https://httpbin.org/ip', proxies=proxies)

5.3 环境变量速查

go-socks5-proxy 环境变量一览

变量说明默认值
PROXY_USER认证用户名空(无认证)
PROXY_PASSWORD认证密码
ALLOWED_IPS允许连接的客户端 IP(逗号分隔)空(全部允许)
ALLOWED_DEST_FQDN允许访问的目标域名(正则)空(全部允许)

新版 REQUIRE_AUTH 默认为 true,不设置用户名密码会启动失败。


六、安全建议

安全警告

裸奔的代理服务器几小时内就会被扫进代理池滥用!

  1. 限定来源 IP

Squid http_access / TinyProxy Allow / Dante client pass必须限定来源 IP 段

  1. 防火墙双保险

ufw allow from 192.168.1.0/24 to any port 8888 proto tcp

  1. 改默认端口

扫端口脚本 5 分钟就能找到 3128/1080/8888,改成非标端口

  1. 日志持久化

至少保留 access.log,挂载持久化卷,出问题才能追溯

合规提醒

公司网络出口代理需确保安全/合规策略。MITM 解密 HTTPS 流量在大多数司法管辖区需要明确告知用户。


参考链接