Using rsync+ssh on Debian
Reading Time: 4 min / Published: 12/4/2021 min /
When transferring files with rsync over ssh security is always a concern. Since the execution might not always be done on a controlled server, such as part of CD with shared runners, the keys are always in danger of being compromised. To prevent abuse, from the user that runs rsync, the
rrsync script is delivered with your rsync installation. The
rrsync script allows you, as an admin, to restrict the usage of rsync and in conjunction with ssh the overall ability of a user to execute commands.
This article describes a setup of rrsync on a machine running Debian Buster, the current stable release of Debian. But to use rsync to write to the server it also needs to be installed on the server itself.
To update your package list:
apt install update
To install rsync:
apt install rsync
To install ssh-server:
apt install ssh
After installing rsync you will want to ensure that port
873is open, since rsync needs this port for transferring files.
Now we can start by setting up ssh. This tutorial assumes you use sshd without password authentication and instead only pubkey. For the simplicity we will create a new, unprivileged user called
sudo useradd ssh-deploy. You can set a random password since it won't be needed for file transfer. To begin using rrsync, we need to actually get the rrsync script. It isn't part of the normal
PATH, and we need to manually copy it from the rrsync docs:
Creating Folder for rrsync:
sudo -u ssh-deploy mkdir /home/ssh-deploy/bin/
sudo cp -r /usr/share/doc/rsync/scripts/rrsync /home/ssh-deploy/bin/
Make rrsync executable:
sudo chmod +x /home/ssh-deploy/bin/rrsync
Change ownership of rrsync:
sudo chown -R ssh-deploy:ssh-deploy /home/ssh-deploy/bin/rrsync
Create a directory
ssh-deploy can transfer files to:
sudo -u ssh-deploy mkdir /home/ssh-deploy/share
You should now generate a new ssh key pair, on your machine, to use with this user. Save the secret key somewhere save and copy the public key for the next steps;
Create a new .ssh dir for
sudo mkdir -u ssh-deploy /home/ssh-deploy/.ssh
To now employ
rrsync create an
authorized_keys file with after the following template:
Everything is on a single line
command="$HOME/bin/rrsync /home/ssh-deploy/share",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding [your public key]
Let's take a look at what we are defining here:
commanddirective forces the command a user executes when authenticating with the appended public key. In this case we point to our previously fetched
rrsyncexecutable. Furthermore, we tell
rrsyncto only allow transfers to the previously created
You can add
$HOME/bin/rrsyncto restrict rsync to read-only mode
After the command you can add additional restrictions onto the user. In this case we limit all non-required function, such as getting a
pty, to prevent further execution.
The previous restrictions only apply to the appended public key. If you need this setup again, you can also register multiple public keys with individual restrictions in the same file, if you e.g., want to use the user across multiple projects with invidiual keys.
Now you can use rsync for this server:
rsync -e 'ssh -i /path/to/private/key -p SSH_PORT' [options] - src DEST_USER@DESTHOST:
There's no need to specify a path since rrsync automatically will map an empty path to your previously specified path.
Warning: Never forget to add
:at the end, or you will encounter errors
I hope this article helped you in setting up your own server with rrsync. This tutorial is based on my own experience when trying to set this up for one of my environments. Since I couldn't find an up-to-date version, I created my own, to help others who want to use rsync securely too.
There will be a follow-up article about integrating above strategy into GitLab CI soon.