~/.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.