code-scan starred rsync
2021-09-06 23:44:22 Author: github.com(查看原文) 阅读量:195 收藏

tests

Package rsync contains a native Go rsync implementation.

Beware: very fresh. Might eat your data. You have been warned!

The only component currently is gokr-rsyncd, a read-only rsync daemon sender-only Go implementation of rsyncd. rsync daemon is a custom (un-standardized) network protocol, running on port 873 by default.

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

Existing rsync implementation survey

Language URL Note Max Protocol Server mode?
C WayneD/rsync original “tridge” implementation; I found older versions easier to study 31 yes
C kristapsdz/openrsync OpenBSD, good docs 27 yes
Go gokrazy/rsync → you are here ← 27 yes 🎉
Go jbreiding/rsync-go rsync algorithm no
Go kaiakz/rsync-os only client/receiver 27 no
Go knight42 proxy no
Go c4milo/gsync no
Java APNIC-net/repositoryd archived yes
Java JohannesBuchner/Jarsync archived, internet draft RFC “The rsync Network Protocol” yes
Java perlundq/yajsync yes
C++ gilbertchen/acrosync-library commercial no
Rust sourcefrog/rsyn client, “rsyn is rsync with no c” 27 no

Getting started

To serve the current directory via rsync on localhost:8730, use:

go install github.com/gokrazy/rsync/cmd/gokr-rsyncd
gokr-rsyncd -modulemap=pwd=$PWD

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

% rsync -v --archive --port 8730 rsync://localhost/pwd/ quine
receiving file list ... done
created directory quine
./
.git/
[…]
.github/workflows/main.yml
LICENSE
Makefile
README.md
cmd/gokr-rsyncd/rsyncd.go
doc.go
go.mod
go.sum
internal/rsyncd/connection.go
internal/rsyncd/rsyncd.go
interop_test.go

sent 1,234 bytes  received 5,678 bytes  13,824.00 bytes/sec
total size is 666  speedup is 0.10

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

% openrsync -v --archive --port 8730 rsync://localhost/pwd/ quine
socket.c:109: warning: connect refused: ::1, localhost
Transfer starting: 369 files
.git/index (1.1 KB, 100.0% downloaded)
Transfer complete: 5.5 KB sent, 1.2 KB read, 666 B file size

Limitations

Bandwidth

In my tests, gokr-rsyncd can easily transfer data at ≈ 2 Gbit/s. The current bottleneck is the golang.org/x/crypto/md4 implementation. With a faster implementation, we would be able to fill a 10 Gbit/s link!

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. Docker (Linux)
  3. privileged Linux
  4. privileged non-Linux

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

  • (On Linux only) The host file system is made read-only for gokr-rsyncd, to guard against accidental data exfiltration.
  • gokr-rsyncd is running without privileges, as user nobody, to limit the scope of what an attacker can do when exploiting a vulnerability.

Known gaps:

  • gokr-rsyncd 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-rsyncd -modulemap=pwd=/etc/tmpfiles.d

Close the editor and install the service using:

systemctl enable --now gokr-rsyncd.socket

Additional hardening recommendations:

Docker (unprivileged)

We provide a Dockerfile for gokr-rsyncd.

docker run \
  --read-only \
  -p 127.0.0.1:8730:8730 \
  -v /etc/tmpfiles.d:/srv/rsync:ro \
  stapelberg/gokrazy-rsync:latest \
    -modulemap=pwd=/srv/rsync

Additional hardening recommendations:

privileged Linux (including gokrazy.org)

When started as root on Linux, gokr-rsyncd will create a 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-rsyncd)/root/.

Additional hardening recommendations:

privileged non-Linux (e.g. Mac)

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

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

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


文章来源: https://github.com/gokrazy/rsync
如有侵权请联系:admin#unsafe.sh