SOCKS5代理认证中继:自己构建还是完全跳过

Chrome和许多自动化工具仍无法认证SOCKS5代理。一个小型本地中继可以通过保存凭据来解决这个问题——这里有一个最小可行的中继、现成的工具,以及在某些情况下你完全不需要它。

SOCKS5代理认证中继是一个小型本地进程,它代表你回答代理的用户名/密码挑战,然后将你的工具连接到127.0.0.1上的一个无认证端点。它的存在是为了弥补一个顽固的缺口:Chromium从未支持认证的SOCKS5(追踪为Chromium bug 40829748),而许多自动化工具只接受裸host:port。一个在Reddit上流传的帖子——有人因为工具仍无法处理认证的SOCKS5而沮丧到构建一个小中继——就是这种情况的缩影。本指南展示了一个最小可行的中继、现成的工具,以及同样重要的,何时不需要它。

模式:前端无认证,后端认证

这个领域的每个中继都做同样的事情。它在本地监听,无需认证,并为每个连接使用你的真实凭据打开上游连接。你的工具连接到127.0.0.1——无需密码——中继执行SOCKS5认证握手到SOCKS5网关。凭据保存在一个地方,在环回接口上,从不接触工具的配置。这很重要的第二个原因是:SOCKS5没有加密,凭据以明文传输,所以将认证连接保持在你自己的机器上,绑定到127.0.0.1,是安全的做法。

单命令中继:gost

你很少需要手写一个中继。gost是一个开源的隧道工具,实施了完整的SOCKS5规范,包括用户名/密码认证,并将整个工作变成一个命令。在本地暴露一个无认证的SOCKS5监听器并转发到你的认证上游:

# local no-auth SOCKS5 on :1080  ->  authenticated SOCKS5 upstream
gost -L socks5://:1080 -F socks5://USER:PASS@gate.quantumproxies.io:PORT

# now point any tool at the loopback address, no credentials:
#   --proxy-server=socks5://127.0.0.1:1080   (Chrome, nodriver, zendriver)

如果你的工具支持HTTP但不支持SOCKS5,同样的命令可以转换协议——暴露一个本地HTTP代理,转发到认证的SOCKS5网关。这是对反复出现的“将SOCKS5转换为HTTP代理”问题的简洁答案,并且优于经典的Privoxy配置,因为gost在一个地方处理了上游认证:

# local HTTP proxy on :8080  ->  authenticated SOCKS5 upstream
gost -L http://:8080 -F socks5://USER:PASS@gate.quantumproxies.io:PORT

# Chrome/curl/anything with an HTTP proxy setting can now use 127.0.0.1:8080
本地SOCKS5认证中继的流程图:一个工具连接到无认证的环回监听器,添加凭据并转发到认证的代理网关
中继将凭据保存在环回接口上并执行SOCKS5认证握手,因此工具只会看到一个无认证的端点。

从头开始的最小中继

如果你想了解运作的部分,这里是一个用纯Python编写的最小实用版本。它使用PySocks(pip install PySocks)打开认证的上游连接,并双向传输字节。这个特定的草图隧道一个目标主机——足以通过认证的SOCKS5出口抓取单个API——这使得它简短且正确;一个解析客户端握手的通用SOCKS5服务器是像gost这样的工具已经为你做的:

import asyncio, socks   # PySocks

UP_HOST, UP_PORT = "gate.quantumproxies.io", 0000   # your SOCKS5 gateway
UP_USER, UP_PASS = "USER", "PASS"
TARGET = ("example.com", 443)                        # the one host to reach

async def pipe(reader, writer):
    try:
        while data := await reader.read(65536):
            writer.write(data)
            await writer.drain()
    finally:
        writer.close()

async def handle(local_r, local_w):
    # open the upstream leg with SOCKS5 auth (PySocks is blocking -> a thread)
    up = await asyncio.to_thread(
        socks.create_connection, TARGET,
        proxy_type=socks.SOCKS5, proxy_addr=UP_HOST, proxy_port=UP_PORT,
        username=UP_USER, password=UP_PASS,
    )
    up_r, up_w = await asyncio.open_connection(sock=up)
    await asyncio.gather(pipe(local_r, up_w), pipe(up_r, local_w))

async def main():
    server = await asyncio.start_server(handle, "127.0.0.1", 1080)
    async with server:
        await server.serve_forever()

asyncio.run(main())

对于任何客户端都可以指向的完整本地SOCKS5服务器,GitHub上的社区项目socks-relay是一个很好的参考:它运行一个无认证或用户/密码监听器并中继到另一个SOCKS5服务器,基于PySocks构建的几百行代码。如果你更喜欢编译的二进制文件,socks-to-http-proxy项目(Rust)可以完成HTTP转换工作。无论哪种方式,你都在运行与gost在一行中提供的相同模式。

何时不需要中继

中继是你拥有的一个跳点,通常你可以删除整个问题。当以下任意一项为真时,跳过它:

# no relay needed — curl authenticates SOCKS5 directly (socks5h resolves DNS
# through the proxy, avoiding leaks):
curl -x socks5h://USER:PASS@gate.quantumproxies.io:PORT https://httpbin.org/ip

# and HTTP Basic proxy auth is even more widely supported:
curl -x http://USER:PASS@gate.quantumproxies.io:PORT https://httpbin.org/ip
比较何时不需要SOCKS5认证中继与何时它物有所值的清单,涵盖HTTP端点、IP白名单、本地库支持和Chromium的SOCKS5缺口
大多数设置可以跳过中继:HTTP端点、IP白名单或本身支持SOCKS5认证的客户端都消除了对中继的需求。

诚实的缺点

运行你自己的中继增加了一个故障点。它是另一个需要监督的进程:如果它崩溃,后面的每个请求都会失败,而一个裸脚本没有重启、健康检查和日志记录,除非你添加它们。它没有自己的轮换——它转发到你配置的单一上游,所以出口轮换仍然必须来自网关。它增加了一个延迟的跳点,并在内存中保存明文凭据,这正是为什么它必须绑定到127.0.0.1而不是公共接口。对于一个抓取单个网站的笔记本电脑来说,这没问题。对于任何你需要监控的东西,优先选择没有新活动部件的解决方案——白名单或HTTP端点——而不是你现在必须保持活跃的中继。

相同的中继模式在隐形生态系统中反复出现,因为Chromium的SOCKS5缺口是每个基于它的浏览器共享的。如果你要将其接入特定框架,请参阅Playwright SOCKS5认证和我们的407故障排除指南,了解你在过程中可能遇到的错误。

常见问题解答

什么是SOCKS5代理认证中继?

一个小型本地进程,它在没有认证的情况下监听,并使用你的用户名和密码将每个连接转发到上游SOCKS5代理。它允许无法发送SOCKS5凭据的工具——主要是基于Chromium的浏览器——通过指向127.0.0.1:1080这样的环回地址来连接到认证代理。gost可以通过一个命令创建一个。

如何将SOCKS5代理转换为HTTP代理?

你不能转换代理本身;你需要运行一个在本地支持HTTP并在上游支持SOCKS5的中介。gost -L http://:8080 -F socks5://USER:PASS@host:port暴露一个本地HTTP代理,转发到认证的SOCKS5网关。像socks-to-http-proxy和Privoxy这样的专用工具也可以完成相同的工作,如果你更喜欢它们。

为什么Chrome不能使用认证的SOCKS5代理?

Chromium从未实现SOCKS5用户名/密码认证——这是一个长期存在的限制,记录为Chromium bug 40829748。未经认证的SOCKS5可以通过--proxy-server=socks5://host:port工作,但没有办法提供凭据。一个本地中继或IP白名单是标准的解决方案,而一个代理认证扩展涵盖了HTTP代理。

将SOCKS5凭据发送到中继是否安全?

仅限于环回。SOCKS5没有加密,并以明文传输凭据,因此中继必须绑定到127.0.0.1而不是公共接口——这使得认证连接保持在你自己的机器上。无论如何,目标的加密隧道是端到端建立的,因此中继只会看到它无法读取的TLS字节。

仅在工具没有其他选择时才使用中继。gost是一行答案,PySocks是从头开始的解决方案——但对大多数人来说,最快的解决方案是白名单一个IP或使用HTTP端点,完全不运行额外的东西。更少的活动部件,更少的凌晨3点的警报。

获取带IP白名单的SOCKS5代理