Secure rsync over SSH without shell access
Rsync is one of the best local and remote syncing programs. However, there is one problem with it: it's unsecure when used over internet:
- rsync protocol transfers data in plain text - meaning, it can be easily listened to by a middleman
- rsync credential exchange is encrypted using a weak RC4/ARC4/ARCFOUR cipher)
Traditionally, this has been worked around by running rsync over SSH, which provides proper and secure encryption. Unfortunately it leads us to additional problems:
- it requires giving shell access to the system
- you're no longer able to use the rsync server with its versatile configuration options (chroot, read-only, different modules with different paths etc.)
Is there a way to have the best of two systems, meaning:
- rsync runs as a proper daemon
- rsync is only accessible over encrypted channel, without having to access any exotic software
- no SSH shell access
Yes, there is - read on.
The following will start rsync as a daemon with "all" module having access to everything on the server (/), read only, listening on localhost only.
address = localhost [all] comment = the whole server path = / use chroot = yes read only = yes list = no uid = root gid = root auth users = backup secrets file = /etc/rsync/rsyncd-backup.secrets hosts allow = 127.0.0.1 log file = /var/log/rsyncd.log
Secrets file is a username:password pair, for example:
Make sure to chmod 600 /etc/rsync/rsyncd-backup.secrets - otherwise, rsync will refuse to use it.
SSH user with no shell access
- create a normal user first:
useradd -m -s /bin/bash backupuser
- add a key to user's .ssh/authorized_keys with the following content:
no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="/bin/nc localhost 873" ssh-rsa aaaabbbbb-user-key-goes-here-yyyzzzz root@server
Explanation of terms:
no-port-forwarding - don't allow port forwarding no-agent-forwarding - don't allow agent forwarding no-X11-forwarding - don't allow X11 forwarding command="/bin/nc localhost 873" - force netcat to localhost on port 873 as an executed command
This way, SSH user will have no access to the shell.
Connecting from remote
export RSYNC_USERNAME=user1 export RSYNC_PASSWORD=password1 export RSYNC_CONNECT_PROG="ssh -i /etc/snapbackup/keys/id_rsa backupuser@remoteserver -p 6253 nc localhost 873" rsync --exclude=/proc/ --exclude=/mnt/ --exclude=/tmp/ --exclude=/media/ --exclude=/sys/ --exclude=/swapfile --exclude=/var/lib/mysql/ --exclude=/run/ --delete --inplace --partial -z --compress-level=9 -a -H -v --stats user1@remoteserver::all /mnt/backup/remoteserver/latest/all