-
Notifications
You must be signed in to change notification settings - Fork 31
Port/Protocol Level Rules #72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
晚点我去跑跑看 😃 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
darwin上在修改了一个AutoRoute变量设置后可以正常执行,功能性没问题
目前还有几个问题:
- mac上dns劫持依赖写入/etc/resolver文件夹,大量规则写入会导致程序退出时删除文件缓慢
- parseResources里面有一个抽象的ip:port 格式的host,已添加了一个额外parser
- 有点没懂Resolve中咋不用dnsResource再检查一遍了
if cachedIP, found := r.getDNSCache(host); found { | ||
log.Printf("%s -> %s", host, cachedIP.String()) | ||
return ctx, cachedIP, nil | ||
} | ||
|
||
if r.dnsResource != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里是为啥不用r.dnsResource继续查找下发的域名解析规则了
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
对于那些严格的服务端来说,dnsResource 里面有域名并不能代表就可以访问,最后还是要靠之前那些细化到端口和协议的规则来走。如果解析出的 ip 在对应的 ip 资源里,那最终在 dial 函数里还是可以被正确分流,所以感觉不是很有必要?
大多数情况下 dnsResource 里面的 ip 在前面的资源里都是有对应的规则的(因为原版客户端就是这样工作的,解析出对应的 ip,ip 已经在之前解析资源的时候写入系统路由表了,这样才会被 EasyConnect 正确处理)
事实上那种严格的服务端即使域名在域名资源里也未必就允许 (#70) ,感觉域名资源更多是用来在客户端 GUI 里给用户显示的,实际上最后就是解析成 ip,分流的时候按路由表,然后 EasyConnect 客户端再看看符不符合端口和协议。之前加的 skip-domain-resource
就是不处理域名资源,只按 ip 资源分流
也可以考虑加一个参数分为严格模式和宽松模式,严格模式就只按 ip 资源分流,宽松模式就用域名、ip、dns 中的全部信息分流
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
大多数情况下 dnsResource 里面的 ip 在前面的资源里都是有对应的规则的
原来如此,那确实没有啥加的必要。 目前代码中dnsResource字段已经没啥用了,感觉可以加点相关的注释
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
大多数情况下 dnsResource 里面的 ip 在前面的资源里都是有对应的规则的
原来如此,那确实没有啥加的必要。 目前代码中dnsResource字段已经没啥用了,感觉可以加点相关的注释
啊,犯傻了,dnsResource 还是有用的,要按这个解析 IP,只是不作为判断分流的依据,结果我把这个逻辑全删了
我加回来(
stack/tun/stack_darwin.go
Outdated
} | ||
if err = s.AddDnsServer(s.endpoint.ip.String(), "cc98.org"); err != nil { | ||
log.Printf("AddDnsServer failed: %v", err) | ||
for domain := range domainResources { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在这里如果不使用硬编码AddDnsServer了的话,应该在程序initial_func_darwin里面检查删除一下所有之前添加的,暂时想到的方法是每个文件开头加一个 # Created By ZJU-Conenct 然后找这个
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
以及这里加的域名实在是有点多了,程序结束时删除就要删个10s左右,不知道怎么设计更好
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
以及这里加的域名实在是有点多了,程序结束时删除就要删个10s左右,不知道怎么设计更好
我倒是比较好奇 EasyConnect 的 Mac 客户端是怎么处理的,因为按照我对 Windows 客户端的观察 EasyConnect 干的事情是劫持 DNS,解析 ip,ip 提前按照资源写入系统路由表,靠路由表分流
如果 Mac 需要把要解析的资源加入 /etc/resolver/ 的话,那原版客户端是怎么实现的
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
之前是因为硬编码了domain所以发现通过创建/etc/resolver很方便,现在我看看networksetup -setdnsservers 和 修改/etc/resolv.conf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
现在使用networksetup -setdnsservers劫持了所有dns请求,目前已经可用了
|
||
log.DebugPrintf("Add IP: %s", hostStr) | ||
if isDomain { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里抓到一个非常奇怪的规则,被错误判定成domain了:
202.107.204.54:8080/cnipr/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
暂时添加了一个额外parser
看起来目前可以合了 |
All reactions
-
🎉 1 reaction
由于部分服务端(主要为 7.6.6 以上)对流量的校验很严格 (#65 #70),一旦进行了非法访问服务端会断开连接。ZJU 的服务端由于版本较老,暂未出现此问题,不过如果未来升级服务端版本也可能出现这种现象。
此 PR 添加了基于服务端下发资源的端口/协议级别的分流。主要修改有这几处:
解析服务端下发资源时精确到端口和协议。资源的格式如下:
type 0 是类似 webvpn 的访问方法,暂未实现,目前只对 type 1(TCP 应用) 和 type 2(L3VPN 应用) 进行解析。每条资源中给出了 host(可能为单个 IP 地址,或 StartIP ~ EndIP,或域名,或 URL),端口号(StartPort ~ EndPort,如果只有一个端口也是此格式),协议类型(0 为 TCP,1 为 UDP,2 为 ICMP,-1 猜测为全部)。这里粗略地将资源分为 IP 资源和域名资源。
DNS 解析时,如果发现匹配到域名资源,则将资源的具体信息 8000 端口范围、协议类型)保存到上下文中(因为此时并不能获得请求的端口和类型,无法判断是否走 VPN)。在 DialIPPort 函数中结合上下文和端口、协议进行判断。
gVisor 栈未做修改,因为 gVisor 栈上的流量一定来自于 Dial 函数,已经进行了完善地分流。TUN 栈进行了修改:
此处将 DNS 劫持的逻辑前移,并添加了 IP、端口和协议的判断。一是因为路由规则不可能精确到端口和协议,高版本服务器即使只是访问了不能访问的端口也会断开连接。二是 TUN 上总有一些其他的流量(如 mDNS),无视路由,这部分流量也需要筛除。
为了更好适配其他服务端,删除了一些 ZJU 独有的硬编码的内容(如 TUN 改为了 /32 等等),这些内容通过 ZJUConfig 参数选择性添加。还请 @cxz66666 帮忙看看会不会破坏了 darwin 等系统上的 TUN 功能。