EtherDream / freecdn

A front-end CDN based on ServiceWorker
982 stars 81 forks source link

提些建议 #9

Closed lirko closed 2 years ago

lirko commented 2 years ago

一:建议hash直接使用文件md5,32位省空间,没特殊符号 / =等,使用sha256编码再base64编码会有/ =符号,这导致本地好多图片下载时本身就以md5文件名保存,再使用freecdn编码后很不方便

二:建议清单、sw.js等在freecdn cli增加常量配置可以自定义位置,比如/sw/sw.js,因为很多开发并非有根目录权限,或与根目录的原本sw服务冲突

三:站点权重,开发时基本用什么库都是本地或引用国内公共库,字节,360, 七牛等等,国外真不建议使用,当然有人面向国外用户肯定有需要,所以建议有个站点权重由自己来选择

四:建议开发数据加密功能,比如有同行想爬取本站数据,看到请求一个html地址居然是请求一个图片,对这个图片有疑问肯定会下载图片来研究,这时图片里面的代码没加密,对方很容易获得原数据

五:希望多出一些使用案例,比如看了目前写的css或 js伪装图片合拼,但想把所有css js文件都合拼一个文件进行压缩再伪装图片 1.css取url/img.jpg#pos=555 , 2.js取url/img.jpg#pos=888等等来减少请求

如果想实现全站html本地化,假如有1w个html,请求1w次显然用户体验不好,后台上传1w个html到图床获取1w个备用地址,或5个/10个图床备用地址,后台操作效率显然低下,再要保存这么多备用地址 清单文件肯定又大大增加 假如可以合拼1w个html为一个文件进行压缩再伪装图片上传图床,用户请求就变成1次而非1w次,请求1次后浏览器有缓存就可以拦截,对拦截的url提取这1个文件里面的指定位置即可

六:建议增加支持一些中间件数据库mongo redis等来让 (真后端) 服务器来对接freecdn使用,毕竟freecdn只算是前端工具,真正的数据管理系统还是在后端这边的,比如后端24小时爬取数据,下载图片,上传图床,爬取完成后只需把图片md5哈希和图床地址保存到redis哈希表或set表即可,效率高,跨服务器共用

七:开发用户异步定时后台脚本 比如前端爬虫,用浏览器用户ip突破目标服务器访问限制,https://juejin.cn/post/6844903767226351623 文中提到的第三种postMessage很适合用来前端爬虫,用iframe调用远程网页不跨域,但默认是获取不到dom对象,因为跨域,但可以用sw.js在远程网页拦截后插入postMessage脚本获取整个dom再post给自己

最后建议开个qq交流群

EtherDream commented 2 years ago

感谢建议。

  1. hash 用 md5 我考虑下,或者可以自定义 hash 算法。

  2. 清单(freecdn-manifest.txt)和脚本(freecdn-loader.min.js)的文件名倒是可以加个选项。不过脚本一般都放根目录,因为 Service Worker 只能拦截它所在目录和子目录请求。当然也可以通过 HTTP 头突破这个限制,不过那样配置更麻烦。

  3. 站点权重已经开发完成了,最近几天更新~

  4. 文件加密之前也想过,但考虑到目前前端代码没有保护,所以用什么算法都比较容易破解,因此只放了个 xor 参数,仅用于对数据简单混淆。之后考虑加一个混淆模块,用于放置解密算法,并且有一定的对抗功能。这样可以实现全站资源加密。

  5. 资源合并其实可以用 pos 和 size 两个参数同时使用,根据不同的位置和大小,从同个 URL 中提取文件,当然这样并不优雅,目前在开发更简单的合并功能,包括使用 cli 打包文件。(这个思路之前在 web2img 项目中尝试过)

  6. 后端部分考虑中。其实 URL/Hash 资源维护这些用其他语言、数据库也可以实现,最终生成符合格式的清单文件就可以了。

  7. 这个可以放在第 4 部分前端对抗里实现。

讨论群我准备一个。

lirko commented 2 years ago

二:我知道sw.js无法控制上级父目录,因为站点管理员不给父级权限使用或者父级已经有sw.js服务不想被冲突,所以只给二级目录使用权限,但你说到通过http头突破限制倒引起兴趣 假如: freecdn注册在url/bb/freecdn-loader.min.js 清单文件 url/bb/freecdn-manifest.txt /index.html urlxxx/a.jpg

/sw/ok.html urlxxxx/b.jpg

ok.html必定没问题,但index.html需要怎么突破才能控制拦截?正常sw没有控制上级目录权限

四,五,六: 目前是想使用br压缩全部html合拼到一个大html,再使用xor加密大html,最后附加图片后面传图床 但看到你文档中的

如果 WebAssembly 无法创建,程序直接访问原始 URL,不再使用备用 URL。

意思就是浏览器不支持br解码就直接走原站网络访问,所以对br又爱又恨,能不能退一步选择gzip压缩,br比gzip少20%左右大小,但gzip起码兼容性很好,浏览器都支持。

清单规则不知道写的对不对: /index.html url/x.jpg#pos=100&xor=134&br=on&size=300 /2.html url/x.jpg#pos=400&xor=134&br=on&size=600 我知道可以这样获取同一个jpg文件里面指定位置,主要是这些多个html文件合拼一个大html文件时要记录 开始位置 和 结束位置 ,这些可以在自己后端做运算处理,但处理后一般都是存redis或mysql里面,所以freecdc cli本身不支持多文件合拼导致后端数据库又无法对接freecdn cli,毕竟清单还是要靠freecdn cli生成,当然后端也可以直接生成清单文件,但freecdn cli每次生成时又动态生成一个SIGN签名,其实用习惯了一个语言,比如php py,写这些压缩加密运算记录位置到数据库,查看数据库生成清单都可以在原本熟悉的语言实验,,关键的最后是freecdn前端要验证清单sign签名

EtherDream commented 2 years ago

返回 sw 的文件的时候设置 Service-Worker-Allowed 头可以授权根目录。

wasm 兼容性倒不是大问题,这个项目本身也要 es2020 的浏览器才能运行,理论上都支持 wasm,除非特殊浏览器禁用了 wasm。当然还可以加个 asm.js 的后备方案,这样兼容性就更好了。

前端默认是不校验清单签名的。只有当前站点故障,前端正好是 sw 激活后首次访问,加载不了远程清单,只能用本地缓存的清单,才会校验签名(防清单被 xss 篡改)。我在考虑被篡改应该是小概率事件,也许关掉签名是不是更方便使用~

lirko commented 2 years ago

设置 Service-Worker-Allowed 头是需要有nginx等服务权限修改,这就更没办法拿到了,连父级目录都不给开放使用,怎么还会给更大的nginx权限使用,看来还是乖乖的使用自己有权限管理的二级目录下注册sw。

我查了下WebAssembly兼容性还是不错的,基本支持sw脚本的浏览器版本也支持WebAssembly,br模块基于WebAssembly,估计也有很多基于WebAssembly的模块使用,比如加密模块

我也奇怪清单都是直接看到明文,为什么要有sg签名,也看过其他项目,原本是用json保存清单的,为什么现在选择txt这种不规范格式保存?

看了项目todo,里面的日志功能建议特别关注错误日志的处理,比如图床地址404或403等盗链导致失效问题,特别关注错误日志,对更新清单和数据库里面备用url起到重要关键

EtherDream commented 2 years ago

最早设计也是 json 格式,不过看起来比较冗余,用 txt 比较简单些。没缩进的是原文件,有缩进的是备用 URL 和参数。可以考虑加个 json 支持,或者通过 cli 在 json 和 txt 之间转换。

日志功能之后会加上,目前在考虑日志格式、如何配置问题。

lirko commented 2 years ago

主要是json是流行标准,各种编程语言数组对象转换json方便,很期待freecdn尽快成熟,以它为基础做出前端cdn负载均衡,减轻服务器带宽成本,同时更加希望freecdn再极致下一步,比如用户访问第三方图床资源后再获取自己接口查看该资源是否需要上传其他接口平台,比如get一下自己的接口,如果服务器返回需要上传和返回接口地址参数等信息,用户在浏览器随带就把资源上传到指定接口,因为我发现很多第三方的接口都没有设置同源策略的情况,成功就给自己接口传资源哈希和第三方资源地址,把用户的带宽帮自己服务器要做的事情完成,还有爬虫这类也是可以在用户浏览器帮服务器完成,,这样就做到freecdn不光用第三方图床帮网站节省带宽,还帮网站后端要做的爬虫、压缩加密再上传数据到第三方图床节省服务器资源开销,让服务器进一步得到更低成本的释放,例如一个资源原计划传5个,10个备用地址,服务器就上传1,2个,其他让用户来完成上传,毕竟用户下载到浏览器了就随带帮服务器完成上传工作而已

changhr2013 commented 2 years ago

mark 一下,要开发加密的话我可能可以帮上点忙😂

lirko commented 2 years ago

可以先提下建议思路方案,作者觉得整合方便肯定会完善的,不方便整合最终估计freecdn还是会走向做平台中心插件化,毕竟每个人需要不一,但freecdn可以做的就是把代码模块化,用钩子插件式让使用者来自己写需要的代码

EtherDream commented 2 years ago

关于 hash 算法,由于 WebCrypto API 不支持 md5,所以要自己实现算法,估计得用 wasm 实现。

之后考虑加个可以动态加载自己模块的参数,这样用户可以自己实现 hash/解密/验签等操作,包括混淆功能也可以放在动态模块里实现。

lirko commented 2 years ago

普遍md5 sha256用的最多,比如百度云秒传用md5阿里云盘用sha256,大部分图床还直接返回url/md5.jpg命名的url地址来过滤重复资源提交,我自己的文件信息存数据库是md5 sha256都有,资源名倒是使用短字符的md5,没再用base64,因为base64有/+=等特殊符号,系统不支持这种特殊符号命名,而且base64目的是防止浏览器把空格:/等符号转换,所以一般用在url有特殊符号情况下压缩传输,本身不管是md5还是sha256,算出来都是数字+英文,所以没必要再用base64压缩一次,浪费多一次压缩的机器资源,况且文件名也和数据库对不上,所以文件名用md5/sha256 数据库存md5/sha256节省base64压缩步骤,也方便文件和数据库对接查询,建议取消base64即可

changhr2013 commented 2 years ago

理论上用 sha256 前 16 个字节跟 md5 能达到同样的效果,因为碰撞空间都是 128 个比特。类似于 sha224 实际就是将 sha256 的结果截掉了 32 个比特。 不过从密码学的角度来讲,至少应该使用 sha256 以上的算法,md5 和 sha1 的强抗碰撞性已经被攻破了。 应用在目前标记文件的场景下,用哪个问题都不大。