istoreos 不断请求 Packages.sig
Hi 管理员/贡献者:
我近日在多个开源镜像站上观察到有ua为 "curl/8.4.0" 或者 "curl/8.6.0" 的客户端在大量请求 "uri":"/openwrt/releases/22.03.6/packages/*/base/Packages.sig",我通过搜索发现主流openwrt发行版中只有istoreos还在使用这一版本且使用了mirrors.cernet.edu.cn,我希望知道这是否是由于你们的配置出现了一些错误?这一文件的请求数量较为巨大,虽然整体传输量较低暂未对我们的镜像站构成较大的压力,但是我仍然希望知道这是否是由于错误的配置所导致的。
refer: https://github.com/istoreos/istoreos/discussions/1534
btw,我们通过逆向得知,是 /usr/sbin/quickstart 导致的,getDistFeedUrlForCheck里拼接了包含/Packages.sig的路径,然后NetworkOnlineChecker_doCheck继续拼接成了curl --fail --show-error --max-time 5 -o /dev/null -s -L '%v'
抱歉,确实会有这个请求,这个请求主要是判断用户选择的ipk镜像源是否能正常使用。之所以检查Packages.sig也是因为这个文件最小。如果请求量太大,或许我们可以减少检查频率?
原本的逻辑: 用户打开首页以后,前端会调用网络状态的API,这个API隔15秒会检查一次外网联通性,如果可以访问外网,则会尝试请求feed,也就是前面提到的“Packages.sig”。如果用户离开了首页,其实就不会再调用这个API了,也不会触发访问“Packages.sig”。
打算改成: 前端不变,后端的网络状态的API内部缓存当前网络中的IP/网关/DNS/FeedURL,如果变化了则立即检查网络,否则90秒最多检查一次。理论上 “Packages.sig” 的请求数会降低到原本的1/6。
原本的逻辑: 用户打开首页以后,前端会调用网络状态的API,这个API隔15秒会检查一次外网联通性,如果可以访问外网,则会尝试请求feed,也就是前面提到的“Packages.sig”。如果用户离开了首页,其实就不会再调用这个API了,也不会触发访问“Packages.sig”。
打算改成: 前端不变,后端的网络状态的API内部缓存当前网络中的IP/网关/DNS/FeedURL,如果变化了则立即检查网络,否则90秒最多检查一次。理论上 “Packages.sig” 的请求数会降低到原本的1/6。
如果可以的话再加一个闲置检查?防止用户打开网页但是放置到后台之后继续请求
OK,我看看前端怎么实现
前端加上了 document.hidden 判断,也就是当前标签页是否活跃。如果不活跃就暂停API调用。
前端加上了
document.hidden判断,也就是当前标签页是否活跃。如果不活跃就暂停API调用。
感谢您的及时修复
嗯,大概周五或周六发布固件以后这些新变更才会开始生效。
固件已经发布了,明天看看请求量有没有下降
固件已经发布了,明天看看请求量有没有下降
感谢您的跟进,我将会持续观察并及时反馈
固件已经发布了,明天看看请求量有没有下降
目前来看请求量已经得到了较好的控制,我将关闭此issue,再次感谢您的帮助
Hi, @jjm2473 抱歉打扰您。不知道能否给相应检查的请求带上特定的 User-Agent,里面能够包含软件的名称和版本等信息,以便镜像站识别。目前看到的 User-Agent 是 curl,容易与其它的异常请求相混淆。
@shankerwangmiao 原版的opkg默认应该都是wget来请求的,istoreos只是打了补丁换成使用curl了(wget的超时机制有问题,会卡死)
https://github.com/istoreos/istoreos/blob/6ac30a11607a73f5e25299200a9c6bbfe9645ae2/package/system/opkg/patches/001-opkg-add-curl.patch
所以只要是curl的请求ipk仓库基本都是istoreos的
嗯,不知道能否顺手加上一个特定的 UA,这样可以和其它的异常请求相区分?
@shankerwangmiao 你那边能看到正常的opkg请求的UA吗,看看能不能模仿下,毕竟如果直接改成istoreos,这个补丁也可能被其他人使用,到时候一样分不清,还是使用跟opkg相同的UA吧
@shankerwangmiao 你那边能看到正常的opkg请求的UA吗,看看能不能模仿下,毕竟如果直接改成istoreos,这个补丁也可能被其他人使用,到时候一样分不清,还是使用跟opkg相同的UA吧
用就用,只要不是curl就行....
我看了一下,确实没有发现比较明显有特征的 UA。
考虑到补丁有可能被别人使用的情况,您看这么做是否可行?就是在补丁正文中预留一个宏定义,然后在编译期通过 -D 传入具体的值。这样就不会将您选用的 UA 硬编码在代码中了。
比如这样:
const char *argv[16];
//....
#ifdef CUSTOM_UA
argv[i++] = "-H"
argv[i++] = "User-Agent: " CUSTOM_UA
#endif
然后编译的时候加上 "-DCUSTOM_UA=\"Some UA/x.x.x\""
不只是opkg这边使用curl,前面提到的检查软件源是否有效是另一个quickstart程序发起的,这个检查过程则只会请求 Packages.sig(现在这个请求量应该也降低很多了)。
quickstart可以读取openwrt的版本号拼接UA,opkg就不想改太多了,毕竟opkg是openwrt维护的。但是两边要是UA不一样导致检测结果不准确,反而跟我们的预期不符;
折衷方案,我们也可以在quickstart和opkg上都增加一个固定的UA,但是没法保证其他人不会用这个UA;
此外,opkg加上自己的UA以后会不会反而被一些ipk站点认为是非法请求,毕竟用户是可以自己加ipk源的,不只是请求openwrt镜像站以及istore的ipk仓库。所以我才想找个opkg默认的UA。
总之,我比较倾向于不改UA,或者改成跟opkg默认UA一致,避免其他不可预知的麻烦。
PS: opkg默认UA应该是Wget/*,wget应该不会比curl更容易区分。
不只是opkg这边使用curl,前面提到的检查软件源是否有效是另一个quickstart程序发起的,这个检查过程则只会请求 Packages.sig(现在这个请求量应该也降低很多了)。
quickstart可以读取openwrt的版本号拼接UA,opkg就不想改太多了,毕竟opkg是openwrt维护的。但是两边要是UA不一样导致检测结果不准确,反而跟我们的预期不符;
折衷方案,我们也可以在quickstart和opkg上都增加一个固定的UA,但是没法保证其他人不会用这个UA;
此外,opkg加上自己的UA以后会不会反而被一些ipk站点认为是非法请求,毕竟用户是可以自己加ipk源的,不只是请求openwrt镜像站以及istore的ipk仓库。所以我才想找个opkg默认的UA。
总之,我比较倾向于不改UA,或者改成跟opkg默认UA一致,避免其他不可预知的麻烦。
PS: opkg默认UA应该是
Wget/*,wget应该不会比curl更容易区分。
..edu.cn 这边 应该不会 认为是异常请求,但是不保证阿里云等镜像站会如何处理
不只是openwrt的镜像站点,还可能有用户自己添加的第三方软件源(istore的repo从openwrt角度来看也算是第三方软件源)
不只是opkg这边使用curl,前面提到的检查软件源是否有效是另一个quickstart程序发起的,这个检查过程则只会请求 Packages.sig(现在这个请求量应该也降低很多了)。
啊,其实我之前想说的就是给这个 quickstart 程序加个 UA。
quickstart倒是只会检查镜像站和openwrt站。但修改检测UA还是可能有问题,要是因为UA不同导致检测的结果跟opkg实际请求的结果不一致,用户可能以为是检测过程有bug呢。
emmmm,也不是没有道理。但是一般而言,因为 UA 产生的结果的变化应该比较少见?
是挺少的。不过最近我们在接入cloudflare的cdn的时候,就算不做特别设置,cloudflare也会拦截一些不正常的请求(“浏览器完整性检查”),虽然不知道cf的具体规则,但大部分UA都是Python-urllib/*。
如果我是一个openwrt软件仓库的管理员,如果流量太大也许我会限制仓库只能给浏览器和opkg访问。
其实现在quickstart检测的特征还是很明显的吧,使用curl访问镜像站Packages.sig的估计也只有quickstart了(以及少量istoreos的opkg update请求)。
此问题已在 酷友社 上被提及。那里可能有相关详细信息:
https://www.koolcenter.com/t/topic/2269/1