Xray-core icon indicating copy to clipboard operation
Xray-core copied to clipboard

REALITY: Add rate limiting to fallback handling via token bucket

Open Meo597 opened this issue 9 months ago • 17 comments

这下~小学生论坛的~mjj们再也不用担心reality偷cf导致小鸡流量被人偷了

建议配置 给一个较大的after以应付探测,rate和brust弄小点防止mjj偷流量 过大的after和brust将起不到限速效果,过小的rate和brust则十分容易被探测 应结合被偷网站的资源大小合理设置参数 如果不允许突发,可以把brust设为和rate一样

技术细节: 当传输after减去brust字节后开启限速算法 限速采用令牌桶算法 桶的容量是brust,每传输一个字节用掉一个token,初始brust是满的 每秒以rate个token填充桶,直到容量满

示例配置: 如果下载一个文件,效果是: 前10mb不限速,然后被卡256kb/s 如果此时暂停了一会儿,随着时间推移慢慢攒令牌直到上限 再恢复下载又能跑到突发的2mb/s,然后继续被限为256kb/s

至于上行按感觉来配比,一般给很小就足够了

{
    "inbounds": [ // 服务端入站配置
        {
            // 省略...
            "streamSettings": {
                  // 省略...
                "realitySettings": {
                    // 省略...
                    // 下列六个 limit 为选填,可对回落的 REALITY 连接限速,单位是字节/秒。默认为 0 即不启用
                    "limitUploadRate": 65536, // 上行基准速率 64kb/s
                    "limitUploadBrust": 65536, // 上行不允许突发
                    "limitUploadAfter": 0, // 立即对上传开启限速
                    "limitDownloadRate": 262144, // 下行基准速率 256kb/s
                    "limitDownloadBrust": 2097152, // 下行突发速率 2048kb/s
                    "limitDownloadAfter": 10485760 // 下载10mb后开启限速
                }
            }
        }
    ]
}

Meo597 avatar Mar 26 '25 15:03 Meo597

然后面板脚本们随便往里填个或高或低默认参数 很多reality就有了一个限速特征 如果是中间人的人话还可以顺便观察到别人可以长时间得到高于主动探测的速度

Fangliding avatar Mar 26 '25 15:03 Fangliding

探测想要触发到限速,是需要时间和带宽成本的 合理的参数想被探测出来,墙需要无差别cc攻击所有目标

然后还可以加rate随机抖动


刚才随机找了几个可以偷的站,体积小的2mb,图片很多的也不过30mb ~如果担心brust给太大起不到限速效果~ ~也可以加limitUp/DownloadAfter且随机化再限速~ 刚刚加好了,没测,目测没问题


至于中间人那就跟限速无关了 假设真的无差别中间人所有 不用探测限速都知道你在爬梯

Meo597 avatar Mar 26 '25 16:03 Meo597

这个功能我打算在 REALITY 抗量子更新之后合并,因为现在支持抗量子的服务端 CF 占最多?Nginx 用的 OpenSSL 才刚合并它

至于会引入限速特征,虽然会标明,但即使不标明,这太明显了,任何人都应该能自己想到吧,所以说这是个风险自负的问题

RPRX avatar Mar 29 '25 14:03 RPRX

我感觉特征这块还好,因为:

  • 毕竟他都偷CDN了,ASN都不在一个段,不用探测都知道是reality
  • 同ASN的话,站长也没必要反过来把reality当边缘,流量都一样跑何苦呢

实在不行下个PR加个参数随机浮动

Meo597 avatar Mar 29 '25 14:03 Meo597

反正要偷 CDN 就是个风险自负的问题,不偷 CDN 的话也用不上这个限速,确实得说明一下以防面版脚本们无差别设默认值

RPRX avatar Mar 29 '25 14:03 RPRX

看了一眼好长的选项 感觉加个下行限速够了

Fangliding avatar Mar 30 '25 14:03 Fangliding

after和brust是为了规避探测,因此要3个 上下行都可以被滥用,因此要x2

nginx也是六个参数限速,当前行为也和nginx一模一样 或者你有啥好办法没

@Fangliding

Meo597 avatar Mar 31 '25 05:03 Meo597

这个功能不要仅限于reality吧,其它入站协议也需要

intmain0 avatar Apr 26 '25 18:04 intmain0

没合是因为现在还无法合并 https://github.com/XTLS/REALITY/pull/12 ,因为它 base 的 https://github.com/XTLS/REALITY/commit/e26ae2305463dd69cccc8a79a3576d7b68c4f3a4 似乎有问题,@yuhan6665

目前 REALITY 这块的代码只能等跟进 Go 1.24 的改动后再合入新的代码

RPRX avatar Apr 28 '25 04:04 RPRX

https://github.com/XTLS/Xray-core/blob/a608c5a1dbfa59b8328ac5d0363f360b2fd3bebe/go.mod#L23

比如说 Xray-core 用的 REALITY 都不是 https://github.com/XTLS/REALITY/commit/e26ae2305463dd69cccc8a79a3576d7b68c4f3a4 ,此前 @yuhan6665 好像升级到了该版本然后回退了

给 REALITY 加抗量子更新没啥难度,麻烦的是同步 Go 1.24,又是 boring 又是 internal 的,Golang 这 TLS 库写得真的很烦人,也不知道从哪学的,我都想要不 fork uTLS 搞 REALITY 算了,但是 VLESS 加密要抗量子的话似乎得暴露 internal?还有待研究

RPRX avatar Apr 28 '25 04:04 RPRX

当时好像是 v2rayng 用不了新版 go 现在应该没问题了

yuhan6665 avatar Apr 28 '25 04:04 yuhan6665

@yuhan6665 有时间同步下 Go 1.24 吗,~~这个我是真不想弄~~

RPRX avatar Apr 28 '25 05:04 RPRX

@yuhan6665 有时间同步下 Go 1.24 吗,~这个我是真不想弄~

好吧 我有空尝试更新 reality 到最新

yuhan6665 avatar May 03 '25 14:05 yuhan6665

@yuhan6665 有时间同步下 Go 1.24 吗,~这个我是真不想弄~

https://github.com/XTLS/REALITY/pull/14

yuhan6665 avatar May 11 '25 21:05 yuhan6665

@yuhan6665 @RPRX

XTLS/REALITY 的测试挂了,仅macos跑不通

我试了剥离此PR,REALITY和core都用latest得到一样结果

See: https://github.com/Meo597/Xray-core/actions/runs/15030945205/job/42243080029


=== RUN   TestVlessXtlsVisionReality
Xray 25.4.30 (Xray, Penetrates Everything.) Custom (go1.24.3 darwin/arm64)
A unified platform for anti-censorship.
2025/05/14 21:03:21.070922 [Debug] app/log: Logger started
2025/05/14 21:03:21.071033 [Debug] app/proxyman/inbound: creating stream worker on 127.0.0.1:58205
2025/05/14 21:03:21.071042 [Info] transport/internet/tcp: listening TCP on 127.0.0.1:58205
Warning: 4 21:03:21.071044 [Warning] core: Xray 25.4.30 started
Xray 25.4.30 (Xray, Penetrates Everything.) Custom (go1.24.3 darwin/arm64)
A unified platform for anti-censorship.
2025/05/14 21:03:21.076927 [Debug] app/log: Logger started
2025/05/14 21:03:21.077045 [Debug] app/proxyman/inbound: creating stream worker on 127.0.0.1:58206
2025/05/14 21:03:21.077165 [Info] transport/internet/tcp: listening TCP on 127.0.0.1:58206
Warning: 4 21:03:21.077168 [Warning] core: Xray 25.4.30 started
2025/05/14 21:03:23.078362 [Debug] [3650243354] proxy/dokodemo: processing connection from: 127.0.0.1:58207
2025/05/14 21:03:23.078436 [Info] [3650243354] proxy/dokodemo: received request for 127.0.0.1:58207
2025/05/14 21:03:23.078466 [Info] [3650243354] app/dispatcher: default route for tcp:127.0.0.1:58204
2025/05/14 21:03:23.078485 [Info] [3650243354] transport/internet/tcp: dialing TCP to tcp:127.0.0.1:58205
2025/05/14 21:03:23.078830 [Debug] [3650243354] transport/internet: dialing to tcp:127.0.0.1:58205
REALITY remoteAddr: 127.0.0.1:58208
2025/05/14 21:03:23.080876 [Info] [3650243354] transport/internet/reality: REALITY localAddr: 127.0.0.1:58208	hello.SessionId[:16]: [25 4 30 0 104 37 5 27 1 35 69 103 137 171 205 239]

2025/05/14 21:03:23.080950 [Info] [3650243354] transport/internet/reality: REALITY localAddr: 127.0.0.1:58208	uConn.AuthKey[:16]: [204 238 135 162 160 161 66 217 225 50 74 121 191 110 174 79]	AEAD: *gcm.GCM

REALITY remoteAddr: 127.0.0.1:58208	hs.c.AuthKey[:16]: [204 238 135 162 160 161 66 217 225 50 74 121 191 110 174 79]	AEAD: *chacha20poly1305.chacha20poly1305
REALITY remoteAddr: 127.0.0.1:58208	hs.c.conn == conn: false
REALITY remoteAddr: 127.0.0.1:58208	forwarded SNI: www.google.com
panic: runtime error: index out of range [8] with length 0

goroutine 20 [running]:
github.com/xtls/xray-core/transport/internet/reality.UClient({0x101f92ad8, 0x1400028c070}, 0x140000feb00, {0x101f8b500, 0x140003343c0}, {{0x101f8b650?, 0x14000306148?}, 0x2?, 0x0?})
	/Users/runner/work/Xray-core/Xray-core/transport/internet/reality/reality.go:256 +0xf48
github.com/xtls/xray-core/transport/internet/tcp.Dial({0x101f8b500, 0x140003343c0}, {{0x101f8b650, 0x14000306148}, 0xe35d, 0x2}, 0x14000301aa0)
	/Users/runner/work/Xray-core/Xray-core/transport/internet/tcp/dialer.go:90 +0x15c
github.com/xtls/xray-core/transport/internet.Dial({0x101f8b500, 0x140003343c0}, {{0x101f8b650?, 0x14000306148?}, 0x6148?, 0x140?}, 0x0?)
	/Users/runner/work/Xray-core/Xray-core/transport/internet/dialer.go:64 +0x14c
github.com/xtls/xray-core/app/proxyman/outbound.(*Handler).Dial(0x14000271700, {0x101f8b500, 0x140003343c0}, {{0x101f8b650, 0x14000306148}, 0xe35d, 0x2})
	/Users/runner/work/Xray-core/Xray-core/app/proxyman/outbound/handler.go:316 +0x988
github.com/xtls/xray-core/proxy/vless/outbound.(*Handler).Process.func1()
	/Users/runner/work/Xray-core/Xray-core/proxy/vless/outbound/outbound.go:84 +0xac
github.com/xtls/xray-core/common/retry.(*retryer).On(0x14000131d28, 0x14000131d48)
	/Users/runner/work/Xray-core/Xray-core/common/retry/retry.go:27 +0xbc
github.com/xtls/xray-core/proxy/vless/outbound.(*Handler).Process(0x14000334cf0, {0x101f8b500, 0x140003343c0}, 0x1400027a120, {0x101f88970, 0x14000271700})
	/Users/runner/work/Xray-core/Xray-core/proxy/vless/outbound/outbound.go:81 +0x19c
github.com/xtls/xray-core/app/proxyman/outbound.(*Handler).Dispatch(0x14000271700, {0x101f8b500, 0x140003343c0}, 0x1400027a120)
	/Users/runner/work/Xray-core/Xray-core/app/proxyman/outbound/handler.go:211 +0x3a0
github.com/xtls/xray-core/app/dispatcher.(*DefaultDispatcher).routedDispatch(0x140001fff20, {0x101f8b500, 0x140003343c0}, 0x1400027a120, {{0x101f8b650, 0x140003060a0}, 0xe35c, 0x2})
	/Users/runner/work/Xray-core/Xray-core/app/dispatcher/default.go:486 +0xaa0
created by github.com/xtls/xray-core/app/dispatcher.(*DefaultDispatcher).Dispatch in goroutine 19
	/Users/runner/work/Xray-core/Xray-core/app/dispatcher/default.go:266 +0x4a4
testConn finishes: 151 ms	 read tcp 127.0.0.1:58207->127.0.0.1:58206: read: connection reset by peer 	Alloc = 472.58MB 	TotalAlloc = 5.87GB 	Sys = 1.51GB 	NumGC = 35
    vless_test.go:509: read tcp 127.0.0.1:58207->127.0.0.1:58206: read: connection reset by peer
2025/05/14 21:03:23.230340 [Info] Closing all servers.
2025/05/14 21:03:23.230475 [Debug] app/log: Logger closing
Failed accept TCP connection: accept tcp 127.0.0.1:58204: use of closed network connection
--- FAIL: TestVlessXtlsVisionReality (2.18s)

Meo597 avatar May 14 '25 21:05 Meo597

https://github.com/XTLS/Xray-core/commit/09d84c42e9c729c23549ea71b374e154d5365922 修了,rebase 即可

RPRX avatar May 16 '25 07:05 RPRX

https://github.com/XTLS/REALITY/commit/50752aec6bfb7c5180aca44f5e83380a00405be5

RPRX avatar Jun 08 '25 13:06 RPRX

把上面几个问题改一下应该就行了

RPRX avatar Jun 08 '25 13:06 RPRX

我把这个 PR 的链接放 release notes 了,你更新一下“技术细节”和“示例配置”吧

RPRX avatar Jun 10 '25 03:06 RPRX

ok

Meo597 avatar Jun 10 '25 03:06 Meo597

@Meo597 你新示例配置中 limitFallbackUpload 的 bytesPerSec 是 0,与描述不符

RPRX avatar Jun 10 '25 04:06 RPRX

@Meo597 应该是你想把 65536 填入 bytesPerSec,结果填入 afterBytes 了

RPRX avatar Jun 10 '25 04:06 RPRX

@Meo597 应该是你想把 65536 填入 bytesPerSec,结果填入 afterBytes 了

~果然还是太细了~

改好了

release notes 要不要提一下 docker 的 break changes https://github.com/XTLS/Xray-core/pull/4738

Meo597 avatar Jun 10 '25 04:06 Meo597

Xray-core releases 每月都有几十万下载量,那 docker 镜像一个月就几千拉取,~~1% 提它干嘛~~

你示例配置的单位还是不对,Byte 和 bit 是有区别的,要么写 kB,要么乘以 10 大概换算成 kb,多 2 是带上了 TCP 头等一些损耗

RPRX avatar Jun 10 '25 04:06 RPRX

ok

Meo597 avatar Jun 10 '25 05:06 Meo597

~~数了一下 release notes 只有九个链接,出于强迫症把 docker 那个补上了~~

话说我一直想问 docker 内用非 root 有什么必要性吗,还有那个 -usa 是啥玩意儿

RPRX avatar Jun 10 '25 06:06 RPRX

还有这 docker 历史镜像太乱了,有没有一个脚本能把 v25.6.8 以外的全清了

RPRX avatar Jun 10 '25 06:06 RPRX

不是所有用户都把docker引擎配为rootless和uid remap,如果docker爆0day有可能逃逸危害宿主 反正遵守权限最小化原则,应该非root运行,大多知名镜像都是这么干的

很多云原生的项目在最后一层都from distroless、chainguard等“无发行版” 里面只有ca、时区,其它啥都没,shell都不给


然后-usa那个是为了支持老旧架构搞得玩意,不必在意它 如果有强迫症我可以再开个PR想办法把它删了

它出现的原因是distroless默认不支持一些老旧的架构 然后我这里做了一些兼容,不得不搞了这个标签 最后-usa的,都被合并到latest里了


删历史镜像得写个脚本,没有现成的 而且不让删下载量大的 或考虑删掉整个package,再触发一次构建镜像

~早就发现你有强迫症了~

Meo597 avatar Jun 10 '25 06:06 Meo597

帮忙写个脚本删掉 v25.6.8 以外的吧

~~应该不会不让删下载量大的吧~~

RPRX avatar Jun 10 '25 06:06 RPRX

应该不会不让删下载量大的吧

https://docs.github.com/zh/packages/learn-github-packages/deleting-and-restoring-a-package

公共包的特定版本(如果包版本不超过 5,000 次下载) 如果任何版本的包下载量超过 5,000 次,则无法删除公共包。 在这种情况下,请通过 GitHub 支持门户 联系我们,以获取进一步的帮助。


帮忙写个脚本删掉 v25.6.8 以外的吧

好的我这两天写


usa需要想办法干掉吗?

Meo597 avatar Jun 10 '25 06:06 Meo597