eycorsican / go-tun2socks

A tun2socks implementation written in Go.
MIT License
1.29k stars 431 forks source link

fix UDP ASSOCIATE is inconsistent with rfc1928 #136

Closed lucashanmail closed 3 years ago

lucashanmail commented 3 years ago

refer: https://github.com/ginuerzh/gost/issues/96

eycorsican commented 3 years ago

how does this relate to the issue you're referring? if we should set dst.addr and dst.port in the associate request, and if it's not the target address, then what?

lucashanmail commented 3 years ago

抱歉,昨天有点晚,没写说明。

我看 rfc1928 的理解是, UDP ASSOCIATE 请求的 DST 地址是客户端向socks5服务器发udp包的源地址,不是目标网站的地址。 当由于存在 nat 等情况,socks5客户端无法确定 udp 包源地址时,应该设置为 0 。socks5 服务端会根据这个地址限制来源的udp包,非指定的源地址的包会被丢弃。如目前使用了目标网站地址,会造成 tun2socks 无法和严格实现 rfc1928 的服务端配合工作

参考:

https://tools.ietf.org/html/rfc1928

UDP ASSOCIATE

   The UDP ASSOCIATE request is used to establish an association within
   the UDP relay process to handle UDP datagrams.  The DST.ADDR and
   DST.PORT fields contain the address and port that the client expects
   to use to send UDP datagrams on for the association.  The server MAY
   use this information to limit access to the association.  If the
   client is not in possesion of the information at the time of the UDP
   ASSOCIATE, the client MUST use a port number and address of all
   zeros.

   A UDP association terminates when the TCP connection that the UDP
   ASSOCIATE request arrived on terminates.

   In the reply to a UDP ASSOCIATE request, the BND.PORT and BND.ADDR
   fields indicate the port number/address where the client MUST send
   UDP request messages to be relayed.

https://blog.csdn.net/whatday/article/details/40183555

      o  DST.PORT  这个很重要,要填客户端想发送/接收UDP包的本地端口。后面在
发送UDP包时代理服务器会检测收到的UDP包的源端口,只有和这里填入的端口号
符合的包才会被处理。(CCProxy收到源端口错误的包会出bug,狂发包。)

https://www.cnblogs.com/Full--Stack/p/8041880.html

假设CMD为UDP ASSOCIATE。此时DST.ADDR与DST.PORT指明发送UDP报文时的源IP、源
端口,而不是UDP转发目的地,SOCKS Server可以据此进行评估以决定是否进行UDP转
发。如果SOCKS Client发送UDP ASSOCIATE命令时无法提供DST.ADDR与DST.PORT,则
必须将这两个域置零。

下面是一些讨论记录:

scz

什么情况下SOCKS Client发送UDP ASSOCIATE命令,又无法提供DST.ADDR与DST.PORT,
或者说出于什么考虑才需要刻意将这两个域置零。有现实例子存在吗。

shixudong@163.com

考虑这种情况:

Application Client - SOCKS Client - NAT - SOCKS Server - Application Server

SOCKS Client在UDP ASSOCIATE命令中指明DST.ADDR/DST.PORT,SOCKS Server靠这些
信息决定是否转发某个UDP报文。上图中SOCKS Client与SOCKS Server之间有NAT,前
者无法预知UDP报文经过NAT后源IP、源端口会变成什么样,但肯定会变,因此前者无
法提前在UDP ASSOCIATE命令中指明DST.ADDR/DST.PORT,如果强行指定非零值,后者
会检测到待转发UDP报文的源IP、源端口与DST.ADDR/DST.PORT不匹配而拒绝转发。针
对这种情况,RFC 1928建议SOCKS Client将DST.ADDR/DST.PORT置零,SOCKS Server
此时不再检查待转发UDP报文的源IP、源端口。
eycorsican commented 3 years ago

有道理。