轮换代理网关:为您的整个代理池提供一个本地 SOCKS5 或 HTTP 端点
将每个工具指向一个本地 SOCKS5 或 HTTP 端点,让一个小型网关服务为每个连接选择一个上游代理——附带配置、粘性会话、健康检查、DNS 和泄漏验证。
轮换代理网关:为您的整个代理池提供一个本地 SOCKS5 或 HTTP 端点
在代码内部轮换代理可以正常工作,直到第二个工具出现。现在你有一个带中间件的爬虫、一个手动操作的浏览器、一个只有一个代理字段的 CLI 排名检查器,以及一个别人写的 cron 任务——每个都以自己的方式轮换,或者根本不轮换。
轮换代理网关消除了这种重复。你在本地(或 VPS 上)运行一个小型服务,将所有内容指向 127.0.0.1:8080,网关会为每个连接选择一个上游代理。本指南涵盖该服务是什么、何时值得额外一跳、如何用可读的配置构建一个,以及如何在对生产工作信任它之前验证轮换、DNS 解析和泄漏行为。
轮换代理网关到底是什么
它是代理的负载均衡器。请求路径如下:
- 客户端 — 浏览器、
curl、Scrapy、Selenium、桌面应用 - 网关 — 你机器上的本地 HTTP 或 SOCKS5 监听器
- 选择 — 网关从你的池中挑选一个上游
- 出口节点 — 上游代理发出出站请求
- 目标站点 — 看到出口节点的 IP,而不是你的
网关不会让代理更快、更私密或更可靠。它集中了选择、凭证和健康,这与客户端轮换解决的问题不同。
何时网关优于在代码内部轮换
在以下情况下使用网关:
- 多个工具需要代理,而其中只有部分原生支持轮换
- 当提供商轮换你的密码或端口时,你希望有一个地方更新凭证
- 你需要为登录流程提供粘性会话,同时为爬取提供按请求轮换
- 你希望有一个单一位置来运行健康检查、封禁检测和上游评分
- 你希望跨客户端保持一致的 DNS 行为,而不是每个库的怪癖
- 之后你可能将工作负载从笔记本电脑移到 VPS 或 CI 运行器
在以下情况下跳过网关:
- 你只有一个客户端,并且它已经有很好的中间件(例如 Scrapy 的轮换代理中间件)
- 轮换取决于每个请求的业务规则——地理目标、账户、价格层级
- 你需要所用确切上游的按请求延迟和失败统计,而你的网关没有暴露这些
额外一跳会带来一点延迟。对于大多数自动化来说,与出口节点自身的响应时间相比,这只是一个舍入误差。
首先选择监听器协议
| 监听器 | 客户端支持 | 认证 | DNS 行为 | 注意事项 |
|---|---|---|---|---|
| HTTP (CONNECT) | 几乎通用,包括只有“HTTP 代理”字段的应用 | 基本认证被广泛支持 | 取决于上游连接器 | 明文 HTTP 请求在网关处可读;一些工具发送绝对 URL |
| SOCKS5 | 浏览器通过各种标志、curl、大多数爬虫和 CLI 工具 |
用户名/密码(RFC 1929) | 主机名可以转发到上游进行远程解析 | iOS 和 Android 上的系统代理对话框没有 SOCKS5 选项 |
如果不确定,在同一个池上运行两个监听器,使用两个端口。除了多一个配置块,没有任何损失。
一个 DNS 细节比人们预期的更重要。如果网关自己解析目标主机名,那么地理准确的结果反映的是网关的解析器,而不是出口节点的位置。将主机名传递到下游——socks5h 风格的行为——将解析保留在出口节点,这对于位置敏感的数据正是你想要的。
使用 gost 构建一个
gost 是一个单一的 Go 二进制文件,支持 HTTP、SOCKS5,并且可以链式连接或平衡上游节点列表。版本很重要:v3 系列使用 YAML 配置文件,而旧版本依赖命令行标志。首先确认你拥有什么。
curl -s https://api.github.com/repos/go-gost/gost/releases/latest | grep tag_name
gost -V
以下是一个最小轮换设置,包含两个上游 SOCKS5 出口,同时暴露为 HTTP 和 SOCKS5 监听器:
services:
- name: pool-http
addr: \":8080\"
handler:
type: http
chain: pool
listener:
type: tcp
- name: pool-socks
addr: \":1080\"
handler:
type: socks5
chain: pool
listener:
type: tcp
chains:
- name: pool
hops:
- name: hop-0
selector:
strategy: round
nodes:
- name: exit-a
addr: 203.0.113.10:1080
connector:
type: socks5
metadata:
username: user
password: pass
- name: exit-b
addr: 203.0.113.11:1080
connector:
type: socks5
metadata:
username: user
password: pass
测试时在前台运行:
gost -C /etc/gost/gateway.yaml
不同构建版本的选择策略不同——round 按顺序循环节点,一些版本添加随机或基于哈希的选择。检查你的确切版本的 selector 文档,而不是假设某个策略名称存在;如果你需要的功能缺失,下一节中的按策略分配端口的技巧通常也能让你达到目的。
对于任何长期运行的东西,unit 文件胜过一个终端窗口:
[Unit]
Description=Rotating proxy gateway
After=network-online.target
[Service]
ExecStart=/usr/local/bin/gost -C /etc/gost/gateway.yaml
Restart=on-failure
User=gost
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
无需特殊功能的粘性会话
许多任务需要与轮换相反的东西:结账流程、经过身份验证的仪表板或多步表单需要在几分钟内使用相同的出口 IP。与其追求粘性会话标志,不如针对两条链运行两个监听器——一个平衡,一个固定。
services:
- name: pool-http
addr: \":8080\"
handler:
type: http
chain: pool
listener:
type: tcp
- name: pinned-http
addr: \":8081\"
handler:
type: http
chain: pinned
listener:
type: tcp
chains:
- name: pool
hops:
- name: hop-0
selector:
strategy: round
nodes:
- name: exit-a
addr: 203.0.113.10:1080
connector:
type: socks5
- name: exit-b
addr: 203.0.113.11:1080
connector:
type: socks5
- name: pinned
hops:
- name: hop-0
nodes:
- name: exit-a
addr: 203.0.113.10:1080
connector:
type: socks5
端口 8080 为爬取而轮换,端口 8081 为一个出口保持用于会话工作。要固定不同的出口,更改一个地址并重新加载。同样的模式为排名跟踪提供按国家/地区的网关:每个目标国家/地区一个端口,每个端口固定到该国家/地区的出口。
验证轮换、DNS 和泄漏
永远不要假设网关正在执行配置所说的内容。两分钟的验证可以节省一周的混乱数据。
从针对 HTTP 监听器的 shell 循环开始:
for i in 1 2 3 4 5; do
curl -s --max-time 15 --proxy http://127.0.0.1:8080 https://api.ipify.org?format=json
echo
done
五次运行应该显示不止一个出口 IP。如果每一行都相同,那么你的选择器没有轮换,或者你只有一个健康的节点。
然后从你实际使用的客户端库确认同样的事情:
import requests
GATEWAY = \"http://127.0.0.1:8080\"
proxies = {\"http\": GATEWAY, \"https\": GATEWAY}
for i in range(5):
r = requests.get(
\"https://www.cloudflare.com/cdn-cgi/trace\",
proxies=proxies,
timeout=20,
)
trace = dict(line.split(\"=\", 1) for line in r.text.strip().splitlines())
print(i, trace.get(\"ip\"), trace.get(\"loc\"))
loc 字段告诉你 Cloudflare 看到请求来自哪个国家/地区——有助于发现悄悄在本地解析 DNS 并将流量落到错误区域的网关。
对于 SOCKS5 监听器,特意比较两种主机名形式:
curl -s --proxy socks5h://127.0.0.1:1080 https://api.ipify.org
curl -s --proxy socks5://127.0.0.1:1080 https://api.ipify.org
两者都应该能访问互联网;区别在于主机名还是解析后的地址传输到出口节点。对于地理敏感的工作,远程解析是你想要的,并且需要端到端支持——网关和上游都支持。
一个简短的泄漏检查清单:
- 任何响应都不应显示你的真实 ISP 分配的 IP
- 重复运行应显示变化(对于固定端口,则是故意的常量)
- 地理字段应与你配置的池匹配,而不是你自己的位置
- 基于浏览器的测试需要单独的 WebRTC 和 DNS 检查——网关无法修复 WebRTC 泄漏
- 经过认证的上游应该大声失败,而不是静默回退到直接连接
运维:加固、健康检查以及关于限制的诚实
一个能工作的网关很容易。一个安全的网关需要一些额外的决策:
- 默认绑定到
127.0.0.1。在0.0.0.0上的未认证代理一旦防火墙出现漏洞,就会成为开放中继。 - 如果你的构建支持监听器认证,请打开它。如果不支持,通过 SSH 隧道访问网关,而不是暴露端口。
- 将凭证保存在一个具有严格权限的文件中,不要分散在脚本中。
- 添加日志轮换,如果流量涉及任何敏感内容,在记录完整 URL 之前要三思。
- 记住网关不会增加容量。你的上游池的并发限制仍然是上限。
一个简单的健康检查胜过聪明的健康检查。此脚本标记失效的上游,以便你可以从配置中移除它们:
#!/usr/bin/env bash
while read -r host port; do
if curl -s --max-time 8 --proxy \"socks5h://${host}:${port}\" https://api.ipify.org >/dev/null; then
echo \"ok ${host}:${port}\"
else
echo \"dead ${host}:${port}\"
fi
done < upstreams.txt
按计划运行它,过滤掉失效的条目,然后重新加载。这个单一的习惯可以防止大多数“为什么我的爬虫突然被屏蔽了”的早晨。
最后,保持在界限内:只使用你被授权使用的代理,并尊重每个目标网站的条款、robots 指令和速率限制。网关使发送流量更容易——它不会使不受欢迎的流量变得可接受。
这如何与你已经运行的工具配合
如果某个库已经轮换得很好,就保留它。网关补充而不是取代 Python 的 requests、Scrapy 或 Selenium 中的按请求中间件;它覆盖了完全没有轮换方案的工具,并为 rank-tracker 风格的工作负载提供每个国家/地区的固定出口。如果你正在专门权衡客户端与网关轮换用于爬取,我们的“用于网页爬取的轮换代理”指南涵盖了中间件模式,而 Selenium 轮换代理演练涵盖了使网关首先具有吸引力的浏览器启动约束。
简短版本
- 轮换代理网关是代理的本地负载均衡器:一个端点,多个上游
- 同时运行 HTTP 监听器和 SOCKS5 监听器;为粘性工作运行一个固定到一个节点的第二个端口
- 当位置重要时,将 DNS 解析保留在出口节点
- 在对设置信任之前,用针对
api.ipify.org和cdn-cgi/trace的循环进行验证 - 绑定到 localhost,如果可以的话进行认证,并安排健康检查,以便失效的出口离开池