rrsync(1)

๐Ÿ’… rrsync(1) โ€” the manual, but make it make sense

okay so bestie, real talk: this is the rrsync page from the rsync manual, and it's genuinely one of the most useful little security gems out there. it's a script that locks an ssh login down so it can only do rsync transfers inside one directory. no shell, no wandering off, no chaos. ๐ŸŒธ


โœจ NAME โœจ

rrsync โ€” a script that sets up restricted rsync users via ssh logins ๐ŸŽ€


โœจ SYNOPSIS โœจ

rrsync [-ro|-wo] [-munge] [-absolute] [-no-del] [-no-lock] [-no-overwrite] DIR

The one and only non-option argument is the restricted DIR you're locking things into. Lowkey flexible on the format: it can be relative to the user's home directory, or an absolute path. ๐Ÿ’œ

And hiii, the online version of this manpage (it's got the cross-linking of topics, which is kind of iconic) lives at https://download.samba.org/pub/rsync/rrsync.1 โ€” go look, it's giving โœจdocumentationโœจ.


โœจ DESCRIPTION โœจ

So here's the vibe: a user's ssh login can be restricted to only allow running an rsync transfer, and there are two easy ways to do it, and both of them eat:

  • forcing the running of the rrsync script
  • forcing the running of an rsync daemon-over-ssh command

Both setups use an ssh feature that lets you force a command to run instead of handing over an interactive shell. ๐Ÿซถ

โš ๏ธ but heads up, bestie: if the user's home shell is bash, please please please read the BASH SECURITY ISSUE section below, there's a potential problem and we do not ignore it.

๐Ÿฆ‹ the rrsync script route

To use the rrsync script, you edit the user's ~/.ssh/authorized_keys file and slap a prefix like one of these (followed by a space, don't forget the space) in front of every ssh-key line that should be restricted:

command="rrsync DIR"
command="rrsync -ro DIR"
command="rrsync -munge -no-del DIR"

Then make sure the rrsync script has the option restrictions you actually want. Pro tip from the manual itself: you may want to copy the script to a local bin dir with a unique name if you want to have multiple configurations (yes, multiple, it's allowed, live your truth). One or more rrsync options can be specified before the DIR if you want to restrict the transfer even further. ๐Ÿ”ฅ

๐ŸŒˆ the rsync daemon route

To use an rsync daemon setup, edit the user's ~/.ssh/authorized_keys file and add a prefix like one of these (again, followed by a space) in front of each ssh-key line that should be restricted:

command="rsync --server --daemon ."
command="rsync --server --daemon --config=/PATH/TO/rsyncd.conf ."

Then make sure the rsyncd.conf file is created with one or more module names, each with the appropriate path and option restrictions. If rsync's --config option is omitted, it defaults to ~/rsyncd.conf. Go read the rsyncd.conf(5) manpage for the deets on how to configure an rsync daemon. ๐Ÿ’–

๐Ÿ’… rrsync vs. daemon, the showdown

When you're using rrsync, there can be just one restricted dir per authorized key. A daemon setup, on the other hand, allows multiple module names inside the config file, each one with its own path setting. So like, pick your fighter based on how many dirs you're juggling. ๐ŸŽ€

The remainder of this manpage is dedicated to using the rrsync script.


โœจ OPTIONS โœจ

  • -ro โ€” allow only reading from the DIR. this implies -no-del and -no-lock, no take-backs. ๐Ÿ™ˆ
  • -wo โ€” allow only writing to the DIR.
  • -munge โ€” enable rsync's --munge-links on the server side.
  • -absolute โ€” allow file-transfer arguments to name the restricted directory using its absolute server path. For example, with rrsync -absolute /path/to/root, the transfer arg /path/to/root/dir1 is accepted as an alias for dir1. cute little alias situation โœจ
  • -no-del โ€” disable rsync's --delete* and --remove* options. no deleting, we don't do that here. ๐Ÿ’€
  • -no-lock โ€” avoid the single-run (per-user) lock check. Useful with -munge.
  • -no-overwrite โ€” enforce --ignore-existing on the server. Prevents overwriting existing files when the server is the receiver.

okay so this one is a whole paragraph and it matters, so like, listen up bestie: because --ignore-existing protects only the file being transferred, this also refuses the options that can reach a different existing file in the restricted dir: --log-file, --partial-dir, --delay-updates, --delay-symlinks (which creates its symlinks at the end of the transfer, replacing whatever has appeared at that name since the check), and backup mode (-b, --backup-dir, whose published backup replaces whatever already occupies the backup name). Resumable uploads with an explicit --partial-dir, --delay-updates, --delay-symlinks, and server-side logging are therefore unavailable under this option. yeah. that's the trade-off. ๐Ÿซ 

  • -help, -h โ€” output this help message and exit.

โœจ SECURITY RESTRICTIONS โœจ

The rrsync script validates the path arguments it is sent, to try to restrict them to staying within the specified DIR. it's doing its little security check and honestly? slay. ๐Ÿ›ก๏ธ

The rrsync script rejects rsync's --copy-links option (by default) so that a copy cannot dereference a symlink within the DIR to get to a file outside the DIR. no sneaking out the side door. ๐Ÿšช

The rrsync script rejects rsync's --protect-args (-s) option because it would allow options to be sent to the server-side that the script cannot check. If you want to support --protect-args, use a daemon-over-ssh setup.

The rrsync script accepts just a subset of rsync's options that the real rsync uses when running the server command. A few extra convenience options are also included to help it to interact with BackupPC and accept some convenient user overrides. ๐Ÿ’œ

The --nice option is limited to local CPU nice 19, idle I/O priority or both. Other values could raise the server process priority and are rejected. ๐Ÿšซ

The script (or a copy of it) can be manually edited if you want it to customize the option handling. yes, you can justโ€ฆ edit it. it's your world. โœจ


โœจ BASH SECURITY ISSUE โœจ

okay so this is the part where I hold your hand, because it's important. ๐Ÿ˜ญ

If your users have bash set as their home shell, bash may try to be overly helpful and ensure that the user's login bashrc files are run prior to executing the forced command. This can be a problem if the user can somehow update their home bashrc files โ€” perhaps via the restricted copy, a shared home directory, or something similar. and like, an overly helpful shell is not the vibe you want here.

One simple way to avoid the issue is to switch the user to a simpler shell, such as dash. When choosing the new home shell, make sure that you're not choosing bash in disguise, as it is unclear if it avoids the security issue. (bash in a trench coat? we don't know, don't risk it. ๐Ÿ•ต๏ธ)

Another potential fix is to ensure that the user's home directory is not a shared mount and that they have no means of copying files outside of their restricted directories. This may require you to force the enabling of symlink munging on the server side.

A future version of openssh may have a change to the handling of forced commands that allows it to avoid using the user's home shell. so like. maybe later. not today. ๐Ÿคทโ€โ™€๏ธ


โœจ EXAMPLES โœจ

The ~/.ssh/authorized_keys file might have lines in it like this:

command="rrsync client/logs" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAzG...
command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmk...

look at that, read-only results, we love to see it. ๐Ÿ‘‘


โœจ FILES โœจ

  • ~/.ssh/authorized_keys

โœจ SEE ALSO โœจ

rsync(1), rsyncd.conf(5) โ€” go read those too, they're the whole ecosystem bestie ๐Ÿฆ‹


โœจ VERSION โœจ

This manpage is current for version 3.5.2 of rsync. โญ


โœจ CREDITS โœจ

rsync is distributed under the GNU General Public License. See the file COPYING for details.

An rsync web site is available at https://rsync.samba.org/ and its github project is https://github.com/RsyncProject/rsync. go star it, it's free. ๐Ÿ’–


โœจ AUTHOR โœจ

The original rrsync perl script was written by Joe Smith. Many people have later contributed to it. The python version was created by Wayne Davison. absolute legends, all of them. ๐Ÿ‘‘๐Ÿซถ


and that's the whole page bestie ๐Ÿ’…โœจ โ€” this was rrsync from rsync 3.5.2, dated 03 Nov 2026. go restrict some logins responsibly, mwah ๐ŸŽ€๐Ÿ’œ

๐Ÿ“ฆ where this page comes from