[分享创造] 写了个自托管的 Chrome 同步服务器,书签密码再也不经过 Google - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
charlselee59

[分享创造] 写了个自托管的 Chrome 同步服务器,书签密码再也不经过 Google

  •  
  •   charlselee59 2 小时 13 分钟前 113 次点击

    [分享创造] 写了个自托管的 Chrome 同步服务器,书签密码再也不经过 Google

    用 Chrome 的各位,有没有想过一个问题

    你每次加书签、存密码、开个新标签页、装个扩展,这些数据全部原样 POST 到 clients4.google.com。切 Edge 给微软,切 Firefox 给 Mozilla ,切 Brave 还是给 Brave 。你用浏览器这件事,本质上就是往某家公司硬盘里写日记。

    这事我琢磨了挺久说来也巧,我以前干过几年浏览器开发,Chromium 那套东西算是老本行。翻 sync 模块代码的时候就知道,里面藏着一个很有意思的启动参数:--sync-url

    于是就有了这个:

    https://github.com/loyalpartner/selfsync

    Rust 写的,GPL-3.0 ,实现了 Chrome 同步协议,接住 Chrome 的 POST ,解析 protobuf ,存到本地 SQLite 。就这么点事。


    跑起来有多简单

    docker compose up -d 

    然后 Chrome 启动加一个参数:

    google-chrome-stable --sync-url=http://127.0.0.1:8080 

    完事。登录你的 Google 账号、开启同步,书签密码历史记录全部进你自己的 .db 文件。Google 那边:知道你登录了,但同步的内容一个字节都拿不到。


    几个我自己觉得挺妙的点

    1. 多用户自动隔离,零配置。

    Chrome 每次同步请求的 protobuf share 字段里会带当前登录的 Google 邮箱。服务器按邮箱分数据空间,家里人共用一台完全不打架。我一开始以为要自己做账号系统,研究完协议发现 Chrome 自己把这事解决了。

    2. 密码是端到端加密的,服务器看不到明文。

    Chrome 把密码用你账号派生的密钥在本地加密后才上传,selfsync 存的是密文。就算有人把 .db 文件偷走,没密钥也读不出来。这点和 Bitwarden 的思路一样,但你不需要额外装一个密码管理器。

    3. 协议是开放的,不是我逆向出来的。

    Chromium 源码 components/sync/ 目录下全是 .proto 文件,数据结构写得明明白白:BOOKMARK 、PASSWORD 、HISTORY 、OPEN_TABS 、PREFERENCE 、EXTENSION……几十种类型。selfsync 做的事就是照着这些 proto 把请求拆开再装回去。

    4. 整个方案不改变任何使用习惯。

    继续用 Chrome ,继续登 Google 账号,继续享受多设备同步。唯一变的是数据流的另一端从加州机房变成你家那台小破服务器。对同事老婆孩子完全透明,他们根本不会察觉。


    一些可能会被问到的

    Q:手机端呢?

    遗憾的是 Android/iOS 的 Chrome 不支持 --sync-url 启动参数,这是移动端 Chrome 的通用限制。目前只能桌面端先跑起来。有人说过可以用 Kiwi Browser ( Android 上基于 Chromium 的第三方浏览器)试,我还没验证。

    Q:和 Floccus / xBrowserSync 有啥区别?

    那些是"书签同步"单项替代,底层走 WebDAV / 自定义协议。selfsync 直接接管的是 Chrome 原生同步总线书签、密码、历史、打开的标签页、扩展、自动填充全部一起走,不用装扩展,不用改使用习惯。层次不一样。

    Q:能同步哪些数据?

    基本上 Chrome 设置里「同步」开关能勾选的都在:书签、密码、历史记录、打开的标签页、地址和自动填充、扩展、主题、阅读列表、搜索引擎、应用……

    Q:服务器性能要求?

    一个人用,树莓派都够。SQLite 单文件,同步请求就是普通 HTTP POST ,空闲时基本零开销。我自己是丢在一台 N100 的小机器上跑着。

    为什么要做这个

    说点背景我之前干过几年浏览器开发,Chromium 那套东西算是老本行了,sync 模块的代码以前工作里就翻过不少。后来换赛道了,但对这一块一直有感情。

    最近迷上玩 NAS ,家里小机器上陆陆续续跑起来一堆自托管服务:相册、网盘、密码管理、RSS 、笔记……一块一块把数据从各家云服务上拿回来了。某天打开 Chrome 设置,看到那个"已同步到你的 Google 账号"的提示,突然意识到我每天用得最频繁的那个软件,它的数据从来没回过家

    而这块,刚好是我熟的。

    于是就写了这东西。协议那层因为以前读过源码所以没卡多久,主要时间花在把 Rust 的服务端工程化、多用户隔离、SQLite 存储这些事情上。整体写完比预期轻松,算是把过去的职业经验和现在的爱好连上了。

    现在家里、公司、笔记本三台电脑都指向家里那台小服务器,用了一阵子,稳定,完全无感。Google Takeout 下下来的同步数据包是空的这种爽感有点难形容。

    既然自己用着挺好,开源出来,省得同样痛点的老哥再走一遍。


    仓库:https://github.com/loyalpartner/selfsync

    中文 README:https://github.com/loyalpartner/selfsync/blob/master/README.zh-CN.md

    issue 区欢迎任何问题、bug 、想法。代码不多,对 Chrome Sync 协议感兴趣想摸清楚协议形状的也可以直接翻源码,应该比读 Chromium 省事不少。

    如果你也在做"把数据拿回家"这件事,咱们评论区聊。

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1116 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 18:03 PVG 02:03 LAX 11:03 JFK 14:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86