我在 Ubuntu 16 中遇到了奇怪的行为scp
和选项。-T
scp
在一台装有该版本的 PC 上,1:7.2p2-4ubuntu2.8
我运行命令将文件从远程 PC scp 到本地 PC,并且文件已正确传输:
scp -o StrictHostKeyChecking=no -T [email protected]:/home/user/client01.conf /home/userX/ 2>&1
scp
但是,当我在另一台具有该版本的电脑上运行完全相同的命令时,1:7.2p2-4
出现此错误:
scp -o StrictHostKeyChecking=no -T [email protected]:/home/user/client01.conf /home/userX/ 2>&1
unknown option -- T
usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 ... [[user@]host2:]file2
我不知道其用途是什么,-T
因为两台电脑的scp
使用情况都显示相同:
usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 ... [[user@]host2:]file2
答案1
scp
在OpenSSH的足够新版本中,它的-T
作用如下:
-T
禁用严格文件名检查。默认情况下,将文件从远程主机复制到本地目录时scp
会检查收到的文件名是否与命令行上请求的文件名匹配,以防止远程端发送意外或不需要的文件。由于各种操作系统和 shell 对文件名通配符的解释方式不同,这些检查可能会导致所需文件被拒绝。此选项禁用这些检查,但代价是完全信任服务器不会发送意外的文件名。
一些见解:
当您scp
往返于远程位置时,您的本地scp
(客户端)会ssh
在后台运行以连接到远程位置并在那里运行特定命令。该命令以单个字符串的形式传递,并由远程用户的 shell 进行解释,就像通过 传递的任何命令一样ssh
。
如果scp
命令是… scp
;但是带有特殊选项。这些选项未记录(您不会在中找到它们man 1 scp
),它们会scp
变成服务器。
远程端需要使用 shell。通常,shell 可以解释通配符,而本地端scp
无法真正知道结果是什么。如果您知道自己在做什么,您可能会发现-T
使用通配符(如*
)很有用。
你的scp
7.2 版本似乎太旧了,不支持-T
,这个选项是在 8.0 版本中添加的。更重要的是,只有那时才添加了整个严格的文件名检查。
OpenSSH 8.0 于 2019-04-17 发布。
[…]
此版本包含针对工具和协议中的弱点
scp(1)
(CVE-2019-6111) 的缓解措施:将文件从远程系统复制到本地目录时,scp(1)
未验证服务器发送的文件名是否与客户端请求的文件名相匹配。这可能允许恶意服务器使用攻击者控制的内容创建或破坏意外的本地文件。此版本添加了客户端检查功能,确保从服务器发送的文件名与命令行请求匹配,
scp 协议已经过时、不灵活且不易修复。我们建议使用更现代的协议(如 sftp 和 rsync)进行文件传输。
[…]
scp(1)
:与上述更改相关scp(1)
;scp 协议依赖远程 shell 进行通配符扩展,因此没有万无一失的方法让客户端的通配符匹配完美地反映服务器的通配符匹配。如果客户端和服务器通配符扩展之间存在差异,客户端可能会拒绝来自服务器的文件。为此,我们提供了一个新-T
标志,scp
用于禁用这些客户端检查,但可能会再次引发上述攻击。
(来源)
scp
这意味着不支持的旧版s-T
默认行为与支持 的较新版本相同scp
。-T
因此,如果您真的想要-T
,那么缺乏对它的支持就不是问题。如果你想要scp
没有 的较新版本,即如果你想要严格的文件名检查(较旧的s-T
中未实现),那么这可能是一个问题。scp
你想要吗?好吧,检查一下(已经提到)CVE-2019-6111:
OpenSSH 7.9 中发现了一个问题。由于 scp 实现源自 1983 rcp,因此服务器会选择将哪些文件/目录发送到客户端。但是,scp 客户端仅对返回的对象名称进行粗略验证(仅防止目录遍历攻击)。恶意 scp 服务器(或中间人攻击者)可以覆盖 scp 客户端目标目录中的任意文件。如果
-r
执行递归操作 ( ),服务器也可以操作子目录(例如,覆盖文件.ssh/authorized_keys
)。
如果您的scp
文件足够新,它们会默认执行严格的文件名检查,以保护您免受恶意服务器的侵害。但如果您使用通配符,那么它们可能会拒绝您真正想要的文件。在这种情况下,如果你信任服务器,您可以使用-T
禁用严格文件名检查。结论是:使用 new 时,scp
您需要默认行为(否-T
),除非您知道您需要 -T
并接受风险。
对于旧版本scp
您没有选择(除了升级),因为首先没有严格的文件名检查。
请注意,您没有使用任何通配符来由远程 shell 扩展,因此如果您的scp
s 是新的,那么使用-T
只会降低安全性。在这种情况下使用的想法-T
可能会造成危害,并且不会带来任何好处。
旧版scp
s 缺乏严格的文件名检查,就像-T
新版 s一样scp
。只需使用旧版scp
s(-T
显然没有),您就可以实现您想要的鲁莽行为(-T
);但在我看来,您不应该想要这样。
我不知道为什么你们两个scp
s 中只有一个抱怨-T
。这没关系。如果您信任服务器,则使用scp
不带 的旧 s或较新的 s -T
;如果您不太信任服务器,则升级并使用scp
不带 的新 s -T
。
或者最好根本不要使用scp
。请注意(已经引用的)声明:
scp 协议已经过时、不灵活且不易修复。我们建议使用更现代的协议(如 sftp 和 rsync)进行文件传输。
我同意。在我看来,这scp
是一个快速而肮脏的黑客行为。这就是为什么你需要引用一些文件名两次:用于本地和远程 shell。如果你知道如何(或者更糟:如果你不知道)那么你甚至可以注入代码。例如这个命令:
scp 'router:nonexistent; beep' whatever
让我的路由器发出哔哔声!你只能注入你能够运行的代码ssh
,但是如果运行代码不是你的意图(我猜从来scp
都不是),而且你不知道如何引用,scp
那么你可能会运行一些你不想要的东西。