我正在尝试使用 rsync 下载文件,其中 rsync 以守护进程模式通过服务器上的 SSH 运行,并在客户端上收到以下错误:
rsync -a myserver:/remote/path/ localdestdir/
protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(176) [Receiver=3.1.1]
服务器在 .ssh/authorized_keys 中为用户提供了以下内容:
command="rsync --config=/path/to/engine-rsyncd.conf --server --daemon ." ssh-rsa ...
我已经阅读了所有我能找到的关于这个问题的信息,并且,正如大家建议的那样,检查了外壳是否干净,它是干净的:
ssh myserver false >out.tmp
创建一个零长度的文件 out.tmp(如果我从服务器上的 authorized_keys 中删除“command=...”)。
我也尝试在服务器上将用户的 shell 设置为 rssh 而不是 bash - 结果是一样的。
客户端和服务器都运行 Ubuntu 16.04,因此它们具有相同版本的 rsync(3.3.1,协议 31)。
还有什么原因呢?我尝试在 rsync 和 SSH 中启用详细日志记录,但日志没有给我任何线索。rsync 守护进程只记录了
2018/02/12 15:14:24 [6215] connect from clienthostname
答案1
在这种情况下,您的问题不是 shell 不干净,而是客户端 rsync 无法在服务器上执行它需要执行的命令。如果您command="rsync..."
在 authorized_keys 中使用,那么这就是 sshd 将执行的命令,无论客户端传递的命令是什么。
客户端 rsync 将使用以下参数调用 ssh:
ssh myserver rsync --server --sender -de.LsfxC . /remote/path/`。
请注意--sender
是这些选项的一部分,因为您希望服务器向您发送文件。如果服务器应接收文件,则不存在。还请注意 不--daemon
存在于 rsync 的选项中。由于 选项--config
仅与 一起使用--daemon
,因此也可以将其从命令条目中删除。
我已经提到过,命令将完全按照 authorized_keys 文件中的原样执行。这意味着从客户端传递的所有参数都将被忽略。所以如果你真的想在 authorized_keys 中使用命令,你必须指定 rsync 将提供给 ssh 客户端的确切选项,这意味着你只能使用 rsync 从 authorized_keys 中指定的路径接收文件。如果你在客户端上为 rsync 提供不同的选项,它们将不会在服务器上生效,因此可能会或可能不会起作用,这取决于这些选项的效果是在客户端还是在 rsync 的服务器端实现。所以你应该考虑你是否真的想要那个。
编辑 您可以使用脚本作为命令,并检查 SSH_ORIGINAL_COMMAND 环境变量以根据需要调用 rsync。由于远程路径是最后一个参数,您可能只想检查它是否以正确的前缀开头,并且不包含任何将转到父目录的“/..”