yichya / luci-app-xray

(Almost) full feature Xray client for OpenWrt
Mozilla Public License 2.0
600 stars 513 forks source link

support transparent proxy ports filter(fw4) #299

Closed lialosiu closed 1 year ago

lialosiu commented 1 year ago

对应这个issue #244

加入了透明代理中按需转发端口的支持

(我的英文有点烂,大佬看下配置页面的那几行英文描述写得有没啥问题.....😂

yichya commented 1 year ago

你需要 rebase master 一下,你的 commit 把 67d24545e8a60fec8fb358fb445bdb1648de455e 的改动覆盖掉了。

lialosiu commented 1 year ago

刚刚发现了,改好了,应该是我用2.0.0的代码复制粘贴的时候不小心盖掉了😂

yichya commented 1 year ago

然后,考虑一下能不能同时支持一个反向的开关(就只有一部分端口不代理,其他正常走代理那种),以及提上来之前 squash 一下合并成一个 commit

lialosiu commented 1 year ago

好嘞

lialosiu commented 1 year ago

改成了默认端口策略可选为 bypassed / forwarded,根据默认策略提示用户输入要 直出/转发 的端口列表 另外处理了下列表为空时的bug

yukeiyang commented 1 year ago

要小心处理 53 等 UDP 端口,错误配置会导致国内网站全部错误解析到不当的海外 CDN 节点。

我编译了包含 support transparent proxy ports filter(fw4) 的固件,发现一旦使用 Forwarded TCP Ports & Forwarded UDP Ports 选项并保持默认,163.com 等国内站点的打开会极其缓慢并难以忍受。

而采用 Bypass TCP Ports 排除法来排除 22, 3306, 3389 等端口的话,访问国内网站会恢复正常。

所以逻辑上,作者需要再想想怎么在界面表现会相对合适。

设计风格上,luci-app-xray 一贯保持了极其 clean 的气质。so, 在这一功能的提供上,建议仅保留 Bypass TCP Port 和 Bypass UDP Port 相对合宜,这已能够完全覆盖此一 patch 本来的所有要求。

若采用 Forwarded TCP Ports 和 Forwarded UDP Ports, 非常容易让端口设置不当,并影响到使用。

yukeiyang commented 1 year ago

问题出在 Chrome 我默认使用了 dns over https, 请忽略以上提议。Sorry about it.

以下仅供参考。

设计风格上,luci-app-xray 一贯保持了极其 clean 的气质。so, 在这一功能的提供上,建议仅保留 Bypass TCP Port 和 Bypass UDP Port 相对合宜,这已能够完全覆盖此一 patch 本来的所有要求。

lialosiu commented 1 year ago

就我个人的需求而言,按需转发端口还是有必要的,毕竟日常要转发的也就只有80 443等常用web服务端口... 默认全转发然后一个个排除的话未免有点过于麻烦了( 我倒是在想filter总开关可以去掉,毕竟默认策略forwarded并且bypass列表里面空的话,就和关掉filter开关一个效果了

yukeiyang commented 1 year ago

默认全转发然后一个个排除的话未免有点过于麻烦了。

同意。

我倒是在想filter总开关可以去掉,毕竟默认策略forwarded并且bypass列表里面空的话,就和关掉filter开关一个效果了

同意。

yukeiyang commented 1 year ago

如果能自动判定 port 类型的话,可以简化成仅仅只添加 2 个下拉可选项:

Bypass the port
Forward the port

也就是说,只需要添加一个 select box 元素,以替代在 UI 中添加 4-5 多个元素的方式。

这样界面可能更简洁,也更易于理解。

yukeiyang commented 1 year ago

我倒是在想filter总开关可以去掉,毕竟默认策略forwarded并且bypass列表里面空的话,就和关掉filter开关一个效果了

由于你的 patch 采用的是排除法,若 UI 中完全显示 bypass forward 两个元素的话,而用户若同时配置了这两个元素,就会引起冲突。

因此,选用 select box 下拉单选框较为合宜。

lialosiu commented 1 year ago

如果能自动判定 port 类型的话,可以简化成仅仅只添加 2 个下拉可选项:

Bypass the port Forward the port

也就是说,只需要添加一个 select box 元素,以替代在 UI 中添加 4-5 多个元素的方式。

这样界面可能更简洁,也更易于理解。

端口不可能判断的啊,我怎么知道用户是要tcp还是udp呢?

yukeiyang commented 1 year ago

hmm ... I need to think it over.

lialosiu commented 1 year ago

hmm ... I need to think it over.

很简单的例子,443端口,可以是标准https(tcp),也可以是http3/quic(udp),不可能判断得了的

yukeiyang commented 1 year ago

image

好奇一问,入口 port 到达你的 port filter 之前,其入口port 原来的属性(TCP/UDP) 无法被 detect 到么?

逻辑上,你目前的设计是严谨的。我只是单纯觉得似乎有点复杂,也许有什么方式能简化一下,以方便普通用户的理解和使用,也能符合 luci-app-xray 一贯的风格。

yukeiyang commented 1 year ago

之所以在本例中之前建议仅保留 Bypass 一种策略,也是出于此意。

GFW 升级很快,各种技术的迭代也很快,采用 Forward 443 80 53 端口的策略,有时候可能会中招,譬如有时候一不小心可能会漏掉 853 tls, 如果用户在本地采用了 dns over tls的话。

而 Bypass 策略可能对99.99% 的用户已经足够,而且配置时不容易出错。

当然,你目前的设计思路是逻辑最全的,适合高级用户的需求,可能我更多考虑的是易用性。

lialosiu commented 1 year ago

image

好奇一问,入口 port 到达你的 port filter 之前,其入口port 原来的属性(TCP/UDP) 无法被 detect 到么?

逻辑上,你目前的设计是严谨的。我只是单纯觉得似乎有点复杂,也许有什么方式能简化一下,以方便普通用户的理解和使用,也能符合 luci-app-xray 一贯的风格。

问题不在这呀,问题是在gui配置阶段,不让用户指定tcp还是udp的话,就没法写防火墙的规则了,因为不知道用户是要的什么协议

之所以在本例中之前建议仅保留 Bypass 一种策略,也是出于此意。

GFW 升级很快,各种技术的迭代也很快,采用 Forward 443 80 53 端口的策略,有时候可能会中招,譬如有时候一不小心可能会漏掉 853 tls, 如果用户在本地采用了 dns over tls的话。

而 Bypass 策略可能对99.99% 的用户已经足够,而且配置时不容易出错。

当然,你目前的设计思路是逻辑最全的,适合高级用户的需求,可能我更多考虑的是易用性。

这种场景我觉得默认端口策略为forwarded即可,默认forwarded,并且bypass列表为空的话,其实行为就和原本一样了

yukeiyang commented 1 year ago

我本身是从事数据算法的,对网络不太深入,你这说的这一点,我之前忽略了。

lialosiu commented 1 year ago

如果是简化配置项的话,其实还有一种方案,一般udp还是比较少用于转发的,可以把tcp、udp列表合并为一项,然后默认用户填端口是tcp,如果需要udp,则显式声明,如这样53/udp

yukeiyang commented 1 year ago

And,我编译了包含你这一 patch 的 firmware, 分别在两台软路由上测试了两天,完美运作。

功能上没有任何问题。

yukeiyang commented 1 year ago

如果是简化配置项的话,其实还有一种方案,一般udp还是比较少用于转发的,可以把tcp、udp列表合并为一项,然后默认用户填端口是tcp,如果需要udp,则显式声明,如这样53/udp

你的这一提议非常好。这样就能在 UI 中仅添加一个 select box 下拉框就搞定,极其简洁,总开关什么的都可以去掉了。

下拉框中,就两个 options:

Bypass the Port
Forward the Port

不过应该就 53/udp 样式在 select box 下面加一行提示。

lialosiu commented 1 year ago

如果是简化配置项的话,其实还有一种方案,一般udp还是比较少用于转发的,可以把tcp、udp列表合并为一项,然后默认用户填端口是tcp,如果需要udp,则显式声明,如这样53/udp

你的这一提议非常好。这样就能在 UI 中仅添加一个 select box 下拉框就搞定,极其简洁,总开关什么的都可以去掉了。

下拉框中,就两个 options:

Bypass the Port Forward the Port

不过应该就 53/udp 样式在 select box 下面加一行提示。

具体方案等 @yichya 大佬来敲定吧

yukeiyang commented 1 year ago

Agree.

hqvv commented 1 year ago

感谢分享, 这解决了我大问题。 测试了一下,发现Default Ports Policy 如果是 bypass模式,可以正常访问转发的端口。 但在 Forward 模式就无法使用, 转发的端口无法访问,不知道 forward模式是否需要额外的设置?

yukeiyang commented 1 year ago

@hqvv Default Ports Policy 为 Forwarded 模式时,你需要填入需 bypass 的端口。

我这边的软路由提供给公司内同事使用,测试 3 天了,诸如 3306 端口的 MySQL 连接设置了 bypass,截至目前同事没有报告故障。

过去采用 bypass ip 的方式来连接 mysql,否则就报告连接缓慢,但目前采用端口 bypass 的方法,没有报故障。

hqvv commented 1 year ago

@hqvv Default Ports Policy 为 Forwarded 模式时,你需要填入需 bypass 的端口。

我这边的软路由提供给公司内同事使用,测试 3 天了,诸如 3306 端口的 MySQL 连接设置了 bypass,截至目前同事没有报告故障。

过去采用 bypass ip 的方式来连接 mysql,否则就报告连接缓慢,但目前采用端口 bypass 的方法,没有报故障。

谢谢指教。 使用Forwarded 模式时,我肯定是有设置需要bypass的端口的,但奇怪的是没有生效,也不太确定是什么原因。 我再试试看吧

lialosiu commented 1 year ago

@hqvv Default Ports Policy 为 Forwarded 模式时,你需要填入需 bypass 的端口。 我这边的软路由提供给公司内同事使用,测试 3 天了,诸如 3306 端口的 MySQL 连接设置了 bypass,截至目前同事没有报告故障。 过去采用 bypass ip 的方式来连接 mysql,否则就报告连接缓慢,但目前采用端口 bypass 的方法,没有报故障。

谢谢指教。 使用Forwarded 模式时,我肯定是有设置需要bypass的端口的,但奇怪的是没有生效,也不太确定是什么原因。 我再试试看吧

我发现问题了,我写了个低级bug,复制粘贴改漏字了,Forwarded 模式时有个bug,Bypassed UDP Ports 列表被当作 Bypassed TCP Ports,把上面真正的 Bypassed TCP Ports 列表给覆盖了😂

我在修了,等新格式弄好之后我一起发上来

yukeiyang commented 1 year ago

我明白为何我的设置没有出问题,因为我只设置了 tcp 端口,所以不存在被覆盖的问题。

@hqvv 是否填入了 udp 端口而致中招?

感谢 @lialosiu 的 patch。

lialosiu commented 1 year ago

Snipaste_2023-05-24_16-59-42

这次应该稳了,两种模式我都本地测试过没问题了

nft list chain inet fw4 tp_spec_lan_re
nft list chain inet fw4 tp_spec_wan_re

可用这两条nft指令查看具体生效的规则

至于具体的选项措辞,提示语,默认填充的端口之类的,我觉得可能还需要讨论一下😓

yichya commented 1 year ago

我觉得没必要非得用 /tcp /udp 这种方式,这个就算拆两个框也无所谓,还不用自己写 validator

lialosiu commented 1 year ago

拆成两个框的话代码实现上会简单很多倒是真的(

yichya commented 1 year ago

拆成两个框的话代码实现上会简单很多倒是真的(

要不拆一下,然后就 merge 了,不想搞得太复杂

lialosiu commented 1 year ago

拆成两个框的话代码实现上会简单很多倒是真的(

要不拆一下,然后就 merge 了,不想搞得太复杂

好的,我去还原下这部分

yukeiyang commented 1 year ago

@yichya Anyway, 我可能比较龟毛。你的提议在 coding 层面的确更合理。

yichya commented 1 year ago

@yichya Anyway, 我可能比较龟毛。你的提议在 coding 层面的确更合理。

主要是解析这个 /tcp /udp 的代码 js 要写一遍,ucode 要写一遍,lua 要不是 21.02 EoL 了也得写一遍,着实没那个必要

lialosiu commented 1 year ago

bypassed下默认给forwared的端口有什么建议吗? 目前我写的是 TCP 80 443 853, UDP 53 443

yichya commented 1 year ago

bypassed下默认给forwared的端口有什么建议吗? 目前我写的是 TCP 80 443 853, UDP 53 443

Placeholder 随便写吧无所谓

lialosiu commented 1 year ago

bypassed下默认给forwared的端口有什么建议吗? 目前我写的是 TCP 80 443 853, UDP 53 443

Placeholder 随便写吧无所谓

不是 placeholder 呀, 是 default

yichya commented 1 year ago

不是 placeholder 呀, 是 default

default 啊。。。最好啥也别写了,下面写个 help text,里面写一下说建议把 80 443 加进去就行了

lialosiu commented 1 year ago

不是 placeholder 呀, 是 default

default 啊。。。最好啥也别写了,下面写个 help text,里面写一下说建议把 80 443 加进去就行了

OK

yukeiyang commented 1 year ago

@yichya @hqvv 感谢你们在这个 project 上的付出。作为拿来主义者,我们是幸福的。

这个 project 极大地增加了我的幸福感。家里和公司的软路由固件都用这个 project 来编译固件,Apple TV 看 4K 极致丝滑。

用过几乎所有的科学固件,这包括 ss, ssr, clash, passwall 等等,@yichya 你的这个是最最优雅的。

感谢。

lialosiu commented 1 year ago

改好了~


@yichya @hqvv 感谢你们在这个 project 上的付出。作为拿来主义者,我们是幸福的。

这个 project 极大地增加了我的幸福感。家里和公司的软路由固件都用这个 project 来编译固件,Apple TV 看 4K 极致丝滑。

用过几乎所有的科学固件,这包括 ss, ssr, clash, passwall 等等,@yichya 你的这个是最最优雅的。

感谢。

我之前也用过passwall和openclash,但是那UI实在太重了,配置起来真的要命🤣

yukeiyang commented 1 year ago

好的设计哲学应该是如同乔布斯一样,“我告诉你什么是好的”,而不是炫技留一堆配置项,看起来高大上,但用起来极之痛苦,Openclash 有这个问题。

其实,现在好的软件都会预留 a batch of API,让高级用户去自我调适更高级的功能,而软件本身则会做的更 clean。

luci-app-xray 是少有的这个 clean 风格的 project,很难得。

hqvv commented 1 year ago

非常感谢! 使用了最新的 commit, 但还是遇到了 在forwarded 模式下,设置 bypass 端口无法外部访问的问题。 具体设置是这样的

root@AX6000:~# nft list chain inet fw4 tp_spec_lan_re
table inet fw4 {
        chain tp_spec_lan_re {
                tcp dport 2222 return
                meta l4proto { tcp, udp } goto tp_spec_lan_ac
        }
}
root@AX6000:~# nft list chain inet fw4 tp_spec_wan_re
table inet fw4 {
        chain tp_spec_wan_re {
                tcp dport 2222 return
                meta l4proto { tcp, udp } meta mark set 0x000000fc
        }
}
root@AX6000:~# 

image

在关闭 xray 或者 在bypassed 模式下,这个端口外网都是可以访问的。

我能想到的可能原因 1) 可能是我不是主路由拨号,而是由光猫dmz来的。 2) 可能是我保留配置升级的固件,可能有一些残留的错误配置,由于是主路由,不想太影响使用就没有清除设置。

Bypassed 模式已经够我使用了,提出来只是想让诸位帮忙看看

yukeiyang commented 1 year ago

我遇到过类似问题,如你所言,我的问题是由于保留原有配置引起的。

后来不保留配置而采用干净 Upgrade 的 Flash Firmware 方式解决了这一故障。

建议你试试。

yukeiyang commented 1 year ago

@hqvv

我注意到到你使用的是 AX6000,而非 x86-64 软路由,这种路由器 Flash Firmware 简单很多。

主流 x86-64 软路由默认 LAN 口在 LAN1, Flash Firmware 如不保留配置的话,就需要在升级后连接网线到 LAN1 来Switch 端口,并重新分配配置 WAN /LAN 端口。

我过去用过 Netgear 和 TP-Link 的多个路由器,升级 Openwrt 原版固件后,没遇到需要 Switch 端口的情况。

所以我说,你可以尝试不保留配置重新 Flash 下。

yukeiyang commented 1 year ago

@hqvv 我猜你是从 luci-app-xray 1.x 版本保留配置升级到 2.x 版本,我过去遇到了同样的问题,采用不保留配置升级的方式解决了故障。

yichya commented 1 year ago

@hqvv 我猜你是从 luci-app-xray 1.x 版本保留配置升级到 2.x 版本,我过去遇到了同样的问题,采用不保留配置升级的方式解决了故障。

1.x 到 2.x 没动这块儿啊,只是因为拆了配置需要人工介入才换了个不兼容版本号

yukeiyang commented 1 year ago

@hqvv 我猜你是从 luci-app-xray 1.x 版本保留配置升级到 2.x 版本,我过去遇到了同样的问题,采用不保留配置升级的方式解决了故障。

1.x 到 2.x 没动这块儿啊,只是因为拆了配置需要人工介入才换了个不兼容版本号

我记得我当初似乎是从 luci-app-xray v1.23.0 升级到 v2.0.0 固件,同时新使用 xray reality 服务端协议,然后保留配置升级,然后网络就不通了。

Startup 处 Disable 了 xray 后,网络恢复正常。跟他的故障一样。

然后不保留配置以崭新 Flash Firmware 后正常了。

lialosiu commented 1 year ago

非常感谢! 使用了最新的 commit, 但还是遇到了 在forwarded 模式下,设置 bypass 端口无法外部访问的问题。 具体设置是这样的

root@AX6000:~# nft list chain inet fw4 tp_spec_lan_re
table inet fw4 {
        chain tp_spec_lan_re {
                tcp dport 2222 return
                meta l4proto { tcp, udp } goto tp_spec_lan_ac
        }
}
root@AX6000:~# nft list chain inet fw4 tp_spec_wan_re
table inet fw4 {
        chain tp_spec_wan_re {
                tcp dport 2222 return
                meta l4proto { tcp, udp } meta mark set 0x000000fc
        }
}
root@AX6000:~# 

image

在关闭 xray 或者 在bypassed 模式下,这个端口外网都是可以访问的。

我能想到的可能原因

  1. 可能是我不是主路由拨号,而是由光猫dmz来的。
  2. 可能是我保留配置升级的固件,可能有一些残留的错误配置,由于是主路由,不想太影响使用就没有清除设置。

Bypassed 模式已经够我使用了,提出来只是想让诸位帮忙看看

看着像是端口转发的问题,我抽空研究下