2个版本

0.0.1 2020年5月13日
0.0.0 2020年4月26日

#23 in #rsync

Apache-2.0

62KB
1K SLoC

Rust中的兼容rsync客户端

crates.io docs.rs Tests

rsyn使用纯Rust重新实现了部分rsync网络协议(它是“没有C的rsync”)。

rsyn支持版本27的协议,该协议从2004年发布的2.6.0版rsync及其以后的版本以及openrsync开始支持。

安装

  1. https://rustup.rs/或其它地方安装Rust。

  2. 在rsyn源代码树中运行

    cargo install --path .
    

要运行互操作性测试(使用cargo test),您需要一个已安装的rsync副本。

用法

rsyn DIR通过启动一个rsync子进程并通过一对管道控制它,打印给定本地目录的递归列表。

rsyn USER@HOST:DIRrsyn HOST:DIR列出远程目录,通过SSH连接到rsync服务器。

路线图

预期的下一步是

  • 从本地子进程列出本地目录。

  • 通过SSH列出目录。

  • 从通过SSH的rsync复制目录到空本地目录。

  • 从rsync复制目录到本地目录,跳过已更新的文件,但下载缺失或过时的文件的全部内容。

  • 连接到rsync守护进程(rsync://):这些在启动主要rsync协议之前会讨论不同的介绍性协议。支持带有上述限制的下载。

  • 支持增量滚动求和和校验和文件传输:实际的“rsync算法”。

  • 支持常用的-a选项。

  • 通过SSH将目录上传到rsync。

以下点的顺序不太确定,但一些选项是

  • 充当rsync+ssh的服务器。特别是,使用它来测试rsync与自己以及与rsync之间的交互。

  • 充当一个rsync://守护进程。

  • 支持更多选定的命令行选项。

为什么要这样做?

rsync使用C语言手动解析复杂的二进制网络协议。虽然在90年代这是一个合理的选项,但今天看起来很危险。模糊测试工具发现了一些恶意节点可以崩溃rsync的情况,更糟糕的情况可能也会发生。

rsync的C代码相当复杂,有许多相互作用的选项和参数存储在全局变量中,这些变量会影响控制流的不同部分,包括结构体的编码和解码方式。

rsync仍然相当广泛地部署,并且做得很好。一个更安全的互操作实现可能很有用。

而且,就我个人而言:我多年前曾为rsync做出过贡献,现在用更好的工具和更多的经验重新审视这个领域,看看我是否能做得更好。

目标

  • rsyn将通过(首先)rsync+ssh或(稍后)rsync://与上游“tridge”rsync的最近版本进行互操作。

  • rsyn将支持常用的rsync选项和场景。最重要的是递归地传输文件,包括最后修改时间和权限,以及排除模式。

  • rsyn将通过Rust公共库API提供一个干净的接口,通过该接口可以在进程内启动和观察传输。正如Rust库的常规做法,API在1.0之前可能不稳定。

  • rsyn中的每个命令行选项都应该与rsync中的含义相同。

    如果一些rsync选项没有被支持,这是可以接受的。

    例外的是,rsyn特定的选项将以--Z开头,以区分它们并避免冲突。

  • rsyn的测试套件应该通过自动测试rsyn与rsync来演示互操作性。(稍后的版本可能会演示与rsync各种不同版本的兼容性,也许还会与openrsync兼容。)

  • rsyn应该没有任何unsafe块。(底层的Rust库有一些受信任的实现代码,并链接了一些C代码。)

  • rsyn将在Linux、macOS、Windows和其他Unix系统上运行,在64位和(如果操作系统支持)32位模式下运行。

    rsyn将使用在所有地方都受支持的Rust并发结构,而不是像rsync那样创造性地应用Unixism,例如在多个进程间共享套接字。

  • 即使面对任意恶意的节点,rsyn也应该安全。

    特别是,应仔细验证从对等节点接收到的路径,以防止路径遍历漏洞

  • 在吞吐量、CPU和内存方面,rsyn的性能应该与rsync相当。

  • rsyn应该具有良好的测试覆盖率:包括单元测试和互操作性测试。

  • rsyn代码应该是干净易懂的Rust代码。(rsync代码现在相当复杂。)rsyn将使用Rust类型检查来防止非法或不安全的状态。相互作用的选项应该分解为组合类型,而不是大量的if语句。

非目标

  • rsyn不一定支持rsync中的每个选项和功能。

    rsync有许多选项,这些选项(至少在rsync代码库中)以复杂的方式相互作用。其中一些似乎有特定的受众,或者已经过时,例如对rsh或HP-UX remsh的特殊支持。

  • rsyn使用由rsync实现定义的协议,并不打算演进该协议或添加rsyn特定的升级。

    rsync的协议已经很奇怪和复杂,而且是为了与今天存在的环境不同的环境而构建的。在我看来,全新的功能最好在一个全新的协议中。

  • rsyn不需要解决rsync协议中的安全弱点。

    rsync的块哈希、文件哈希和守护进程模式认证使用MD4,这在今天并不建议。在保持兼容性的情况下,这不能由rsyn单方面更改。

    对于敏感数据或可写目录,或者在任何不太受信任的网络上的任何流量,我强烈建议通过SSH运行rsync。

  • rsyn无需生成完全相同的文本/日志输出。

更多文档

致谢

感谢Tridge的杰出和慷慨的指导以及对开源的贡献。

如果没有Kristaps Dzonsons在openrsync项目中关于rsync协议的文档,这个项目将会难得多。

许可证

Apache 2.0.

贡献

我很乐意接受对这个项目的补丁。请阅读贡献指南行为准则

免责声明

这不是一个官方的Google项目。它不受Google支持,并且Google明确拒绝对其质量、适销性或特定用途的适用性的所有保证。

依赖

~6–8MB
~129K SLoC