mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-11-05 19:43:25 -05:00
--ignore-existing protects the live transfer destination, but three
peer-selectable options reach other existing objects inside the
restricted directory: --log-file appends to one, --partial-dir consumes
and then renames or unlinks one, and --delay-updates does the same
through its implicit .~tmp~ directory. Refuse all three under
-no-overwrite.
Refusal rather than confinement, because confining these paths does not
help: keeping the --log-file append inside the tree still appends to an
existing file, and for the partial directories the peer controls both
the directory and the transferred basename, so a collision is always
reachable. A pre-exec emptiness check would be raceable. The cost is
that a push naming --partial-dir on the remote receiver, or using
--delay-updates, is now refused for a -no-overwrite account.
Each regression drives the option through a wrapper WITHOUT
-no-overwrite as well, and requires that to be accepted. Without that
control the tests cannot tell "refused under -no-overwrite" from
"refused always", and would still pass if the options were disabled for
every rrsync deployment -- verified by making the refusal unconditional,
which the controls then catch.
The wrapper is handed a shim rather than RSYNC directly: RSYNC is a
multi-word command whenever the runner forces --protocol=N, and rrsync
execlp()s its RSYNC as a single executable name, so every one of these
tests died before reaching the policy under test. A fleet run caught it
on the protocol columns of three targets.
Backup mode belongs in the same set. Publishing a backup onto a name
that already exists deletes what is there (backup.c make_backup()), and
deleting a file backs it up first (delete.c), so a --delete of an
unrelated file can land on a protected name -- overwriting a file that
--ignore-existing was holding, with rc=0 and no diagnostic. Disable -b
and --backup-dir. --suffix is left enabled: with both of those refused
nothing can turn backups on, so it is inert.
The short option must be disabled before short_no_arg_re is built, since
a stock client sends b inside the remote short-option bundle and the
regex is snapshotted there; the whole -no-overwrite block therefore
moves up beside the other policy gates rather than sitting after the
chdir. Its regression drives the collision through a wrapper without
-no-overwrite, passing --ignore-existing by hand, which both proves the
refusal is conditional and shows the primitive defeating the very
protection -no-overwrite forces.
rrsync.1.md now states what -no-overwrite costs: no explicit
--partial-dir, no --delay-updates, no server-side --log-file, no backups.
(cherry picked from commit c3abc6c095)
180 lines
6.1 KiB
Markdown
180 lines
6.1 KiB
Markdown
## NAME
|
|
|
|
rrsync - a script to setup restricted rsync users via ssh logins
|
|
|
|
## SYNOPSIS
|
|
|
|
```
|
|
rrsync [-ro|-wo] [-munge] [-no-del] [-no-lock] [-no-overwrite] DIR
|
|
```
|
|
|
|
The single non-option argument specifies the restricted _DIR_ to use. It can be
|
|
relative to the user's home directory or an absolute path.
|
|
|
|
The online version of this manpage (that includes cross-linking of topics)
|
|
is available at <https://download.samba.org/pub/rsync/rrsync.1>.
|
|
|
|
## DESCRIPTION
|
|
|
|
A user's ssh login can be restricted to only allow the running of an rsync
|
|
transfer in one of two easy ways:
|
|
|
|
* forcing the running of the rrsync script
|
|
* forcing the running of an rsync daemon-over-ssh command.
|
|
|
|
Both of these setups use a feature of ssh that allows a command to be forced to
|
|
run instead of an interactive shell. However, if the user's home shell is bash,
|
|
please see [BASH SECURITY ISSUE](#) for a potential issue.
|
|
|
|
To use the rrsync script, edit the user's `~/.ssh/authorized_keys` file and add
|
|
a prefix like one of the following (followed by a space) in front of each
|
|
ssh-key line that should be restricted:
|
|
|
|
> ```
|
|
> command="rrsync DIR"
|
|
> command="rrsync -ro DIR"
|
|
> command="rrsync -munge -no-del DIR"
|
|
> ```
|
|
|
|
Then, ensure that the rrsync script has your desired option restrictions. You
|
|
may want to copy the script to a local bin dir with a unique name if you want
|
|
to have multiple configurations. One or more rrsync options can be specified
|
|
prior to the _DIR_ if you want to further restrict the transfer.
|
|
|
|
To use an rsync daemon setup, edit the user's `~/.ssh/authorized_keys` file and
|
|
add a prefix like one of the following (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, ensure that the rsyncd.conf file is created with one or more module names
|
|
with the appropriate path and option restrictions. If rsync's
|
|
[`--config`](rsync.1#dopt) option is omitted, it defaults to `~/rsyncd.conf`.
|
|
See the [**rsyncd.conf**(5)](rsyncd.conf.5) manpage for details of how to
|
|
configure an rsync daemon.
|
|
|
|
When 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.
|
|
|
|
The remainder of this manpage is dedicated to using the rrsync script.
|
|
|
|
## OPTIONS
|
|
|
|
0. `-ro`
|
|
|
|
Allow only reading from the DIR. Implies [`-no-del`](#opt) and
|
|
[`-no-lock`](#opt).
|
|
|
|
0. `-wo`
|
|
|
|
Allow only writing to the DIR.
|
|
|
|
0. `-munge`
|
|
|
|
Enable rsync's [`--munge-links`](rsync.1#opt) on the server side.
|
|
|
|
0. `-no-del`
|
|
|
|
Disable rsync's `--delete*` and `--remove*` options.
|
|
|
|
0. `-no-lock`
|
|
|
|
Avoid the single-run (per-user) lock check. Useful with [`-munge`](#opt).
|
|
|
|
0. `-no-overwrite`
|
|
|
|
Enforce `--ignore-existing` on the server. Prevents overwriting existing
|
|
files when the server is the receiver.
|
|
|
|
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`, 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`, and server-side logging are therefore
|
|
unavailable under this option.
|
|
|
|
0. `-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.
|
|
|
|
The rrsync script rejects rsync's [`--copy-links`](rsync.1#opt) option (by
|
|
default) so that a copy cannot dereference a symlink within the DIR to get to a
|
|
file outside the DIR.
|
|
|
|
The rrsync script rejects rsync's [`--protect-args`](rsync.1#opt) (`-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 script (or a copy of it) can be manually edited if you want it to customize
|
|
the option handling.
|
|
|
|
## BASH SECURITY ISSUE
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
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.
|
|
|
|
## 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...
|
|
> ```
|
|
|
|
## FILES
|
|
|
|
~/.ssh/authorized_keys
|
|
|
|
## SEE ALSO
|
|
|
|
[**rsync**(1)](rsync.1), [**rsyncd.conf**(5)](rsyncd.conf.5)
|
|
|
|
## VERSION
|
|
|
|
This manpage is current for version @VERSION@ of rsync.
|
|
|
|
## CREDITS
|
|
|
|
rsync is distributed under the GNU General Public License. See the file
|
|
[COPYING](COPYING) for details.
|
|
|
|
An rsync web site is available at <https://rsync.samba.org/> and its github
|
|
project is <https://github.com/RsyncProject/rsync>.
|
|
|
|
## 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.
|