rsync is a fast, powerful, and network-capable filesystem synchronization tool. It is useful for transferring files across a variety of mediums, can resume partial or interrupted transfers, perform its own user authentication, and can be run in numerous flexible configurations. Numerous utilities are built atop rsync
, such as the Duplicity backup tool, making rsync
an important infrastructural technology.
- 1 Installing
- 2 Configuring
- 2.1 Socket-activated systemd service unit made available via Tor
- 2.2 Restricted rsync over restricted SSH login (optionally over Tor)
- 3 Connecting from a client
- 4 Hardening
Installing¶
The rsync
package available in most distribution’s package repositories contains everything needed for a basic client and/or server configuration. You likely already have rsync
installed on your system. If you do not, on Debian-derived GNU/Linux distributions, install rsync
with:
sudo apt install rsync
Configuring¶
There are numerous ways to set up rsync
infrastructure for various collaborative purposes. This page describes the configurations useful for and familiar to the Tech Autonomy Infrastructure committee needs.
Socket-activated systemd service unit made available via Tor¶
A “socket-activated service” is systemd jargon for an on-demand server invoked by the systemd
service manager process itself. (For the purposes of this guide, systemd
replaces the xinetd
process, which itself obsoleted the even older inetd
process, which may be familiar to seasoned system administrators.) We prefer to use on-demand server processes for rsync
for performance and resource conservation reasons.
The transfer’s data itself must be protected when in motion by a transport layer protection mechanism. This can be a TLS or SSH tunnel or, arguably more usefully, a Tor Onion service ("hidden service"). This section’s examples showcase how one might configure a socket-activated rsync
server that is made available only over a Tor Onion service. See the Tor page for information about configuring authenticated Onion services, themselves.
Do this to configure rsync
as a server:
- First, we’ll need to configure the
rsync
daemon process itself. This is done by writing a configuration file and placing it in a conventional place, which is usually/etc/rsyncd.conf
for most GNU/Linux systems. Paste the following configuration file, being careful to change the values ofMODULE_NAME
,YOUR_USER_NAME
,YOUR_GROUP_NAME
,RSYNC_USER_NAME
, and specific pathnames to sensible values given the data you intend to make available torsync
clients:
# File: rsyncd.conf # # This is the configuration file for the rsync daemon process. # It provides a default set of options for rsync transfers and # offers a fallback for situations when rsync is not invoked # using a socket-activated incoming network connection. That is, # some options configured here are ignored when rsync is started # by inetd, xinetd, or a systemd socket unit. See rsnycd.conf(5) # for more details. ##################### # Global directives # ##################### # Runtime files. lock file = /var/run/rsync/rsyncd.lock pid file = /var/run/rsync/rsyncd.pid # Send any and all logging performed by rsync to a black hole. log file = /dev/null transfer logging = no # Only listen on the loopback interface; use Tor for remote connectivity. address = 127.0.0.1 # Don't use a default port on the LAN; the authenticated Onion # service can expose the default on the WAN side, if you want. # See `/etc/services` for your system's default rsync port. #port = 8873 # Restrict transfers to (but not connections from) IP ranges. hosts allow = 127.0.0.1 # Don't do any DNS lookups or hostname matching. reverse lookup = no forward lookup = no # Don't offer a list of exported modules. list = no # Wait no more than five minutes (300 seconds) for client data. timeout = 300 # chroot(2) to an exported module's `path`. # This requires the parent `rsync` process to be run as root. # The default setting is `true`. #use chroot = true # The default for all modules is to be read only. # Set this to `false` on a module level to make that one module # writable, or using `auth users` to set this on a per-user per-module # level to grant specific users write access while defaulting to read only # access for the remainder of users not explicitly granted write permission. #read only = true # Provide application-level user access control. secrets file = /etc/rsyncd.secrets #################### # Exported modules # #################### # # Define your exports here. # [MODULE_NAME] comment = A human-readable description of the module. path = /path/to/whatever/you/want/to/share uid = YOUR_USER_NAME gid = YOUR_GROUP_NAME auth users = RSYNC_USER_NAME
- The above configuration uses application-level user access control, so we’ll need to define users and their passwords in the
secrets file
location. In the snippet above, this location is/etc/rsyncd.secrets
. Paste the following in a file at that path:
# FILE: /etc/rsyncd.secrets # # Username and password database for rsync daemon. # This file is described by rsyncd.conf(5). # # The format of this file is: # # user_name:password # # where `user_name` is an rsync user name, and `password` is # the given user's password. Lines containing only whitespace # or lines that begin with a `#` character are ignored. # # Users defined here do not need to exist as Operating System # user accounts, although they can be. Again, see the manual # page for rsyncd.conf(5) for additional details. RSYNC_USER_NAME:RSYNC_PASSWORD
- The rsync daemon will refuse to authenticate users against the secrets file unless its filesystem permission bits are set to
600
:
sudo chown root:root /etc/rsyncd.secrets sudo chmod 600 /etc/rsyncd.secrets
- Next, we’ll need to create two systemd files. The first is a socket unit that provides
inetd
-style backwards compatibility. Paste the following into/etc/systemd/system/rsyncd.socket
:
# FILE: /etc/systemd/system/rsyncd.socket # # rsync daemon socket activation unit # # This file is a systemd socket unit (see systemd.socket(5)) # that offers inetd-style equivalency for starting the rsync # daemon when an incoming connection is detected. # # Without this socket unit started, the rsync daemon is # not available over a network connection. Tor handles all # other parts of the network connection and connectivity. # [Unit] Description=rsync socket for per-connection servers After=tor.service [Socket] ListenStream=127.0.0.1:873 Accept=yes [Install] WantedBy=sockets.target
- Finally, write the `rsyncd@.service` unit file, placing it into the
/etc/systemd/system
directory:
# FILE: /etc/systemd/system/rsyncd@.service # # On-demand per-connection socket-activated rsync server. # # This file is a systemd service unit (see systemd.service(5)) # offering a hand-off from systemd to `rsync` when an incoming # connection bound to the ListenStream address (defined in the # rsyncd.socket unit file) is detected. [Unit] Description=rsync per-connection server [Service] Type=simple ExecStart=-/usr/bin/rsync --daemon StandardInput=socket RuntimeDirectory=rsync # Extra security precautions MemoryDenyWriteExecute=true NoNewPrivileges=true PrivateDevices=true PrivateTmp=true # On some systems, the `PrivateUsers` directive causes errors of the form: # # @ERROR: setgid failed # # If that happens for your system, comment out the `PrivateUsers` line. PrivateUsers=true ProtectControlGroups=true ProtectHome=true ProtectKernelModules=true ProtectKernelTunables=true ProtectSystem=full LockPersonality=true RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 RestrictRealtime=true
- Once the configuration files are in place, invoke them with the following
systemctl
commands:
systemctl daemon-reload # Tell systemd to look at the new files we added. systemctl enable rsyncd.socket # Load the socket-activation unit. systemctl start rsyncd.socket # Manually start the socket unit.
To confirm that this is working, use the ss
command to check for listening ports:
sudo ss --listening --tcp --numeric --processes | grep 873
LISTEN 0 128 127.0.0.1:873 *:* users:(("systemd",pid=1,fd=25))
This rsync
server is only accepting connections from 127.0.0.1
, which makes it unavailable to remote clients unless something like an SSH tunnel or Tor Onion service is exposing it.
Restricted rsync over restricted SSH login (optionally over Tor)¶
TK-TODO: See the rrsync
(“restricted rsync”) script in the rsync distribution. See also Restricting SSH Access to rsync and Allow the restricted rsync (rrsync) script for arbitrary directories with authorized_keys.
Connecting from a client¶
Clients can make connections as normal:
rsync rsync://RSYNC_USER_NAME@server.example.com/MODULE_NAME /tmp/foo
To make a connection over Tor, you will need to Torify your rsync
invocation; consider using torsocks(1)
for this purpose. (Another option if the torsocks
package is unavailable to you is socksify(1), available as part of the dante-client
package on most Debian-derived systems.) See the Tor project’s guides to torification with torsocks for more details. In brief, though, all you should have to do is prepend the rsync command with torsocks
and change the server address to the service’s .onion
address:
torsocks rsync rsync://RSYNC_USER_NAME@abcdef0123456789.onion/MODULE_NAME /tmp/foo
If the Onion service to which you are connecting requires clients to authenticate themselves, see also Connecting to an authenticated Onion service for instructions on configuring your Tor client, which will be necessary for the torsocks
command above to succeed.
Hardening¶
If you have configured rsync
on your own (rather than following this guide), take some care to secure your system by ensuring no unintended access to your rsync server is possible, and that your rsync server is protecting your own and your user’s privacy by not retaining more data than necessary. To do so, check (and double-check) the following configuration options:
- Use the
hosts allow
directive to restrict which remote IP addresses (or hostnames) can upload or download files. - Set a non-default
port
number. - Set the
log file
path to/dev/null
to stoprsync
from logging connection details, which contain IP addresses by default. - Set the
list
value tono
orfalse
for any module you do not want visible to clients, or globally if you do not want clients to be able to ask for a listing of exported modules. - Set the
read only
value toyes
ortrue
for any exported module that you don’t want clients making changes to. - If you do not need hostname matching for the
hosts allow
directive or similar, setreverse lookup
and/orforward lookup
tono
orfalse
to disable rsync’s DNS requests, especially if you have not secured your network’s DNS servers or clients. - Use rsync’s own application-level authentication by using a
secrets file
and anauth users
directive for sensitive modules. - When making a connection to an rsync-authenticated server from a client, use the
--password-file
option to avoid exposing your rsync user’s password on the command line, where it is visible in process listings (ps -ef
and similar).