rsync logs with restricted ssh

Posted by – 15/04/2009

SSH is really the Swiss Army pocket knife of sysadmin tools. When I needed to periodically synchronize log files from an old server (old as in customer-would-never-update-it-or-install-anything-new), I built a simple and secure solution using rsync and ssh. This is what I did:

(I will call “remote” the system where the logs I want to retrieve are, and “local” system where I want them to be copied to) First I created an account with a restricted shell (ideally this should be a system account, but we’ll get there!):

remote# adduser --ingroup nogroup --shell /bin/rbash rlogs

Then locally, I created a new, password-less ssh key pair, copying it to my remote system:

local$ ssh-keygen
>>> When asked where to save it, I chose a different name, like .ssh/rlogs
local$ ssh-copy-id -i .ssh/rlogs.pub rlogs@remote
...
>>> You can delete the password of user rlogs, so it, effectively,
>>> cannot log-in with it (almost like a system user).
remote# passwd -d rlogs

Now you should be able to run password-less rsync already (note that I use -e option to point to a different key):

local$ mkdir logs
local$ rsync -av -e "ssh -i $HOME/.ssh/rlogs" rlogs@remote:"logs/" logs/
receiving file list ... done
./
file1
file2
...
fileN

But even with a restricted shell, I wanted even less possible things to happen. That’s what command= directive is for… It will only allow that command to be run in a session started by that key. Since rsync translates a lot of its command-line options, I run it again with a dirty ps-in-a-loop in the remote host, just to see what running rsync locally causes remotely:

remote$ while 1; do ps wp $(pgrep rsync); sleep 1; done
...
local$ rsync -av -e "ssh -i $HOME/.ssh/rlogs" rlogs@remote:"logs/" logs/
>>> in the remote loop you should be able to get the command:
  PID TTY      STAT   TIME COMMAND
 6183 ?        Ss     0:00 /usr/bin/rsync --server --sender -vlogDtpre.i . logs/

Here comes the authorized_keys magic. At the remote host I edited .ssh/authorized_keys to add a command= line with what I found out in my dirty loop. Also, I added a couple of directives to restrict it even further (they are pretty self-explanatory):

rlogs@remote$ cat .ssh/authorized_keys
command="rsync --server --sender -vlogDtpre.i . logs/",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-rsa (...) myuser@local

Now everything is set. I just added the rsync command to the local crontab and it’s done.

5 Comments on rsync logs with restricted ssh

  1. spectra says:

    @Guy, @Marius,

    Well… Debian default is, also, nullok_secure (which seems to be a Debian/Ubuntu specific patch). Using passwd -d is still safe, since nullok_secure will allow passwordless logins from terminals listed under /etc/securetty.

  2. Guy Illesca says:

    actually, i believe he meant passwd -d really. this will make the password for the user empty and the standard behaviour (at least in Debian) is to not allow passwordless accounts to login. this is a pam feature. passwordless accounts will just be able to login if the auth module receives the nullok option (more info here: http://www.kernel.org/pub/linux/libs/pam/Linux-PAM-html/sag-pam_unix.html#sag-pam_unix-options

    )

  3. As a data point, Ubuntu’s default PAM config allows passwordless logins (nullok_secure
    in /etc/pam.d/common-auth), so passwd -l is a safer choice.

    You can use SSH keys to log into accounts locked with passwd -l, in case you were wondering.

  4. Tommi Vainikainen says:

    passwd -d makes password empty (still allowing login with empty password), I guess passwd -l is what you meant.

Leave a Reply

Your email address will not be published. Required fields are marked *