Ssh – Is it possible to use rsync over sftp (without an ssh shell)

rsyncsftpssh

Rsync over ssh, works great every time.

However, trying to rsync to a host which allows only sftp logins, but not ssh logins, provides the following error:

rsync -av /source ssh user@remotehost:/target/

protocol version mismatch — is your
shell clean? (see the rsync man page
for an explanation) rsync error:
protocol incompatibility (code 2) at
compat.c(171) [sender=3.0.6]

Here's the relevant section from the rsync man page:

This message is usually caused by your startup scripts or
remote shell facility producing
unwanted garbage on the stream that
rsync is using for
its transport. The way to diagnose this problem is to run your
remote shell like this:

          ssh remotehost /bin/true > out.dat

then look at out.dat. If everything is working correctly then
out.dat should be a zero length file.
If you are getting the above error
from rsync
then you will probably find that out.dat contains some text or
data. Look at the contents and try to
work out what is producing it. The
most com‐
mon cause is incorrectly configured shell startup scripts (such
as .cshrc or .profile) that contain
output statements for non-interactive
logins.

Trying this on my system produced the following in out.dat:

ssh-dummy-shell: Command not allowed.

As I thought, the host is not allowing ssh logins.

The following link shows that it is possible to accomplish this task using fuse with sshfs – however it is extremely slow, and not fit for production use.

Is there any chance of getting rsync sftp to work?

Best Answer

Unfortunately not directly. rsync requires a clean link with a shell that will allow it to start the remote copy of rsync, when run this way.

If you have some way of running long-lived listening processes on the host you could try starting rsync manually listening for connections on a non-privileged port, but most techniques for doing that would require proper shell access via SSH too, and it relies on the hosts firewall arrangements letting connections in on the port you chose (and the host having rsync installed in the first place). Running rsync as a publicly addressable service (rather than indirectly via SSH or similar) is not generally recommended for non-public data though.

If you host allows scripting in PHP or similar and does not have it locked down so extra processes can not be execed by user scripts, then you could try starting rsync in listening mode that way. If your end is connectible (you are running SSH accessible to the outside world) you could try this in reverse - have a script run rsync on the server but instead of listening for incoming connections have it contact your local service and sync that way. This still relies on rsync actually being installed on the host which is not a given, or that you can upload a working copy, but does not have the security implications of running an rsync daemon in a publicly addressable fashion and talking to it over an unencrypted channel.

Messing around as described above may be against the hosts policies though, even if it works at all, and could get you kicked off. You are better off asking if a full shell can be enabled for that account and either abandoning rsync for that host or abandoning that host and moving elsewhere if they will not do that.