使用 scp 复制文件失败(debug1:退出状态 -1)

k4m*_*p3t 5 linux ssh scp openssh

我想将单个文件从远程服务器复制到本地计算机。

我在远程计算机上没有根权限,但我可以成功通过 SSH 连接到给定密码的用户。

然而,在实际复制任何内容之前,连接已关闭。

这是我尝试过的:

scp -P PORT user@SRC_HOST:/tmp/file /home/k4mp3t/

使用详细模式我得到以下输出:

debug1: Next authentication method: password
Authenticated to HOST.IP ([IP]:PORT) using "password".
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: filesystem
debug1: Sending subsystem: sftp
scp: Connection closed
debug1: client_input_channel_req: channel 0 rtype exit-signal reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
Transferred: sent 2896, received 3328 bytes, in 0.1 seconds
Bytes per second: sent 36199.5, received 41599.5
debug1: Exit status -1
Run Code Online (Sandbox Code Playgroud)

为什么 scp 连接关闭?

有关远程机器的信息:

ssh -V
OpenSSH_5.5p1 Debian-6+squeeze2, OpenSSL 0.9.8o 01 Jun 2010
Run Code Online (Sandbox Code Playgroud)

我的机器的信息:

ssh -V
OpenSSH_9.0p1, OpenSSL 1.1.1q  5 Jul 2022

OS: EndeavourOS Linux x86_64
Host: VirtualBox 1.2
Kernel: 5.18.14-arch1-1
Shell: bash 5.1.16
Run Code Online (Sandbox Code Playgroud)

我非常感谢任何可以帮助我解决这个问题的帮助或资源。

Kam*_*ski 10

太长了;博士

\n

尝试scp -O,例如:

\n
scp -O -P 1234 user@server:/tmp/file /home/k4mp3t/\n
Run Code Online (Sandbox Code Playgroud)\n
\n

分析

\n

输出的这个片段:

\n
\n
debug1: Sending subsystem: sftp\nscp: Connection closed\n
Run Code Online (Sandbox Code Playgroud)\n
\n

告诉我您本地scp尝试使用 SFTP 协议。传统scp使用SCP协议,这是不同的。你的scp做法并不传统。

\n
\n

历史、SCP 和 SFTP

\n

多年来scp(可执行文件)默认使用 SCP(协议),而不了解任何其他协议。我喜欢称 SCP 为“一个卡住的黑客”。要通过 SCP 与远程系统通信,本地系统scp会调用ssh并传递命令。该命令(与传递的任何命令一样ssh)由远程用户的 shell 解释。该命令尝试scp在远程端运行,使用未记录的选项man 1 scp将其转换scp为服务器。远程文件的名称嵌入在 shell 代码中。如果一切正常,则本地scp和远程scp最终将相互通信并传输数据。

\n

不幸的是,这是脆弱的;有些事情很容易破坏或滥用协议:

\n
    \n
  1. 如果需要引用或转义将在远程端使用的路径名,则需要分别为本地 shell 和远程 shell 引用或转义;即您需要两个级别的引用/转义。一方面,这允许您在远程端使用通配符,例如,本地引用*可能在远程端未被引用并在那里扩展。另一方面,如果您确实需要引用并且您不知道这些东西是如何工作的,那么您很容易编写错误的命令(示例)。

    \n
  2. \n
  3. 如果您知道如何操作,或者如果您不幸错误地执行了此操作(可能是由于错误的引用,请参见上文),您实际上可以在远程端运行任意代码。换句话说,您可以传递一个“远程路径名”,该路径名将由远程 shell 解释为 shell 代码(示例)。这并不是真正的安全漏洞,因为您ssh无论如何都可以通过运行相同的代码(毕竟这是您本地scp为您所做的事情)。问题在于无意中将某些内容作为代码运行的潜在能力。

    \n
  4. \n
  5. 服务器可能会向您提供您未请求的文件,并且您的本地服务器scp可能会接受它们(取决于您正在使用的实现和版本,请参阅此答案)。

    \n
  6. \n
  7. 如果远程“shell”确实不是一个 shell(或者它是一个与 POSIX shell 不兼容的 shell sh),那么即使是简单的、安全的命令也可能会失败。这可能包括您本地创建的任何命令scp

    \n
  8. \n
  9. 远程 shell 可能会在执行命令之前运行某些内容(示例)。如果这涉及打印到标准输出(即最终到本地scp)或从标准输入读取(即最终从本地scp),则本地scp将失败(示例)。

    \n
  10. \n
  11. 如果scp远程端未将其识别为命令,则不支持 SCP。scp如果远程端没有可执行文件或者$PATH远程用户的 shell 不包含远程scp.

    \n
  12. \n
\n

SFTP 是一个设计更好的协议。它当然解决了(1)和(2),我相信它解决了(3)。在服务器端,它可能使用通过远程用户的 shell 调用的单独可执行文件,因此 (4) 和 (5) 仍然是问题;不过,正确的配置可能会使其独立于用户$PATH,因此(6)得到解决。或者它可以使用Subsystem sftp internal-sftp(in sshd_config),然后 (4) 和 (5) 得到解决(甚至可以修复远程用户损坏的启动脚本)。

\n

SFTP 比 SCP 更好,但是sftp(可执行文件)并不总是比scp. sftp交互式地工作得很好,而 的语法scp类似于 的语法cp(您甚至可以scp a b喜欢cp a b;scp只是回退到cp本地复制,这对某些人来说是一个错误)。如果您想使用其中之一来简单地以非交互方式传输几个文件(例如在脚本中),那么您可能会使用看起来scp更简单的一种。

\n

现在您可以使用scpSFTP 而不是 SCP。OpenSSH 的现代scp默认使用 SFTP。从变更日志

\n
\n

OpenSSH 9.0 于 2022 年 4 月 8 日发布。[\xe2\x80\xa6]

\n

[\xe2\x80\xa6]

\n

默认情况下,此版本scp(1)从使用旧版 scp/rcp 协议\n切换为使用 SFTP 协议。

\n
\n
\n

回到你的案例

\n

scp显然是现代的,并且默认使用 SFTP。但相关服务器不支持相关子系统。通常禁用它就像注释掉该Subsystem sftp \xe2\x80\xa6一样简单。但我会期望subsystem request failed;你得到了connection closed,所以它可能不完全是这样。但由于某些原因,SFTP 无法与该服务器一起使用。

\n
\n

解决方案

\n

强迫你scp使用SCP。从man 1 scp

\n
\n

-O
\n使用旧版 SCP 协议而不是 SFTP 协议进行文件传输。对于未实现 SFTP 的服务器、为了向后兼容特定文件名通配符模式以及为了使用~较旧的 SFTP 服务器的前缀扩展路径,强制使用 SCP 协议可能是必要的。

\n
\n

该命令将类似于:

\n
scp -O \xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n

请记住,这将使用 SCP 及其所有怪癖。

\n
\n

兼容性注意事项

\n

即使你知道你想要SCP,一般情况下你也不能scp -O \xe2\x80\xa6盲目使用。对 SFTP 一无所知的实现或版本scp将无法识别-O,因此它们将会失败。我知道你scp可以使用-O;它尝试使用 SFTP,因此它必须支持-O. 但是,如果您尝试从旧系统与某些旧系统进行相同的传输,scp那么您将不得不省略-O.

\n

您最初的问题表明您需要知道服务器支持哪些协议。我的观点是,您需要了解您当地scp支持哪些协议和选项。

\n

要将文件传输到相关服务器或从相关服务器传输文件:

\n
    \n
  • scp没有的现代版本-O不起作用(因为服务器不支持SFTP),它应该可以使用-O;
  • \n
  • 但旧的scp不能使用-O(因为它无法识别该选项),它应该在没有-O;的情况下工作。
  • \n
  • 我遇到过默认scp使用(并提供强制 SFTP);无论是否使用明确的 ,这个都应该工作。-O-s-O-O
  • \n
\n

scp结论是:现在如果你想使用SCP,没有通用的语法。

\n