ciaoSora
215 天前
楼上们说的应该是正解,内核不支持,按照我的理解,原因如下:
TCP 是全双工保证按序交付的传输层协议,所以 Linux 内核支持获取 REDIRECT 之前的 destination 。一个 TCP 连接是以 (Src IP, Src Port, Dst IP, Dst Port) 四元组作为唯一标识的,当真实 destination 发送 TCP 数据包到透明代理时,透明代理知道要把数据返回给 source IP ,因为透明代理内部把 (Src IP, Src Port, Proxy IP, Proxy Port) 和 (Proxy IP, Proxy Client Port, Dst IP, Dst Port) 这两个四元组建立了联系,代理程序清楚地知道,当自己的 Proxy Port 收到来自 source 的数据时,要原封不动地通过第二个 TCP 连接发送给 destination ;当自己的 Proxy Client Port 收到来自 destination 的数据时,要原封不动地通过第一个 TCP 连接发送给 source 。
UDP 几乎就只是在 IP 的基础上加了 Src Port 和 Dst Port ,什么其他功能都没有(不是双工、不保证交付、不一定按序)。假设采取了跟 TCP 一样的原理,当 Proxy Client Port 收到来自 destination 的数据时,能理所当然地直接用 Proxy Port 发回给 source 吗?举个例子,一个人通过 email 投递简历到某公司的 HR 邮箱里( source 是这个人,destination 是 HR ),HR 读了之后感觉很优秀,认为需要直接让 CEO 跟你对接,于是他把 email 转发给了 CEO ( destination 把数据发给了 thirdparty),CEO 看完了之后,回了你一封邮件( thirdparty 发数据给 source )。假设在 source 前面有一个透明代理,如果他收到的是 HR 的回信那还好,直接理所当然地转回给 source 。但如果是刚刚的情况呢? HR 没有直接回你,而是让 CEO 回复你,这时透明代理就不知道应该转回给谁了。正因如此,内核就直接不支持获取 REDIRECT 之前的 destination 是什么,因为 UDP 本来是一种不需要建立连接的协议,仅从 UDP 这一层的角度(而不从应用层协议的角度)出发,REDIRECT 之前的 IP 是没意义的。当然应用层的协议可能刚好规定,若 source 给 destination 发数据,那么 destination 必然要跟 source 回复,但是无论应用层怎么规定,UDP 这个传输层的协议是不知道的,也不能做任何乐观假设。
感觉 tproxy 或者其他能代理 UDP 的解决方案,应该就是乐观假设了「 CEO 给你回信」这个场景不会发生?有了这个假设之后,透过其他技术手段(毕竟内核不直接支持)获取到 REDIRECT 之前的 destination 之后,就可以用类似 TCP 的方式把来自 destination 的数据回复给 source 了。
不知道说得对不对,希望大佬能纠正我 =_=