Using ~/.ssh/authorized keys to decide what the incoming connection can do

~/.ssh/authorized_keys allows you to specify the command run by the incoming ssh connection.

I was searching for a previous blog post to give you some background. I failed.

I backup my Bacula database and my Bacula configuration via rsync. These backups go to more than one host.

The following are lines from ~rsyncer/.ssh/authorized-keys on my dbclone host – which gathers database backups from various hosts.

from="x8dtu.example.org,10.1.1.1",command="/usr/local/sbin/rrsync -ro /usr/home/rsyncer/backups/bacula-database/postgresql/" ssh-ed25519
AAAAC3thisisalsonotmyrealpublickeybcxpFeUMAC2LOitdpRb9l0RoW7vt5hnzwt rsyncer@x8dtu.example.org

The above appears on two lines to make it easier to read without horizontal scrolling – in the file, it’s all on one line.

This says:

* when an ssh connection comes in from a client at x8dtu.example.org, or 10.1.1.1
* run /usr/local/sbin/rrsync -ro /usr/home/rsyncer/backups/bacula-database/postgresql/
* and that client must have this key (as shown)
* rsyncer@x8dtu.example.org is a comment, and has no effect

What does /usr/local/sbin/rrsync -ro /usr/home/rsyncer/backups/bacula-database/postgresql/ do?

See man rrsync, a program supplied with rsync. In short it is “script to setup restricted rsync users via ssh logins”.

It means the incoming client can only rsync from the specified path /usr/home/rsyncer/backups/bacula-database/postgresql/ and that the session is ro (read-only).

This is a great feature. Given that these passphraseless ssh-keys allow access to a rather important system (it has all the database backups), imposing such restrictions seems a good idea.

This works well for transferring the Bacula database back from dbclone over to x8dtu.

Now, what if I want to copy a different database backup in the other direction, from x8dtu to dbclone?

I have previously decided that dbclone is a pull-only host. That is nobody can push data to it. My solution: the command specified in ~/.ssh/authorized keys initiates an rsync on dbclone, pulling data from x8dtu.

That script looks something like this.

[rsyncer@dbclone ~]$ cat /home/rsyncer/bin/rsync-backup-from-x8dtu.sh
#!/bin/sh
#
# This file does a backup of each database on the server.
# It relies upon a file on the server to do the actual backup,
# then uses rsync to copy the files from the server to here.
#

# the ~/.ssh/authorized keys entry on the server must look like this:
#
# from="10.55.0.140",command="/usr/local/sbin/rrsync /usr/home/backups/" [ssh key goes here]
#
# invoking rrsync ensures the incoming rsync process is chrooted to /usr/home/dan/backups/
# Thus, BACKUPDIR is relative to that location.

BACKUPDIR=${HOME}/backups/x8dtu-pg01/database-backup

IDENTITY_FILE_RSYNC=${HOME}/.ssh/id_ed25519
SERVER_TO_RSYNC=x8dtu.example.org

cd ${BACKUPDIR}

#
# use rsync to get local copies
#
/usr/local/bin/rsync -e "/usr/bin/ssh -i ${IDENTITY_FILE_RSYNC}" --recursive -av --stats --progress --exclude 'archive' ${SERVER_TO_RSYNC}:/ ${BACKUPDIR}

Great. Now all I need to do is add another entry into authorized_keys on dbclone, resulting in something like this:

from="x8dtu.example.org,10.1.1.1",command="/usr/local/sbin/rrsync -ro /usr/home/rsyncer/backups/bacula-database/postgresql/" ssh-ed25519
AAAAC3thisisalsonotmyrealpublickeybcxpFeUMAC2LOitdpRb9l0RoW7vt5hnzwt rsyncer@x8dtu.example.org

from="x8dtu.startpoint.vpn.unixathome.org,10.8.1.100",command="/home/rsyncer/bin/rsync-backup-from-x8dtu.sh" ssh-ed25519 AAAAC3thisisalsonotmyrealpublickeybcxpFeUMAC2LOitdpRb9l0RoW7vt5hnzwt rsyncer@x8dtu.example.org

Here’s the problem. Both lines can’t run. Only one will run. The incoming ssh key will match, and that command will be run. Instead. I added a second ssh key:

[rsyncer@x8dtu ~/.ssh]$ ssh-keygen -t ed25519 -f id_ed25519.rsync.bacula
...

I modified the above script to use that key:

IDENTITY_FILE_RSYNC=${HOME}/.ssh/id_ed25519.rsync.bacula

Next, I modified authorized_keys on dbclone to refer to the new public key (again, I’ve added newlines in here so you don’t have to scroll):

from="x8dtu.example.org,10.1.1.1",command="/usr/local/sbin/rrsync -ro /usr/home/rsyncer/backups/bacula-database/postgresql/" ssh-ed25519
AAAAC3thisisalsonotmyrealpublickeybcxpFeUMAC2LOitdpRb9l0RoW7vt5hnzwt rsyncer@x8dtu.example.org

from="x8dtu.startpoint.vpn.unixathome.org,10.8.1.100",command="/home/rsyncer/bin/rsync-backup-from-x8dtu.sh" ssh-ed25519 
AAAAC3thisisthesecondsshkeypKBYib6rCHZ+zK5Q3LvJFukdFzT+Q92GUtej6SLW8 rsyncer@x8dtu.example.org

This works. It means that for each task to be carried out, I need a different ssh key. However, so far, there are just two tasks.

Hope this helps.

Website Pin Facebook Twitter Myspace Friendfeed Technorati del.icio.us Digg Google StumbleUpon Premium Responsive

Leave a Comment

Scroll to Top