1

I'm trying to validate rsync via sshd's authorized_keys file.

The problem is I can't manage to execute rsync from the validating script.


Here's my authorized_keys file:

command="/home/username/Desktop/valrsync username" ssh-rsa AAAA [...]

Here's the valrsync script attempted differently each time:

Test 1 -

$SSH_ORIGINAL_COMMAND

Output -

$ rsync [...] / username@remotemachine:/
/home/username/Desktop/valrsync: line 2: rsync: command not found
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(601) [sender=3.0.7]

And, more importantly, Test 2 -

#!/usr/bin/python

import os
os.system(os.getenv('SSH_ORIGINAL_COMMAND'))

Output (running rsync from the local machine and getting the output of valrsync on the remote machine) -

$ rsync [...] / username@remotemachine:/
sh: rsync: command not found
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(601) [sender=3.0.7]

I understand that rsync somehow spawns an instance of itself at the remote machine, and obviously that instance is not referred when I attempt to execute the rsync command via the script. rsync is not installed on the server, and I know it shouldn't be.

Now the question is, what can I do about it (except maybe installing rsync on the server...?)

3 Answers 3

7

A better method than writing a homebrew script would be to use rrsync, which on Debian-based distros you should already have installed alongside rsync in /usr/share/doc/rsync/scripts/rrsync.gz. In that case simply run the following command to unpack the gzipped script into /usr/bin/rrsync:

gunzip /usr/share/doc/rsync/scripts/rrsync.gz -c|sudo tee /usr/bin/rrsync && sudo chmod +x /usr/bin/rrsync

(when already running as root you can obviously leave off the sudo invocations)

Alternatively download rrsync here.

Reminder: having rsync installed on the remote machine (the one with the authorized_keys file) is a prerequisite here.

Once that's done you can simply prepend a command= in front of a line with a public key, invoking rrsync.

Usually you would include some restrictive SSH options along with the command=, so it might look like this:

command="/usr/bin/rrsync -wo /data/backup/",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ecdsa-sha2-nistp521 AAAAE...

By giving that directory (you can use -ro for read-only and -wo for write-only) you can leave off the directory on the rsync invocation.

So your command line would become rsync [...] / username@remotemachine: (mind the missing path after the :).

1
  • 2
    On some operating systems, rrsync is located at /usr/local/bin/rrsync. If you aren't sure, just good ol' whereis rrsync.
    – Paul
    Apr 11, 2022 at 2:06
5

The error you're receiving is rsync: command not found. This typically implies that your $PATH environment variable is not set correctly. Using your first test, explicitly set PATH to include the directory where the rsync command is installed. For example:

#!/bin/sh

PATH=/usr/local/bin:$PATH
export PATH

$SSH_ORIGINAL_COMMAND

Make sure to make the scrip executable (chmod 755 valrsync).

All this assumes that rsync is in fact installed on the target system.

2
  • Thank you for your replay. Is the only way to solve this is to install rsync on the target machine?
    – Mark
    Jul 7, 2011 at 20:20
  • 2
    Yes, you need to have rsync installed on both the source and destination machine. Rsync needs to run on both ends of the connection (because otherwise, what is rsync talking to?).
    – larsks
    Jul 7, 2011 at 20:45
0

Ensure that you have rsync installed and in the PATH on both ends (client and server). The rsync client uses SSH to execute rsync on the remote (server) end. That's just how rsync works.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .