retro spiller

technokracy

Root, Sudo, and Rsnapshot

Changelog

  • 2013-06-18 Adding change rbackup user’s login shell section.
  • 2013-06-14 A few steps updated, thanks in part to contributors. Notably, the rbackup user doesn’t necessarily need to be created on the backup server (uno) as described originally.
  • 2011-01-07 Initial post.

Introduction

The Mission:

To rsync and/or rsnapshot both normal and protected/restricted files from one server to another over ssh without enabling remote root access to either server while maintaining original file attributes and permissions. Whew.

Cast of Characters

  • uno: the server which will store the backups, run rsync or rsnapshot.
  • zero: the server to be backed up, with root readable files (/etc for example).

Prerequisites

  • root on both uno and zero, hopefully via sudo and not by remote root ssh access!

Configuration

The command examples here are specific to Debian and Ubuntu, so adjust to your distribution accordingly (though little if any adjustment should be necessary).

Server: uno (backup server)

Become root, create an ssh key pair:

1
root# ssh-keygen -t rsa

When naming the key, don’t accept the default. Instead, enter

1
/root/.ssh/id-rbackup_rsa

We’re naming the key pair with ‘rbackup’ in it to keep track of what the keys are for.

As root, create a ssh config file:

1
root# vim .ssh/config

In root’s .ssh/config file:

1
2
3
4
5
Host zero-rsync
  Port 456 # only required if zero is running sshd on a non-standard port
  Hostname zero
  User rbackup
  IdentityFile /root/.ssh/id-rbackup_rsa

Save the file, set permissions:

1
root# chmod 600 config

While still root, copy the public key id-rbackup_rsa.pub somewhere publicly accessible, such as your regular user’s home directory.

As your regular user (which already has ssh access to zero), send this public key from uno to zero:

1
$ scp ~/id-rbackup_rsa.pub zero:~/

Server: zero (server to be backed up)

Create new backup user, lets call it rbackup:

1
$ sudo adduser rbackup

Make uno’s public key id-rbackup_rsa.pub available to user rbackup.

Login as rbackup, create a .ssh directory, set permissions, create an authorized_keys file:

1
2
3
4
5
6
7
$ su rbackup
$ cd
$ mkdir .ssh
$ chmod 700 .ssh
$ cd .ssh
$ cat /home/regularuser/id-rbackup_rsa.pub > authorized_keys
$ chmod 600 authorized_keys

Now we want to limit the use of this authorized key by allowing connections only from uno, and allowing one command only. Edit the key, and add something like this to the beginning of the key:

1
2
from="192.168.100.123",command="/home/rbackup/validate_rsync.sh" ssh-rsa AX
...remainder of key...rbackup@uno

While still user rbackup, create a script named validate_rsync.sh in your home directory:

1
2
$ cd
$ vim validate_rsync.sh

Contents of validate_rsync.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/sh
case "$SSH_ORIGINAL_COMMAND" in
  *\&*)
    echo "Connection closed"
    ;;
  *\;*)
    echo "Connection closed"
    ;;
    rsync*)
    $SSH_ORIGINAL_COMMAND
    ;;
  *true*)
    echo $SSH_ORIGINAL_COMMAND
    ;;
  *)
    echo "Connection closed."
    ;;
esac

Make sure that validate_rsync.sh is executable by user (and group) rbackup:

1
$ chmod 754 validate_rsync.sh

As your regular user (which can sudo):

1
$ sudo visudo

Add this line to the bottom:

1
rbackup    ALL=NOPASSWD:/usr/bin/rsync

For a little added security, set the rbackup user’s login shell to the validate_rsync.sh script:

1
$ sudo chsh rbackup

When prompted to choose the login shell, enter /home/rbackup/validate_rsync.sh.

If you have the AllowUsers directive set for sshd in /etc/ssh/sshd_config, make sure to add the user rbackup to the list, and restart sshd.

As root or with sudo, create a simple rsync wrapper, named rsync_wrapper.sh at /usr/local/bin, containing:

1
2
#!/bin/sh
/usr/bin/sudo /usr/bin/rsync "$@";

Testing

Test 1

Become user rbackup on uno, attempt ssh to zero:

1
$ ssh zero

Expected response:

1
2
Connection closed.
Connection to zero closed.

The “Connection closed.” with the period at the end tells us the validate_rsync.sh worked as expected (echoing the last Connection closed).

Test 2

Become root on uno, attempt to ssh to zero-rsync (the alias set in root’s .ssh/config):

1
root# ssh zero-rsync

Expected response:

1
2
Connection closed.
Connection to zero closed.

Test 3

Become root on uno, attempt to rsync something on zero that is restricted:

1
2
root# rsync -ae ssh --rsync-path='rsync_wrapper.sh' zero-rsync:/etc
/home/regularuser/tmp/

Expected response: you should have a copy of zero’s /etc directory in regular users tmp directory (or wherever). Important things to note in the above command - the –rsync-path switch and using zero-rsync as the host instead of just zero.

Using rsnapshot

If the above tests all work, setting up rsnapshot is easy. Check any other guide for general setup info, the relevant stuff for us to use in our rsnapshot.conf is:

1
2
rsync_long_args --rsync-path=rsync_wrapper.sh --delete --numeric-ids --relative --delete-excluded
backup rbackup@zero-rsync:/etc zero/

Remember the rsnapshot.conf file needs tabs. The rsync_long_args setting is rsnapshot’s default rsync arguments, with our --rsync-path=rsync_wrapper.sh added. The backup command has our backup user (rbackup) and the host alias set in root@uno’s .ssh/config.

References

This was pieced together from various notes, blogs, and articles. Some script source and extra-helpful information was found at: