rsync

gokrazyBSD-3-Clause活跃维护

用 Go 实现的 rsync 客户端和服务端,支持双向收发文件,可替代原生 rsync 做上传下载和增量同步。

rsync in Go! implements client and server, which can send or receive files (upload, download, all directions supported)

v0.3.10发布于 2026-10-25 15:18 UTC880star +1 / 7 天74fork同步于 2026-11-10 11:54 UTC

怎么上手

由 README 提炼,执行前请确认
go install github.com/gokrazy/rsync/cmd/gokr-rsync@latest
gokr-rsync --daemon --gokr.listen=localhost:8730 --gokr.modulemap=man=/usr/share/man
硬件要求按 README 说明

README 未说明

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

用 Go 实现的 rsync 客户端与服务端,与原生 rsync 协议兼容,可嵌入程序或自建服务

用 Go 实现的 rsync 客户端和服务端,支持双向收发文件,可替代原生 rsync 做上传下载和增量同步。

核心能力

  • gokr-rsync 命令同时充当客户端和服务端,支持双向收发文件
  • 支持 daemon 模式与 SSH 两种服务方式,可匿名或鉴权
  • 提供 rsynccmd 包,可把 rsync 传输嵌入自己的 Go 程序
  • 提供 rsyncd 包,可自行实现 rsync 服务端
  • 用 os.Root 与 Linux Landlock 沙箱降低路径穿越等漏洞风险

容易踩的坑

项目自述测试不如原生 tridge 版充分、用户尚少,重要数据需自行验证传输结果;SSH 命令模式(setup 3)下客户端可能需显式加 --protocol=27;SSH daemon 模式(setup 4)要求服务端存在 ~/.config/gokr-rsyncd.toml 配置文件

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v0.3.10
  1. v0.3.10最新正式版2026-10-25 · 2026-10-25 15:18 UTC

    This release contains a number of hardening changes to prevent malicious peers from crashing the server or consuming lots of resources (primarily RAM).

    Full Changelog: https://github.com/gokrazy/rsync/compare/v0.3.9...v0.3.10

  2. v0.3.92026-10-21 · 2026-10-21 06:55 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/gokrazy/rsync/compare/v0.3.8...v0.3.9

  3. v0.3.82026-09-23 · 2026-09-23 17:32 UTC
    查看更新说明
  4. v0.3.72026-09-07 · 2026-09-07 14:46 UTC
    查看更新说明
  5. v0.3.62026-08-07 · 2026-08-07 14:03 UTC
    查看更新说明

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    gokrazy rsync

    Go Reference tests Sourcegraph

    gokrazy/rsync is an Rsync program and reusable library implemented in the Go programming language, originally as part of the gokrazy Go appliance platform project. gokrazy/rsync is (wire-)compatible with the original "tridge" Rsync.

    Various use-cases are supported:

    • The gokr-rsync command implements an rsync client and server, which can send or receive files (all directions supported).
    • You can set up a public or private rsync server, in daemon mode or via SSH (anonymous or authorized).
    • You can embed rsync in your program with the rsynccmd package.
    • You can implement your own rsync server with the rsyncd package.

    Aside from being implemented in Go, a memory-safe programming language, gokrazy/rsync makes use of Go’s traversal-resistant file API (os.Root) and the Linux Landlock Unprivileged Sandboxing to steer clear of vulnerabilities. In server settings, gokrazy/rsync supports mount namespaces and can be further locked down with systemd’s various hardening options.

    This project accepts contributions as time permits to merge them (best effort).

    Notable users / use-cases

    How do I know this project won’t eat my data?

    This rsync implementation is not as well-tested as the original “tridge” implementation from the Samba project. gokrazy/rsync was started in 2021 and doesn’t have many users yet.

    With that warning out of the way, the rsync protocol uses MD4 checksums over file contents, so at least your file contents should never be able to be corrupted.

    There is enough other functionality (delta transfers, file metadata, special files like symlinks or devices, directory structures, etc.) in the rsync protocol that provides opportunities for bugs to hide.

    I recommend you carefully check that your transfers work, and please do report any issues you run into!

    Existing rsync implementation survey

    LanguageURLNoteMax ProtocolServer mode?
    CRsyncProject/rsync (formerly WayneD/rsync)original “tridge” implementation; I found older versions easier to study32✔ yes
    Ckristapsdz/openrsyncOpenBSD, good docs27✔ yes
    Gogokrazy/rsync→ you are here ←27✔ yes 🎉
    Gojbreiding/rsync-gorsync algorithm❌ no
    Gokaiakz/rsync-osonly client/receiver27❌ no
    Goknight42proxy❌ no
    Goc4milo/gsync❌ no
    JavaAPNIC-net/repositorydarchived✔ yes
    JavaJohannesBuchner/Jarsyncarchived, internet draft RFC “The rsync Network Protocol”✔ yes
    Javaperlundq/yajsync✔ yes
    C++gilbertchen/acrosync-librarycommercial❌ no
    Rustsourcefrog/rsynarchived, client, “rsyn is rsync with no c”27❌ no

    Getting started

    To serve the /usr/share/man directory via rsync on localhost:8730, use:

    go install github.com/gokrazy/rsync/cmd/gokr-rsync@latest
    gokr-rsync --daemon --gokr.listen=localhost:8730 --gokr.modulemap=man=/usr/share/man
    

    You can then copy the contents of the current directory with clients such as rsync(1):

    % rsync -v --archive --port 8730 rsync://localhost/man/ man
    receiving file list ... done
    created directory man
    ./
    ar/
    ar/man1/
    […]
    zh_TW/man8/userdel.8.gz
    zh_TW/man8/usermod.8.gz
    
    sent 658.973 bytes  received 88.012.067 bytes  3.940.935,11 bytes/sec
    total size is 84.504.170  speedup is 0,95
    

    …or openrsync(1), shown doing a differential update:

    % openrsync -v --archive --port 8730 rsync://localhost/man/ man
    openrsync: warning: connect refused: ::1, localhost
    Transfer starting: 40202 files
    […]
    zh_TW/man8/userdel.8.gz (732 B, 100.0% downloaded)
    zh_TW/man8/usermod.8.gz (1.8 KB, 100.0% downloaded)
    Transfer complete: 83.93 MB sent, 643.5 KB read, 80.59 MB file size
    

    Usage / Setup

    setupencryptedauthenticatedprivate files?privilegesprotocol versionconfig required
    1. rsync daemon protocol (TCP port 873)❌ no⚠ rsync (insecure)❌ only world-readable✔ dropped + namespace✔ negotiatedconfig required
    2. anon SSH (daemon)✔ yes✔ rsync❌ only world-readable✔ dropped + namespace✔ negotiatedconfig required
    3. SSH (command)✔ yes✔ SSH✔ yes⚠ full user⚠ assumedno config
    4. SSH (daemon)✔ yes✔ SSH (+ rsync)✔ yes⚠ full user✔ negotiated~/.config/gokr-rsyncd.toml required

    Regarding protocol version “assumed”: the flags to send over the network are computed before starting SSH and hence the remote rsync process. You might need to specify --protocol=27 explicitly on the client. Once the connection is established, both sides do negotiate the protocol, though.

    Setup 1: rsync daemon protocol (TCP port 873)

    Serving rsync daemon protocol on TCP port 873 is only safe where the network layer ensures trusted communication, e.g. in a local network (LAN), or when using Tailscale or similar. In untrusted networks, attackers can eavesdrop on file transfers and possibly even modify file contents.

    Prefer setup 2 instead.

    Example:

    • Server: gokr-rsync --daemon --gokr.modulemap=module=/srv/rsync-module
    • Client: rsync rsync://webserver/module/path

    Setup 2: anon SSH (daemon)

    This setup is well suited for serving world-readable files without authentication.

    Example:

    • Server: gokr-rsync --daemon --gokr.modulemap=module=/srv/rsync-module --gokr.anonssh_listen=:22873
    • Client: rsync -e ssh rsync://webserver/module/path

    Setup 3: SSH (command)

    This setup is well suited for interactive one-off transfers or regular backups, and uses SSH for both encryption and authentication.

    Note that because gokr-rsync is invoked with user privileges (not root privileges), it cannot do namespacing and hence retains more privileges. When serving public data, it is generally preferable to use setup 2 instead.

    Note that rsync(1) assumes the server process understands all flags that it sends, i.e. is running the same version on client and server, or at least a compatible-enough version. You can either specify --protocol=27 on the client, or use setup 4, which negotiates the protocol version, side-stepping possible compatibility gaps between rsync clients and gokr-rsync.

    Example:

    • Server will be started via SSH
    • Client: rsync --rsync-path=gokr-rsync webserver:path

    Setup 4: SSH (daemon)

    This setup is more reliable than setup 3 because the rsync protocol version will be negotiated between client and server. This setup is slightly inconvenient because it requires a config file to be present on the server in ~/.config/gokr-rsyncd.toml.

    Note that this mode of operation is only implemented by the original “trigde” rsync, not in openrsync. Apple started shipping openrsync with macOS 15 Sequoia. For a while, /usr/libexec/rsync/rsync.samba was still available, but on more recent macOS versions you need to use homebrew or Nix to get tridge rsync.

    Example:

    • Server will be started via SSH
    • Client: rsync -e ssh --rsync-path=gokr-rsync rsync://webserver/module/path

    Limitations

    Bandwidth

    In my tests, gokr-rsync can easily transfer data at > 6 Gbit/s. The current bottleneck is the MD4 algorithm itself (not sure whether in the “tridge” rsync client, or in gokr-rsync). Implementing support for more recent protocol versions would help here, as these include hash algorithm negotiation with more recent choices.

    Protocol related limitations

    • xattrs (including acls) was introduced in rsync protocol 30, so is currently not supported.

    Supported environments and privilege dropping

    Supported environments:

    1. systemd (Linux)
    2. privileged Linux (running as root, or in a user namespace)
    3. privileged non-Linux
    4. unprivileged Linux, Mac or Windows

    In all environments, the default instructions will take care that:

    • gokr-rsync uses Go’s Traversal-resistant os.Root file APIs to restrict all file access to the specified paths.
    • (On privileged Linux only) Only configured rsync modules from the host file system are mounted (read-only, unless the module is writable) into a Linux mount namespace for gokr-rsync, to guard against data modification and data exfiltration.
    • (On Linux only) File system access is restricted using the Landlock Linux kernel security module, which works similar to OpenBSD’s unveil(2) API.
    • (On privileged environments) gokr-rsync drops privileges to user nobody, to limit the scope of what an attacker can do when exploiting a vulnerability.

    Known gaps:

    • gokr-rsync does not guard against denial of service attacks, i.e. consuming too many resources (connections, bandwidth, CPU, …).

    systemd (unprivileged)

    We provide a gokr-rsyncd.socket and gokr-rsyncd.service file for systemd. These files enables most of systemd’s security features. You can check by running systemd-analyze security gokr-rsyncd.service, which should result in an exposure level of “0.2 SAFE” as of systemd 249 (September 2021).

    First, configure your server flags by creating a systemd service override file:

    systemctl edit gokr-rsyncd.service
    

    In the opened editor, change the file to:

    [Service]
    ExecStart=
    ExecStart=/usr/bin/gokr-rsync --daemon --gokr.modulemap=pwd=/etc/tmpfiles.d
    

    Close the editor and install the service using:

    systemctl enable --now gokr-rsyncd.socket
    

    Additional hardening recommendations:

    privileged Linux (including gokrazy.org)

    When started as root on Linux, gokr-rsync will create a Linux mount namespace, mount all configured rsync modules read-only into the namespace, then change into the namespace using chroot(2) and drop privileges using setuid(2).

    Tip: you can verify which file system objects the daemon process can see by using ls -l /proc/$(pidof gokr-rsync)/root/.

    Additional hardening recommendations:

    privileged non-Linux (e.g. Mac)

    When started as root on non-Linux (e.g. Mac), gokr-rsync will drop privileges using setuid(2).

    unprivileged with write permission (e.g. from a shell)

    To prevent accidental misconfiguration, gokr-rsync refuses to start when it detects that it has write permission in any configured rsync module.