为啥 SOCKS5 需要通过 UDP 中继 UDP?

Posted

技术标签:

【中文标题】为啥 SOCKS5 需要通过 UDP 中继 UDP?【英文标题】:Why does SOCKS5 require to relay UDP over UDP?为什么 SOCKS5 需要通过 UDP 中继 UDP? 【发布时间】:2017-01-31 20:48:37 【问题描述】:

RFC1928 描述的SOCKS5 协议提供对 UDP 的支持。

总而言之,希望通过 SOCKS5 服务器中继 UDP 数据包的客户端至少必须:

打开与 SOCKS5 服务器的 TCP 连接; 发送UDP ASSOCIATE 请求(参见section 4); 从服务器接收它必须发送要中继的 UDP 数据包的地址和端口; 将数据报 (UDP) 发送到该地址,并用一些标头封装(参见 section 7)。

以下是一些相关的引用,来自section 6:

当 UDP ASSOCIATE 请求到达的 TCP 连接终止时,UDP 关联终止。

在对 UDP ASSOCIATE 请求的回复中,BND.PORT 和 BND.ADDR 字段指示客户端必须发送要中继的 UDP 请求消息的端口号/地址。

和section 7:

基于 UDP 的客户端必须在对 UDP ASSOCIATE 请求的回复中通过 BND.PORT 指示的 UDP 端口将其数据报发送到 UDP 中继服务器。

为什么这么复杂? 为什么不在预先存在的 TCP 连接中发送 UDP 数据包?

编辑: 对于clarify,我希望 SOCKS 代理通过 TCP 流接收 UDP 数据包,然后使用实际的 UDP 将它们传输到目标。然后从目标接收 UDP 数据包并将它们发送回 TCP 流。


这里有一些上下文。

我的目标是实现反向网络共享,以便 android 设备可以使用它所插入的计算机的互联网连接,而无需在设备和计算机上都进行 root 访问 (@987654328 @ 有效,但需要计算机上的 root 访问权限)。

我的第一个想法是在电脑上用ssh -D启动一个简单的SOCKS5服务器,这样我只需要实现客户端。由于adb reverse提供的远程端口转发,数据包将通过adb从设备传输到计算机......

不幸的是,OpenSSH SOCKS 服务器does not support UDP。但这只是实现的一个限制,我可以使用另一个 SOCKS 服务器。

但是,adb reverse 也不支持 UDP 转发。

因此我的问题是关于 SOCKS5 协议。

我目前正在编写一个 PoC,通过 TCP 实现我自己的(简单)协议,该协议能够中继 UDP 数据包,但我很失望不能使用标准协议(并从现有实现中受益)。

【问题讨论】:

您不能通过 TCP 连接发送数据报。 TCP 是一种字节流协议。这个问题要有意义。 我的意思是,当然,一个包裹在 TCP 流上的 UDP 数据包,作为有效负载。 @rom1v:如果 UDP 数据包被包装在 TCP 流中,它就不再是 UDP,而是 TCP。代理后面的现有 UDP 软件不知道进行 TCP 包装。想到的一种情况是一个应用程序连接到 SOCKS 代理并打开 UDP 中继端口,然后另一个应用程序通过代理实际发送 UDP 数据包。因为 UDP 是无连接的,所以没有什么可以阻止这一点。没有什么要求打开 UDP 端口的应用程序和发送到 UDP 数据的应用程序是同一个应用程序。另一方面,TCP 不允许这样做。 @rom1v:您是否希望 SOCKS 代理通过 TCP 流接收 UDP 数据包,然后使用实际的 UDP 将它们传输到目标?然后从目标接收 UDP 数据包并将它们发送回 TCP 流? @Remy Lebeau 没错。我编辑了我的问题以添加您的公式,这是完美的;-) 【参考方案1】:

我在回答我自己的问题:可能是为了避免 TCP 机制(数据包重传,head-of-line blocking...)。

对于一个本地的reverse tethering工具,这不是问题,所以我在不使用SOCKS的情况下实现了UDP over TCP。

【讨论】:

以上是关于为啥 SOCKS5 需要通过 UDP 中继 UDP?的主要内容,如果未能解决你的问题,请参考以下文章

关于SOCKS5中UDP请求的问题

socks5udp转发不通过

使用Python通过Tor(SOCKS5)发送UDP请求

Socks5 udp代理

Gstreamer:为啥我不能在 localhost 上通过 UDP 发送数据?

为啥即使使用 HTML5 也没有通过浏览器的 UDP 连接?