LWN:同步一切的 syncthing!

Syncthing是一款开源同步工具,可在多台设备间安全同步文件,支持加密共享与自定义历史版本管理,无需中央服务器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关注了就能看到更多这么棒的文章哦~

Syncing all the things

By Jonathan Corbet
July 9, 2021
DeepL assisted translation
https://lwn.net/Articles/861978/

计算机等设备是非常有用的,肯定是这样的,因为我们大家都有这么多的计算机设备。然而,计算机的广泛应用带来了一个熟悉的问题:我们想要的文件总是没有存放在当前正在使用的这台机器上。解决方案之一就是使用同步服务(synchronization service),它可以使一组文件在多个机器上都一直保持最新版;有些公司已经基于这种服务创造了成功的商业产品。但是,我们中的一些人坚决反对将我们的数据交到这些公司和他们的专有系统中的做法。对于我们这些更希望保持对数据的控制权的人来说,像 Syncthing 这样的系统就提供了一个可能的解决方案。

各种同步系统的重心基本上来说都是相同的:指定一个目录列表和一个系统列表,确保这些目录在每个系统上的内容都相同。如果在一个系统上增加了一个文件,那么它就会被自动复制到其他系统上;修改和删除的内容(通常)也会被传播给其他系统。不过,有很多细节会导致麻烦,比如繁琐的设置程序,或者数据可能损坏,以及安全问题,这些都可能使同步出错。因此,用户必须对这些系统给予很大的信任;开放源代码就是实现这一目标的重要一环,此外通常也需要信赖相关开发者已经仔细考虑过这些问题。

Syncthing

当北半球的夏天来临时,新鲜的新闻很少,不过现在机会来了,终于可以有空看见一两个有趣的软件项目了。因此,编者尝试了一下 Syncthing 1.17.0 版本,这是从 Fedora 和 CentOS(EPEL)仓库获得的。在 Fedora 上只需要运行 syncthing 命令来启动同步守护程序,别害怕这个过程中产生的大量日志数据。而 EPEL 软件包似乎将 Syncthing 安装为一个 systemd 用户服务,这意味着只需要登录系统,守护进程就会自动启动。

[Syncthing 管理屏幕]

该守护进程的行为,是通过一个内置的 webserver 来进行配置和管理的,默认位于 8384 端口,可以参见上面的示例图片。第一次进入的时候不需要认证,用户第一步想要做的事情应该就是配置好登录认证信息。默认情况下,Web 服务器只能通过 loopback 接口访问到,可以修改配置文件来使其可以被互联网访问到,但听起来这不是一个好主意,哪怕启用了认证也最好别这么做。正如文档中所建议的,要想在远程机器上获得 Web 界面的话,有一种方法是在本地系统中建立一个 SSH tunnel。

当它第一次启动时,Syncthing 会生成一个 "设备 ID "来识别本地系统;它看起来像这样。

rs5rz7k-corjap3-tzecyoh-iblfdzm-ksfwoxb-vbeiysb-f7mwech-vqcglaz

在两台机器之间设置同步的过程类似于蓝牙配对的过程。它是通过向每一方提供属于另一方的设备 ID 来完成的。这里建议使用复制粘贴的方式来避免填写出错。另外,如果两个系统都在同一个本地网络上的话,它们可以通过广播信息发现对方,并询问用户(通过管理界面)是否需要建立连接。

在系统间建立好连接(connection)之后,用户必须要告诉 Syncthing 需要同步哪些目录应该被同步,也就是需要设置文件夹并与已知的远程系统(Syncthing 称之为 "设备")中的全部或一部分系统来进行共享。一旦共享在远程端被接受了,那么后续的文件改动将被来回传播。在可能的情况下,Syncthing 会依靠内核来获取文件更改的通知,这样就可以尽量快速地进行传播。

有很多选项可以设置来控制共享的行为。例如,这个共享可以配置成单向的,这样就是在一个指定系统中创建文件就可以被发送出去,而不会接受来自其他系统的修改。一个特别有趣的(尽管是个崭新功能还处于 "测试" 阶段)功能就是能够以加密的形式向特定的系统共享文件。例如,如果某个系统是一个云服务器,主要用来备份或分发的目的,那么传递给它的数据可以都是加密过的数据,这样它就不能真正看到这些内容了。而在共享网络中的任何其他系统中,只要有正确的密码,就能读取这些文件。还可以配置多种方法来管理历史版本,也就是当一个系统改变了某个文件时,相应的旧版本的文件会被按照某种规则保留下来。

值得注意的是,虽然可以配置一组 Syncthing 客户端全部都连接到一个中央服务器上,但 Syncthing 本身并没有强制要求有这种中央节点。系统可以以任何有意义的方式来互相连接。如果某个系统发现它需要的文件已经传播到了 connection 中的多个对端,那么它可以以类似 BitTorrent 的方式,哪个系统能首先提供某块数据块的话,就从它来接收这一部分。

Discovery and security

有趣的是,在配置阶段都不涉及主机名或 IP 地址,至少在默认情况下是这样。系统只根据设备 ID 来找到对方,不管它们连接到的是哪个网络。显然,这需要一些第三方帮助。Syncthing 项目运行了一组 "discovery" 服务器,帮助系统根据其设备 ID 找到对方。还有一套 "relay server, 即中继服务器",可以用来在两个系统无法直接通讯时使用,比如当它们被 NAT 防火墙隔离时。

这种架构显然是考虑了一些安全问题。例如,只有在没有其他选择的情况下,数据才会通过中继服务器传输,并且在两端都会进行加密再发送。但是,仍有一些信息是可能被恶意的 discovery 或 relay server 获得的,这一点可能会让部分用户感到担心。对于任何真正感到担心的人来说,因为这两种类型的服务器的代码都是可以直接编译使用的,因此任何人都可以建立自己的私有服务器,并配置他们的 Syncthing 实例来只使用自己的私有服务器。

根据文档所说,设备 ID 不需要保密,因为双方都需要采取行动来确认是否要建立这个连接。人们可能会想,攻击者是否会试图用目标系统的设备 ID 来仿造一个系统,从而能够访问到其管理的文件。不过,该 ID 本质上是一个公钥,而连接过程涉及到要证明自己拥有私钥,所以这样的攻击应该是不可能发生的。本页(https://docs.syncthing.net/dev/device-ids.html%EF%BC%89%E8%AF%A6%E7%BB%86%E5%9C%B0%E6%8F%8F%E8%BF%B0%E4%BA%86%E8%AE%BE%E5%A4%87 ID。

Syncthing on the move

也许今天网络上最常见的同步场景,就是将照片从手机复制到中央服务器上。由于安卓手机还是基于 Linux 的,因此人们只需要在上面建立一个正常的 shell 环境,并把 Syncthing 放在那里就可以实现这一目标;这一过程应该并不麻烦,可能一天都不需要。或者,人们也可以直接安装安卓应用程序,这在 F-Droid 和 Google Play 商店中也都存在。这个应用程序,如下图所示,提供了开箱即用的配置,包含了一个相机文件夹(设置的共享模式是 send-only),所以只要再设置好两端的连接就行。而且,为了避免人们担心用屏幕键盘输入这些设备 ID 不够安全,该应用程序还可以读取 web 界面上提供的二维码,这就大大地简化了这个过程。

[Syncthing Android 应用程序]

不过它有一个略微让人惊讶的行为,就是该应用程序申请获得定位许可,这似乎不是它本该需要的权限。其实它需要这种权限来确定手机当前处于哪个 WiFi 网络中(如果有连接到 WiFi 的话),这样会方便配置应该在什么时候进行同步的功能了。计费 WiFi 服务的用户可能会希望使用这一机制,从而避免在使用这些需要花钱的 WiFi 时进行同步。如果没有获得这个权限,那么只要连接到任何 WiFi 网络,该应用程序都会默认执行同步操作。

很容易就会想到,用户可能会抱怨安卓应用会迅速耗尽电池电量。编者在有限的测试中没有观察到这种现象。可能功耗方面最糟糕的问题都已经被 fix 了。

Closing thoughts

该项目称,"安全是项目的主要目标之一",而开发者似乎确实在这个问题上花了很多心思。加密被用在正确的地方,也进行了证书验证等等。快速搜索一下 CVE 的话,发现在过去四年里有两个条目跟它有关,其中一个漏洞被利用的话可以覆盖写入任意文件,要利用该漏洞就需要首先获得共享网络中的一台机器的控制权,如果真被攻击者获得了这个访问权,那么保护数据的战斗本来就可能已经失败了。尽管似乎没有做任何形式的 formal security audit,但 Syncthing 的开发者的做法至少都是正确的。

关于可靠性,不难搜索到(并找到)各种可怕的故事,这些故事来自使用 Syncthing 之后丢失过数据的用户。似乎这些问题中许多都是来自于操作错误。如果你配置了一个系统并允许它删除你所有的数据,那么它可能最终认为你确实希望它进行这些删除操作。同步操作经常会迅速地把错误的操作也传播出去。这里如果配置好了 Syncthing 本身的版本管理的话会有所帮助,同时也可以尽可能地避免使用双向同步。Syncthing 似乎没有出现过丢失很多数据的错误,但经常进行备份永远都是一个好主意。

Syncthing 至少从 2013 年就发布出来帮助大家进行同步工作了,当时它的第一个提交出现在 Git 仓库中。LWN 在 2014 年的时候就介绍过。该项目主要用 Go 语言编写,并在 Mozilla 公共许可证下发布。目前的 Syncthing 版本是 1.18.0,在 7 月 6 日发布,这也正是本文撰写的时间。该项目在过去一年中几乎是每月发布一次;1.7.0 是在 2020 年 7 月 7 日发布的。在过去的一年中,有 728 个 non-merge commit 进入了 Syncthing 仓库,来自 40 个开发者。前三名开发者(Simon Frei、Jakob Borg 和 Jesse Lucas)提供了这些提交的 76% 以上。因此,该项目并没有拥有大量的开发者,但目前看来已经非常健康了。

一家名为 Kastelo 的公司为 Syncthing 提供支持订阅(support subscriptions),并为 Syncthing 的发展提供了大量资源。该公司也是 Syncthing 基金会的一部分,该基金会负责管理此项目的基础设施,并为项目开发提供资助。

总而言之,Syncthing 给我们留下了很好的印象。开发人员似乎已经做了工作,来创建一个功能强大、可靠、安全的系统,并且表现得相当好。但同时他们也做了一些工作,使得其更加易于设置和使用,这似乎是许多自由软件项目失败的地方。对于那些想要控制自己的数据的同步和复制需求的人来说,这是一个有吸引力的工具。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值