把 Socket.Connect() 指向 SOCKS 服务器只是与该服务器建立了一条 TCP 连接。接下来的字节仍然必须说 SOCKS。立即发送应用协议会让服务器等待另一段对话。

在 SOCKS5 中,建立连接包括方法协商、任何被选中的认证交换,以及指明目的地的请求。只有成功的应答才会为应用字节打开通路。这些阶段定义在 RFC 1928 中。

把协商留在连接层

拥有自己 TCP 协议的应用可以使用一个懂代理的连接器,由它返回已建立的流。应用其余部分随后通过该流读写。连接器必须考虑部分读取、可变长度地址、认证失败以及协商的截止时间。

手写的实现如果只读取一个固定大小的缓冲区并假定成功,是很脆弱的。TCP 并不保留 SOCKS 消息的边界。在开始应用协议之前,要读取按其地址类型所描述的完整应答。适用于 .NET 7+ 的 CONNECT 应答读取器 演示了这一步。

如果某个仍在维护的库已经提供了这一连接层,请检查它支持的 SOCKS 版本、认证方法以及目标框架。十年前论坛里的链接只是调查的起点,并不能证明如今的兼容性。

HTTP 客户端配置属于另一个范围

HTTP 客户端的代理设置只配置该 HTTP 客户端。它不会修改进程中的每一个原始 socket。Socket API 接受一个网络端点,把更高层的协商留给调用者。

对于加密的应用协议,要在代理隧道建立之后执行它的 TLS 握手。并在这一阶段验证预期的目的地身份。代理认证和目的地认证虽然使用同一条底层流,但仍彼此独立。

相关文章