scp:错误:意外的文件名:

Eli*_*ock 23 bash scp

我使用了很长时间来上传文件的 SCP 突然停止工作。我在 12 小时前运行了脚本,它运行得很好,但突然停止了。

有问题的命令是将当前目录上传到远程文件夹:

#!/bin/bash
cd "$(dirname "$0")"

scp -r . <remote_server>:<remote_folder>
Run Code Online (Sandbox Code Playgroud)

错误信息是:

scp: error: unexpected filename: .
Run Code Online (Sandbox Code Playgroud)

我在运行 Mojave 10.14.2 的 Mac 上。

更新:我已经通过将命令重写为此解决了特定问题,但我仍然有兴趣知道发生了什么:

scp -r $(pwd) <remote_server>:<remote_folder>
Run Code Online (Sandbox Code Playgroud)

Bla*_*ear 22

罪魁祸首是CVE-2018-20685,其描述为:

在 OpenSSH 7.9 中,scp 客户端中的 scp.c 允许远程 SSH 服务器通过 . 或空文件名。影响是在客户端修改目标目录的权限。

这是更大的一组 SCP 漏洞的一部分。从那里引用:

概述

来自多个供应商的 SCP 客户端容易受到恶意 scp 服务器对目标目录和/或客户端输出操作执行未经授权的更改的影响。

描述

许多 scp 客户端无法验证 scp 服务器返回的对象是否与其请求的对象匹配。这个问题可以追溯到 1983 年和 scp 所基于的 rcp。客户端中的一个单独缺陷允许任意更改目标目录属性。最后,客户端中的两个漏洞可能允许服务器欺骗客户端输出。

在 OpenBSD 中修补此漏洞的提交是在 2018 年 11 月 16 日进行的

  • 使 scp 工具无法处理标准目录条目“.” 是一个可怕的解决方案!他们必须有 10 种其他方法可以解决这个问题(也许通过验证返回的对象是所要求的对象?)......这是“花费最少的努力来确保安全”,这是“安全性不发布主机名”... (4认同)
  • 很好的答案,现在我知道为什么我在 Ubuntu 上的 scp 脚本不再工作了。但解决办法是什么?我不能使用“*”代替“.”,因为该文件夹包含数千个文件。是否有新的开关可以关闭此行为? (3认同)
  • @Stéphane 使用 `$(pwd)` 而不是 `.` (3认同)
  • @BlackBear 不一样。`.` 允许复制所有文件(包括以点开头的文件)而不复制目录本身。`scp -r $(pwd) &lt;host&gt;:&lt;dest. dir&gt;` 和 `scp -r 。&lt;主机&gt;:&lt;目标。dir&gt;` 是不同的。在第一种情况下,你有 `&lt;dest. dir&gt;/&lt;current dir name&gt;/&lt;files list&gt;` 当你有 `&lt;dest. dir&gt;/&lt;files list&gt;` 第二种情况。 (3认同)
  • 感谢您的解释。所以我的 SCP 以某种方式在夜间更新以包含此补丁,这就是它停止工作的原因? (2认同)

Sté*_*ane 12

@BlackBear 的另一个答案解释了为什么这不再有效。

但是,如果像我一样,您最终也在这个问题上寻找解决方案,那么正确的方法似乎是使用rsync而不是scp. 例如,我的一个旧scp命令看起来像这样:

# this no longer works due to the "."
scp -BCr output/html/. www:/var/www/site/html/
Run Code Online (Sandbox Code Playgroud)

现在我用这个:

rsync --recursive --times --compress --delete --progress output/html/ www:/var/www/site/html/
Run Code Online (Sandbox Code Playgroud)

如果你喜欢较短的标志,它看起来像这样:

rsync -rtz --del --progress output/html/ www:/var/www/site/html/
Run Code Online (Sandbox Code Playgroud)

/源头的尾随很重要。它告诉 rsync 您想要没有目录名称的目录的内容

也可以考虑--dry-runman rsync搞乱事情之前。

  • @JanD 当您尝试上传不是当前工作目录的目录时,使用 $(pwd) 不起作用,这就是我提供答案的原因。看看我的回答中的第一个例子,这是从使用“。scp 不再支持的符号。 (2认同)