标有“代理”的四种协议除了名称之外几乎没有共同点。HTTP 代理解析第 7 层并重写标头;SOCKS 代理完全不读取你的流量。这一区别决定了哪种代理适合浏览、爬取和原始隧道传输。
HTTP 代理
HTTP 代理期望 HTTP 语义。它打开请求、读取 URL、可以附加诸如 Via 或 X-Forwarded-For 之类的标头,并拒绝任何不是有效 HTTP 请求的内容。浏览器、curl 以及大多数爬取库默认使用 HTTP 代理,因为配置几乎零成本——设置一个环境变量或传递一个标志即可。
这种简单性的代价是可见性。代理可以看到完整的 URL,包括路径和查询字符串,在明文 HTTP 中它还能看到请求体。缓存代理可以重写响应;透明代理可以剥离 Cookie。请将任何 HTTP 代理视为完全特权的中间人,切勿通过明文发送凭据。
HTTPS 代理与 CONNECT 方法
“HTTPS 代理”这个标签略有误导。它指的是额外实现了 CONNECT 方法的 HTTP 代理。CONNECT 告诉代理打开一个到目标主机的原始 TCP 隧道,并在两个方向传输字节;客户端和目标随后协商 TLS,就好像代理不存在一样。代理能看到目标主机和端口以及字节量,但看不到有效载荷。
因此,“支持 HTTPS”的代理是一个支持隧道传输 TLS 的代理,而不是自身运行在 TLS 之上的代理。从你的机器到代理的链路可以独立地是明文或加密的。如果你关心该链路的保护,请使用基于 TLS 的 SOCKS5 实现,或者发布其 TLS 端点的付费商业代理。
SOCKS4
SOCKS4 是 1994 年的最低标准:仅 TCP、仅 IPv4、无 UDP、无 IPv6、无认证、代理端不解析主机名。握手过程为六个字节加上一个字节的响应码。它之所以在现实中存活,是因为该协议非常小,几乎任何支持 TCP 的工具都能正确实现。如果某个列表宣传 SOCKS4,那么期望的是到 IPv4 地址的原始 TCP 转发——仅此而已。
SOCKS5
SOCKS5 定义于 RFC 1928(1996 年),是现代工具最常使用的版本。它增加了 UDP 转发、IPv6 地址、GSSAPI 认证,以及由代理而非客户端解析主机名的选项。由于 SOCKS5 不对上层的应用层做任何假设,因此对于非 HTTP 工作负载(SSH、IRC、BitTorrent、自定义 RPC)来说,它是最灵活的选择。
性能与开销
SOCKS 代理的每请求开销较低,因为它们不解析任何内容。HTTP 和 HTTPS 代理每次连接都要付出完整的请求解析代价。对于 CONNECT 内部单个长生命周期的 TLS 会话,差异可以忽略不计。但对于数千个短请求(代理每次打开新连接),SOCKS5 明显胜出——通常每个请求在解析路径上节省 2–5 毫秒。
匿名性的实际表现
一个不剥离你标头的 HTTP 代理可能会通过 Via、X-Forwarded-For 或 Forwarded 泄露你的客户端 IP。SOCKS 代理没有此类标头,因为它们根本没有标头的概念。这与其说是匿名特性,不如说是缺少泄露面。在 CONNECT 隧道化的 HTTPS 内部,目标只能看到 TLS 握手,因此代理端的任何 HTTP 级别泄露都无关紧要。
端口惯例
你会在本目录中看到这些端口:80、8080、3128、8888 用于 HTTP;443 用于明确支持 CONNECT 的端点;1080 用于 SOCKS。许多提供商暴露非标准的高端口(10000 以上)以规避随意的端口扫描。端口号本身并不能说明质量——它只表明运营商选择暴露什么。