feat: Add rate limiting to fallback handling via token bucket
如题,fallback时限速,不影响正常reality
比自己搭nginx过滤SNI的方案更好,更简单
仅demo因此速率写死,欢迎PR我再弄config
对于reality最佳实践虽然是偷同ASN,但考虑到实际情况,大多还是找个知名网站莽就完事了 即便target现在不是CF,可能以后也会用CF等CDN
自己搭nginx限SNI对小白来说不友好,因为需要探测出目标站的所有SNI并放行,哪天target证书更新可能又有新的域 我都嫌费劲,而且流量从nginx绕了一下,感觉怪怪的
此PR使能所有reality握手失败的分别针对上下行限速,允许brust 达成效果:调大after并严格限制rate和brust,使能勉强可开个正常网页应付探测,但想把小鸡拿来中转白嫖流量基本可杜绝
效果图
https://github.com/XTLS/Xray-core/pull/4550#issuecomment-2754263456
我想了一下先设计得简单点吧,只给 fallback 下行限速即可,而且看描述 burst 和 after 有点重复,不过 burst 实际上是 capacity?
~~还有你 burst 拼成了 brust,这要是我没仔细看就很搞笑了~~
我当时考虑的是上行不限,香港优选节点可能被拿来跑直播之类的啥用途。 不过删就删随你,我个人觉得是放在那里,用户用不用看他自己
现在上行的删不删?
after的作用主要是为了防止探测, 因为考虑到如果用户想要突发小一点。那就搞得限速特征很明显,after此时能很好的解决问题 限速三参数是参考nginx做的
~奶子的问题我现在改~
我在想怎么设计,请保持在线,~~这样我就不用自己改代码了~~
我在想怎么设计,请保持在线,~这样我就不用自己改代码了~
ok
burst 你这个描述应该改成“突发倍数”更合适吧,且 0 应该默认相当于 1
~~还有,其实我想搞个范围机制,不过感觉又复杂了~~
burst本质就是个令牌桶的容量 rate是装令牌的速率
after是单独加的,消耗完了开始用桶算法
nginx是这么干的
看明白一些了,令牌数就是 byte
yes
下列六个 limit**** 为选填,可对回落的 REALITY 连接限速。默认为 0 即不启用。
原理:当传输了after减去burst字节后开启限速算法。 限速采用令牌桶算法,桶的容量是burst,每传输一个字节用掉一个token,初始burst是满的。 每秒以rate个token填充桶,直到容量满。
举例:after=10485760, burst=5242880, rate=1048576 代表传输10mb后开始限速为1mb/s,如果暂停传输,5秒后能突发到5mb/s,然后又恢复到1mb/s。
建议:过大的after和burst将起不到限速效果,过小的rate和burst则十分容易被探测。
应结合被偷网站的资源大小合理设置参数,如果不允许突发,可以把burst设为和rate一样。
可以保留上行限速,参数设计成这样:
"limitFallbackUpload": {
"afterBytes": 0,
"bytesPerSec": 0,
"burstBytesPerSec": 0
}
"burstBytesPerSec" 小于 "bytesPerSec" 时自动等于它
话说 Nginx 没有 "afterSeconds" 这种东西吗
~~还有虽然单连接上行被限速了,但 XHTTP 上行分包可破此局~~
话说 Nginx 没有 "afterSeconds" 这种东西吗
我刚翻了下文档nginx的确没有按时间限速的 可以限ip并发连接数,然后每个连接限速
~还有虽然单连接上行被限速了,但 XHTTP 上行分包可破此局~
下个PR按IP限连接数?
总之先按我说的参数格式改一下吧
总之先按我说的参数格式改一下吧
ok
你这改的是个啥?完全没按我说的格式,README 也是不该动的地方都动了,还是放下个版本吧
RatelimitedConn 的 Read() 有个问题,如果数据量大要等很久,或者直接卡死
应该改成 Write() 里有多少 token 就 write 多少数据
"AfterBytes" 放结构体最上面,LimitFallback struct 放 Config struct 上面,BurstBytesPerSec 小于 BytesPerSec 时直接等于它
BytesPerSec 改为 int64 吧,不需要它是小数
BurstBytesPerSec 小于 BytesPerSec 时直接等于它
这个还是没改
这样吧,三个参数全改成 uint64
判断是否启用只需判断 config.LimitFallbackUpload.BytesPerSec 是否为 0
after是可能为负数的
after是可能为负数的
意义是?
不是设置的值,运行中计算的时候可能为负
只有参数设为 uint64 即可
RatelimitedConn 的 Read() 有个问题,如果数据量大要等很久,或者直接卡死
应该改成 Write() 里有多少 token 就 write 多少数据
这个我想了一下不会卡死,但有多少 token 就 write 多少数据也不太行,调用方循环 write 会造成调用次数太多
只是说如果限速 1kb/s,但 target 发来一个 16kb 的 record,要等 16 秒。。。
~~uint64,不是 int64~~
没错吧, juju库要的burstBytesPerSec就是int64
配置允许的是uint64必须得做检查,超了就设为max
运行时的LimitAfter初始值得是 AfterBytes - BurstBytesPerSec 这里要的是int64 也得转换
我不确定 golang 里 uint64 转 int64 大于一半时会发生什么,你试一下,不过搞这么大还限什么速,所以 max 那里有点没必要
After 就直接传过去,不用减掉 burst
把 write 改回 read 吧,然后把 NewBucketWithRate 的逻辑合进去,也就是说直接传三个参数