运行 `scp` 客户端 -> 服务器会导致找不到 scp 命令(在服务器上),为什么?

运行 `scp` 客户端 -> 服务器会导致找不到 scp 命令(在服务器上),为什么?

我们特意使用此开关构建 OpenSSH:--with-default-path空白。我们正在尝试部署 OpenSSH,以便服务器不包含scp二进制文件。

现在,当我们尝试scp从本地计算机(客户端)到远程计算机(服务器)时,我们会收到以下消息:

找不到 scp 命令

服务器似乎期望scp二进制文件存在于双方(客户端和服务器)上。那么为什么我们需要scp远程端的二进制文件呢?仅将其放在本地计算机(客户端)上还不够吗?有人可以澄清一下吗?

笔记:如果scp我们想要复制某些文件的远程服务器上不存在,它会在远程(服务器)上抛出如下错误:

找不到 scp 命令

答案1

scp我想你已经回答了你自己的问题:双方都需要。

的本地实例使用未记录的标志远程scp调用来处理文件传输协议。scp-t

如果您确实没有scp,但您有ssh服务器,则可以使用sftp它来传输文件,因为在许多情况下,SFTP 服务器组件内置于ssh服务器中。

答案2

总长DR

SSH 协议正在促进多个重叠的“服务”,其中文件复制就是其中之一。 SSH 协议执行此操作的方式是,当客户端使用命令行工具scp -t连接到服务器时,它会作为服务器上的子进程启动。scp

每台安装了 SSH 的服务器都需要完整的 CLI 工具来提供 SSH 的所有“服务”(sshscpsftp)。仅管理服务器守护程序需要磁盘上的该位置sshd。这意味着它们可以位于任何位置,客户端不知道也不需要知道,它们仅sshd作为客户端/服务器通过 TCP 端口(通常为 22)进行通信。


背景

诸如scprsync之类的应用程序ssh本身就是客户端/服务器应用程序。这意味着它们需要客户端应用程序scp和服务器应用程序。在这种情况下,scp两者都是。

这是一个例子

$ scp /Users/user1/thumbnails-digikam.db pi-hole:/tmp/.
thumbnails-digikam.db                                                                                                                                   0%    0     0.0KB/s   --:-- ETA^Z
[1]+  Stopped                 scp /Users/sammingolelli/thumbnails-digikam.db pi-hole:/tmp/.

我已经从我的笔记本电脑启动到我的 Raspberry Pi 服务器(pi-hole),然后通过+scp中途暂停它。CtrlZ

如果我然后ssh到 Raspberry Pi 服务器并执行以下操作ps

$ ps -eaf | grep [s]cp
pi        9688  6147  0 11:11 ?        00:00:00 scp -t /tmp/.

我们可以看到应用程序服务器scp正在运行,并将我们的文件写入/tmp目录。我们可以看到处于暂停状态的文件也正在被写入:

树莓派(服务器)
$ ls -l /tmp/thumbnails-digikam.db
-rw-r--r-- 1 pi pi 2260992 Jul  6 11:12 /tmp/thumbnails-digikam.db
笔记本电脑(客户端)
$ ls -l ~/thumbnails-digikam.db
-rw-r--r--  1 user1  staff  38551552 Jun  4 00:47 /Users/user1/thumbnails-digikam.db

如果我们scp通过在笔记本电脑(客户端)上取消暂停来继续:

$ fg
scp /Users/user1/thumbnails-digikam.db pi-hole:/tmp/.
thumbnails-digikam.db
$

它将完成,如果我们再次查看 Raspberry Pi(服务器),您会发现该scp应用程序不再运行:

$ ps -eaf|grep [s]cp
$

OpenSSH 有点独特,因为它仅在特定操作期间按需启动服务器应用程序(守护程序),然后一旦传输完成,它就会终止它们。

促进这一点的原始守护进程是ssh守护进程:

$ ps auxf | less
...
root      6132  0.0  0.6  11524  5812 ?        Ss   02:53   0:00  \_ sshd: pi [priv]
pi        6147  0.0  0.4  11812  4016 ?        S    02:53   0:03      \_ sshd: pi@pts/0
pi        6150  0.0  0.4   6172  4036 pts/0    Ss   02:53   0:00          \_ -bash
root      6172  0.0  0.3   7232  3336 pts/0    S    02:53   0:00          |   \_ sudo -Es
root      6176  0.0  0.4   6120  4180 pts/0    S    02:53   0:00          |       \_ /bin/bash
root      9772  0.0  0.3   7888  3076 pts/0    R+   11:20   0:00          |           \_ ps auxf
root      9773  0.0  0.0   3800   480 pts/0    S+   11:20   0:00          |           \_ less
pi        9745  0.2  0.1   3988  1872 ?        Ss   11:19   0:00          \_ scp -t /tmp/.
...

请注意 的父/子层次结构scp,它是 的子进程ssh

scp会话剖析

如果你看一下奥莱利 SSH 书籍有一个图表显示了scp连接如何工作的机制。

                SS1

在上图中,您可以看到当scp <file> <server>:/<path>执行命令时,它在客户端被转换为如下内容:

/usr/bin/ssh -x -oForwardAgent=no -oPermitLocalCommand=no -oClearAllForwardings=yes -- pi-hole scp -t /tmp/。

在本例中,客户端 ( scp) 指示sshd客户端上的守护进程向服务器发送请求,告诉它在远程端sshd启动。scp -t /tmp

根据文档,这是设计如何scp使用 SSH 隧道的。

         SS2

额外的见解

我做了一些实验,复制了二进制文件scpmyscp然后在客户端上运行。在每种情况下,该/usr/bin/ssh ...命令仍然显示-- someserver scp -t /tmp/..

这让我相信scp可执行文件的名称虽然在执行命令scp时由客户端引用ssh,但不会直接传递给客户端。相反,sshd守护进程具有它支持的各种客户端工具的名称,并在其中进行硬编码。

上图所示的详细信息进一步证实了这一点。

结论

--with-default-path编译时不可能完全删除/禁用 的定义sshd。完全删除它会破坏sshd查找连接scp -t <dir>何时scp被触发的能力。

最好的隔离方法sshd是指定一个目录,其中仅包含构成 OpenSSH 的各种二进制文件。

参考

答案3

很明显,您必须在两个实例中都有协议才能使用它。如果您想要替代方案,可以使用 ssh,如下所示。

ssh user@ip "cat > destination" < file.txt

相关内容