scp 不安全吗?应该换成sftp吗?

Fab*_*adi 59 security scp sftp

我在 Un*x 中有 20 多年的经验,而且我一直在使用它scpscp通过 SSH,因此我认为它与后者一样安全。现在,在我最近开始工作的公司中,安全官说scp不应使用它,因为它不安全且已过时。sftp应该比它更受青睐(但也比 SSH 更......)

基于 scp 下的基础设施,以及scp在专业社区以及我前公司的其他同事中的受欢迎程度和信任度,我并不立即同意这一点。我不想仅仅因为某些 CSO 这么说就改变主意。

  • 这就是说,这里有主题吗?
  • scp突然的害群之马?
  • 仅仅是在更高领域的安全专家辩论吗?
  • 还是scp只是好用?

JoL*_*JoL 36

这有点“不安全”

轻微的“不安全”,然后加入scp -T在OpenSSH的8.0,它仍然轻微的“不安全”当使用scp -r

就像其他答案所说的那样,声称 scp 不安全来自客户端之前无法验证它是否正在接收它所请求的内容。scp 无法验证的原因是因为请求是使用在服务器环境中运行的 shell 代码(具有服务器状态)发出的。

例如,假设服务器的 shell 设置为带有扩展 glob 的 zsh,并且我将我的项目目录设置为 zsh 动态命名目录以便快速访问。如果我想从 Rails 项目foo获取文件,我可以通过以下方式获取:

scp server:~foo/config/database.yml .
Run Code Online (Sandbox Code Playgroud)

我服务器上的 zsh 扩展~foo~/work-for/client/$client_name/foo.

如果我想获取服务器的 10 个最新的常规文件,我可以这样做:

scp server:'*(.oc[1,10])' .
Run Code Online (Sandbox Code Playgroud)

如果服务器有普通的 bash,我可以这样做:

scp server:'$(ls -t | head -10)' .
Run Code Online (Sandbox Code Playgroud)

如果我想获取在其内容中包含模式 foo 的文件,我可以这样做:

scp server:'$(grep -l foo *)' .
Run Code Online (Sandbox Code Playgroud)

scp 客户端无法验证这些使用 shell 代码的请求。但是,令人担忧的是它使恶意服务器能够响应:

scp -r server:foo/ ~
Run Code Online (Sandbox Code Playgroud)

与覆盖.ssh/authorized_keys。在 眼中scpfoo/是服务器 shell 代码,它将评估谁知道什么。

输入scp -T

-T禁用严格的文件名检查。默认情况下,将文件从远程主机复制到本地目录时,scp 会检查接收到的文件名是否与命令行上请求的文件名匹配,以防止远程端发送意外或不需要的文件。由于各种操作系统和 shell 解释文件名通配符的方式不同,这些检查可能会导致所需文件被拒绝。此选项以完全信任服务器不会发送意外文件名为代价禁用这些检查。

总而言之,之前的默认行为scp已移至-T,现在默认是检查接收到的内容,使用提供的参数作为简单模式,当不进行递归复制时。我相信它可以识别简单的 globs 和转义符(查看源代码,它使用fnmatch(3)进行匹配,标志设置为 0)。换句话说,当您不希望利用其通过 shell 代码指定文件的独特能力时,它的行为更可预测。

所以现在,如果你不使用-T也不使用-r,覆盖之类的东西的唯一方法.bashrc就是明确地要求它。如果你想使用 shell 代码,你必须以-T信任服务器为代价使用:

scp -T server:'*(.oc[1,10])' .
Run Code Online (Sandbox Code Playgroud)

因此,现在您可以在简单的非递归情况下获得安全性,而无需完全放弃scp比其他实用程序(如sftpor )更有用的独特功能rsync

SCP通过SFTP所取代?

sftp 不能用shell 代码指定它想要的文件。它只接受实际的文件路径。这样就比较有限了。如果您只需要 scp 用于简单的文件路径,那么是的。但是,如果您希望能够从带有服务器端 shell 代码的简单命令中指定文件的附加功能(尽管以必须信任您的服务器为代价),那么我认为您唯一的选择是scp.

为什么引用“不安全”?

这是不安全的,但前提是您不相信服务器不会受到损害。就我而言,也许对于大多数人来说,我们将 scp 与我们以其他方式完全信任的服务器一起使用。特别是,我用它从我的笔记本电脑登录到我的台式机,反之亦然。如果我们不能相信自己的设备,那我们还能相信什么?这就是为什么我认为将其称为简单不安全是夸张的。例如,它无法与我们称 telnet 不安全的方式相提并论。

不过,我仍然感谢对 required 的更改-T。它安全的。此外,对于那些不需要由 启用的功能的人来说-T,使用 scp 确实比 sftp 或 rsync 并没有太大优势。

  • TL;DR:如果您不信任您的服务器,请验证您的“scp”客户端是否支持“-T”标志,但**不要使用**“-T”或“-r”。 (2认同)

Arc*_*mar 21

我读它的方式是“视情况而定”。

根据CVE-2019-6111

但是,scp 客户端仅对返回的对象名称进行粗略验证(仅防止目录遍历攻击)。恶意 scp 服务器(或中间人攻击者)可以覆盖 scp 客户端目标目录中的任意文件。如果执行递归操作 (-r),服务器也可以操作子目录(例如,覆盖 .ssh/authorized_keys 文件)。

因此,如果scp在您的场所(数据中心)内的主机之间进行,很可能(但不确定)不会执行 MITM 攻击。

但是,如果从世界各地的野生网的客户/合作伙伴获取业务文件,你应该依靠sftp,或更好的ftps。(至少,确保scp客户端和ssh服务器有正确的版本)

  • . . . 但是那个 CVE 已经被修复了。如果您的前提是我们应该表现得好像所有过去的安全问题仍然有效,那么我也不认为您可以推荐任何其他软件。(你真的是说 `sftp` 和 `ftps` 从来没有任何潜在的安全问题吗?) (7认同)
  • 我不会认为 ftps 更好。考虑到两者之间的漏洞历史,我会相信 ssh 而不是 ssl/tls (6认同)
  • @slebetman 错误的历史是一条红鲱鱼。在许多情况下,在特定协议或系统中会发现更多错误,因为它是一个更大的目标,因为它被使用得更多并且被更频繁地识别。您没有解决我的主要观点,即在 SSH 中,大多数人使用它并在他们第一次通过 WAN SSH 进入系统时盲目输入“y”而没有检查指纹。TLS 具有自动检查证书的基础结构,从而提高了安全性。 (4认同)
  • @slebetman 正是因为 SSH 是为系统管理员开发的,所以它没有像 TLS 那样针对人为错误进行加固。系统管理员会犯人为错误(比如在提示检查密钥指纹时盲目输入“y”)**一直**。 (3认同)

Dmi*_*yev 6

如果您认为 SSH 上的 MITM 是可能的,我会说很多 Unix 命令变得不安全。恶意者sudo可以窃取您的密码,恶意通信客户端可以读取您的邮件/即时消息等。

至少可以说,在与受感染的服务器交谈时替换scpwithsftp会以某种方式纠正这种情况是非常乐观的。任何对scp本地文件造成的破坏也可以通过二进制文件、shell 脚本、Python 文件、Makefile 等来完成,流氓sftp会很乐意为您服务。

简而言之,如果您不注意 SSH 连接到哪些服务器,那么无论您使用哪种工具,您都有很高的风险,而使用sftp代替scp只会稍微安全一点。

这并不是说切换到sftp是一个坏主意:如果它是手头任务的高级工具,那么您就有充分的理由切换,顺便说一下,这与安全性无关。


小智 5

对于针对CVE-2019-6111所做的新 OpenSSH更改以及它们应该如何保证一切的安全性,存在很多困惑。scp

它们的目的是防止用作文件源的恶意服务器发送请求之外的其他文件名,并覆盖本地计算机上的随机文件。

但当使用该选项时它们没有任何作用-r。使用-r意味着-T.

虽然完全合乎逻辑,但许多人无法意识到这一点,并且他们会因为总是期望scp检查文件名而陷入自满感。直到有一天,他们遇到了残酷的事实。由此提供的“安全性”并不比alias rm='rm -i'.

由于仅用于测试而设置流氓 ssh/scp 服务器可能非常复杂,因此您可以使用选项-S programscp指示它使用另一个程序而不是ssh设置通道)来验证我的声明。

在这里,我使用一个小的可执行脚本ssh_from_hell,无论要求什么,它总是发送一个lolcats.lol文件:

$ chmod 755 ssh_from_hell
$ scp -S ./ssh_from_hell user@host:foo.txt .
protocol error: filename does not match request
    # OK, as expected

$ scp -S ./ssh_from_hell -r user@host:foo/ .
lolcats.lol                                   100%   12    62.0KB/s   00:00
$ cat lolcats.lol
LOL LOL LOL


$ cat ssh_from_hell
#! /usr/bin/perl
use strict;

$|=1;   # autoflush
sub readack { local $/=\1; <STDIN> }
sub ack { print "\0" }
my $data = join '', <DATA>;

readack;
printf "C%04o %lld %s\n", 0666, length($data), "lolcats.lol";
readack;
print $data;
ack;

__DATA__
LOL LOL LOL
Run Code Online (Sandbox Code Playgroud)

新更改带来的另一个不幸是您不能再引用远程文件名,而是不能再引用远程文件名。

scp 'user@host:"a file with spaces and * love *.txt"' .
Run Code Online (Sandbox Code Playgroud)

你应该使用

scp 'user@host:a\ file\ with\ spaces\ and\ \*\ love\ \*.txt' .
Run Code Online (Sandbox Code Playgroud)

然而,一些有影响力的开发人员显然喜欢大括号,因此他们还添加了一个带有大括号支持的临时模式匹配实现scp——他们可能已经使用glob(3)with GLOB_ALTDIRFUNC|GLOB_BRACE,但编写新代码总是更有趣。无论如何,fwiw,请注意 scp 中的大括号扩展实现几乎与 csh 类似,即。{{foo}}将扩展到foo

$ scp -S ./ssh_from_hell 'user@host:{{lolcats.lol}}' .
lolcats.lol                                   100%   12    61.6KB/s   00:00
Run Code Online (Sandbox Code Playgroud)

csh但与、perl和 的内容并不完全相同glob(3)

$ scp -S ./ssh_from_hell 'user@host:lolcats{}.lol' .
protocol error: filename does not match request
Run Code Online (Sandbox Code Playgroud)

还有越野车:

$ scp -S ./ssh_from_hell 'user@host:lolcats{,}.lol' .
protocol error: filename does not match request
Run Code Online (Sandbox Code Playgroud)


Mar*_*art -4

他们不正确,你是!

sftp 是 ssh 的衍生产品。我认为他的意思是不使用FTP而使用sftp。

SCP 和 sftp 大部分都在 SSH 之上运行,因此如果他们希望您不使用 SCP,他们也不应该希望您使用 SSH(或 sftp)。sftp 和 scp 都允许安全文件传输、加密密码和传输数据。

sftp 可以做一些 scp 不能做的事情,但据我所知与安全无关

此外,SCP 比 sftp 更快,因为它使用更快的算法。

显示 sftp 是 ssh 的衍生版本的链接。

https://www.linux.com/tutorials/transfer-files-securely-sftp/

https://www.goanywhere.com/blog/are-ssh-and-sftp-the-same https://www.technology.pitt.edu/security/secure-shell-ssh-and-sftp

  • 正确的。不同之处在于 1) SFTP 不是 *SCP 的衍生品*。协议完全不同。2) SCP 协议的一些细节使其实现更容易出现一些安全错误(请参阅@Kusalananda 的评论)。 (2认同)
  • _“SFTP 是 scp 的衍生品。”_ -- 对此有来源/参考/进一步解释吗?_“SFTP 可以做一些 scp 不能做的事情”_ —— 好吧,我不怀疑这一点,但至少提及其中一些事情会很有用。_“而且 SCP 比 sftp 更快,因为它使用更快的算法。”_ -- 需要引用。 (2认同)
  • `scp` 是 `rcp` 的派生物。除了依赖于底层“ssh”传输的“scp”和“sftp”之外,两者都与“sftp”没有任何代码关系。 (2认同)