是`curl {something} | sudo bash -` 一种相当安全的安装方法?

信息安全 卷曲 须藤 安装
2021-08-29 14:04:59

在 Ubuntu 或 Debian 上安装 NodeJS 最直接的方法似乎是 Nodesource,它的安装说明说要运行:

curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -

这与我很久以前学到的一些基本安全规则相冲突,例如“对下载保持怀疑”和“对 sudo 保持谨慎”。但是,我很久以前就学会了这些规则,现在似乎每个人都在这样做……好吧,至少它在askubuntu.com 上有 350 个赞

当我在其他网站上阅读各种意见时,我发现有些人也认为 curl-pipe-sudo-bash 不安全:

虽然有些人认为它与任何其他实际安装方法一样安全:

也有一些在没有给出决定性意见的情况下探索问题:

由于其他站点没有明确的共识,我在这里问: curl-pipe-sudo-bash 是一种相当安全的安装方法,还是它带有可以通过其他方法避免的不必要的风险?

4个回答

它与任何其他标准1安装方法一样安全,只要您:

  • 使用 HTTPS(并拒绝证书错误)
  • 对您的证书信任库充满信心
  • 信任您从中下载的服务器

您可以而且应该将这些步骤分开 - 下载脚本2,检查它,并在运行您下载的脚本3之前查看它是否有任何可疑之处这是一个好主意。如果您这样做不会有任何伤害,并且您可能会遇到妥协,您可以向消息来源和整个社区报告。如果我对此类事情的经验可以作为任何指标,请准备好深入研究大量 Bash。如果您特别担心邪恶的服务器,您也可以尝试“扩展”它,下载任何单独的脚本并调整脚本以调用它们,但在某些时候,如果您必须决定只使用不同的服务器太不相信第一个了。

请注意,如果服务器 ( deb.nodesource.com) 受到威胁,您基本上没有追索权。许多包管理器提供验证包上的 GPG 签名,即使密钥签名体系结构的一个基本部分被破坏,这仍然可以正常工作。您可以手动为wgetcurl指定 CA ,但这仅证明您确实连接到该服务器,而不是服务器正在提供安全代码或者它是来自创建者的合法代码。4

如果您担心任意代码执行,APT绝对允许这样做,而且我相当有信心 Homebrew 和 Yum 也可以这样做。所以相对来说,也不算不安全。这种方法允许更大的可见性;您确切地知道发生了什么:正在下载一个文件,然后由 Bash 将其解释为脚本。很有可能你已经有足够的知识开始研究脚本了。在最坏的情况下,Bash 可能会调用另一种您不知道的语言,或者下载并运行已编译的可执行文件,但即使是这些操作也可以事先注意到,如果您愿意,可以进行调查。

附带说明一下,考虑到很多时候您需要使用 安装东西sudo,我不认为它在这里的使用有什么特别的问题。这有点令人不安,是的,但仅此而已sudo apt install ...


1:当然,还有更安全的包管理器——我只谈论标准的包管理器,比如 APT 和 yum。

2:......当然要小心你的复制/粘贴。如果您不知道为什么要小心复制/粘贴,请考虑以下 HTML Use this command: <code>echo 'Hello<span style="font-size: 0">, Evil</span>!'</code>:. 为了安全起见,请尝试粘贴到(GUI)文本编辑器中,并确保您复制了您认为您所做的内容。如果您没有,请立即停止信任该服务器。

3:您实际上可以检测脚本是刚刚被下载还是正在下载并执行,因为使用 Bash 解释脚本与将其保存到文件所需的时间不同,并且 Linux 的管道系统可以“备份”,这可以使这些时间差异对服务器可见。如果您运行curl | sudo bash他们给出的确切命令,那么您的检查(至少如果它是恶意服务器......)毫无意义。

4:再一次,看起来 NodeSource 正在创建某种自定义安装程序,无论如何都不会由 Node 团队签名,所以......我不相信在这种特殊情况下它不那么安全。

在将curl ... | bash安装与 Unix 分发包系统(如aptyum.

首先是确保您请求的是正确的文件。Apt 通过保持自己的包名称映射到更复杂的 URL 来做到这一点;OCaml 包管理器只是opam提供相当简单的验证。相比之下,如果我使用 opam 的 curl/shell 安装方法,我需要 https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh使用我个人的知识来验证 URL,这raw.githubusercontent.com是一个运行良好的站点(由 GitHub 拥有并运行),它的证书不太可能被泄露,它确实是从 GitHub 项目下载原始内容的正确站点,ocamlGitHub 帐户确实是我要安装其软件的供应商,并且 opam/master/shell/install.sh是我想要的软件的正确路径。这不是很困难,但是您可以在这里看到人为错误的机会(与验证相比)apt-get install opam) 以及如何使用更不清晰的站点和 URL 来放大它们。在这种特殊情况下,上述两个供应商(GitHub 和 OCaml 项目)中的任何一个的独立妥协都可能会影响下载,而另一个则无法做很多事情。

第二个安全功能是确认您获得的文件实际上是上述名称的正确文件。curl/shell 方法仅依赖于 HTTPS 提供的安全性,这可能会在服务器端(只要服务器操作员非常小心)和客户端(比你想象的要频繁得多)受到损害TLS 拦截的年龄)。相比之下,apt 通常通过 HTTP 下载(因此使整个 TLS PKI 无关紧要)并通过 PGP 签名检查下载的完整性,这相当容易保护(因为密钥不需要在线等) .

第三是确保当您从供应商处获得正确的文件时,供应商本身不会分发恶意文件。这归结为供应商的包装和审查流程的可靠性。特别是,我倾向于相信签署发布包的官方 Debian 或 Ubuntu 团队已经生产出经过更好审查的产品,这既是因为这是这些团队的主要工作,也是因为他们在顶部进行了额外的审查上游供应商做了什么。

打包系统(例如 apt)还提供了一个额外的有时有价值的功能,使用 curl/shell 安装过程的系统可能会或可能不会提供:安装文件的审计。因为 apt、yum 等具有软件包提供的大多数文件的哈希值,所以可以检查现有的软件包安装(使用诸如debsums或之类的程序rpm -v)以查看是否有任何已安装的文件已被修改。

curl/shell 安装方法可以提供一些潜在的优势,而不是使用打包系统,例如aptor yum

  1. 您通常会获得更新版本的软件,特别是如果它本身是一个打包系统(例如 pip 或 Haskell Stack),它可能会定期检查(使用时)以查看它是否是最新的并提供一个更新系统。

  2. 某些系统允许您以非 root 用户(即,在您的主目录中,由您拥有)安装该软件。例如,虽然opam上面安装的二进制文件install.sh是默认放入/usr/local/bin/的(在许多系统上需要 sudo 访问权限),但您没有理由不能将其放入~/.local/bin/或类似的地方,因此永远不要为安装脚本或后续软件提供任何 root 访问权限全部。这样做的好处是可以确保避免 root 泄露,尽管它确实使以后的软件运行更容易泄露您正在使用的软件的已安装版本。

提交我自己的问题的答案。不确定这是否是最佳答案,但我希望其他答案能够解决这些问题。

curl {something} | sudo bash -在 Linux 上与在 Windows 上下载内容并右键单击以管理员身份运行一样安全。有人可以说这是“相当安全”,但正如最近的xkcd 所暗示的那样,没有人真正知道这些天计算机安全性有多糟糕。无论如何,这种方法不如其他安装方法安全。

所有更安全的方法都包括在安装任何内容之前验证下载完整性的步骤,并且没有充分的理由跳过此步骤。安装程序喜欢apt内置某种形式的此步骤。目标是确保您下载的内容是发布者想要的。这并不能保证该软件没有自身的漏洞,但它至少应该可以防止以恶意软件代替下载的简单攻击。本质只是验证软件发布者发布的 MD5 和 SHA256 校验和。一些进一步的改进是可能的:

  • 最好通过不同的网络路径获取这些校验和,例如通过呼叫另一个国家的朋友,这样可以防止 MITM 攻击。
  • 最好至少提前/晚一天获取校验和,以防万一发布者的网站被短暂接管但接管在一天内停止。
  • 最好使用 GPG 自己验证校验和,这样可以防止发布者的网站遭到入侵,但他们的 GPG 私钥却没有。

一方面评论:一些网站说你应该下载sh脚本,然后在运行之前检查它。不幸的是,这会给人一种虚假的安全感,除非您以几乎不可能的精确度来审查脚本。shell 脚本可能只有几百行,非常微小的更改(例如对 URL 进行模糊的单字符更改)可以将 shell 脚本转换为恶意软件安装程序。

“合理安全”取决于您的球门柱,但curl | bash远远落后于最先进的技术。

让我们看一下人们可能想要的验证类型:

  • 确保您的 ISP 处的恶意人员无法通过中间人为您提供任意代码。
  • 确保您获得与作者发布的相同的二进制文件
  • 确保您获得的二进制文件与下载相同文件名的人获得的二进制文件相同。
  • 确保您下载的二进制文件反映了一组特定的、可审核的源代码和构建步骤,并且可以从中复制。
  • 安装软件运行软件分开——如果您要安装由不受信任的低权限用户运行的软件,则不应在此过程中将任何高权限帐户置于风险之中。

有了curl | sudo bash,如果那样的话,你只会得到第一个;rpm或者你得到其中dpkg的一些;nix你可以得到所有的。

  • 使用curl通过 下载https,您对中间人攻击者有一定的安全性,因为该攻击者无法伪造对远程站点有效的证书和密钥。对于闯入远程服务器的攻击者,或有权访问您公司将本地 CA 放入公司拥有硬件的所有 CA 存储列表中的攻击者,您没有安全措施,因此他们可以 MITM 传出 SSL 连接以进行故意“安全”的目的!)。

    curl | sudo bash这是有时可以成功保护您免受攻击的唯一威胁模型。

  • 确保您获得与作者发布的相同的二进制文件,可以通过该作者的数字签名来完成(Linux 发行版通常会分发 OpenPGP 密钥的钥匙串,这些钥匙串属于被授权将包发布到该发行版的个人,或者拥有他们使用的密钥他们自己构建的包,并使用访问控制措施来限制哪些作者能够将包放入他们的构建系统)。

    正确部署,rpmdpkg为您提供这种安全性;curl | bash才不是。

  • 如果可以捕获授权作者的密钥,那么确保请求相同名称始终返回相同的二进制文件会比较棘手。但是,如果您正在下载的内容是hash-addressed,则可以做到这一点要以相同的名称发布不同的内容,攻击者需要将输入与哈希值与文件内容分离(如果它是已发布的二进制文件的哈希值,则可以轻松检测到。

    迁移到哈希寻址的构建发布有两种可能的方法:

    • 如果哈希是构建的输出,攻击者最简单的方法是找到最终用户查找该哈希并用恶意值替换它的机制——因此攻击点移动了,但是漏洞本身没有。

    • 如果哈希是构建的输入,则检查构建的输出是否真正匹配这些输入需要做更多的工作(即重新运行构建!)来检查,但这种检查变得更加难以逃避。

    后一种方法是更好的方法,即使检查成本高昂并且需要对进行软件打包的人员进行额外的工作(以处理程序作者折叠在时间戳或其他不可重现的元素中以构建流程本身的任何地方)。

    与恶意作者打交道不在rpmdpkg试图解决的安全模型中,当然,curl | bash也没有做任何事情。

  • 将安装与运行时分开是一个预先设计序列化格式的问题,没有危险的特性——不支持setuidsetgid位,不支持安装时使用任意代码的非沙盒运行脚本等curl | sudo bash,在这里没有保护,但rpmdpkg不要吨。nix相比之下,允许任何非特权用户将软件安装到商店中——但它使用的 NAR 序列化格式不会代表 setuid 或 setgid 位,商店中的内容不会被任何未明确请求的用户帐户引用或依赖于它的软件,以及需要setuid安装权限的软件需要在这些位实际设置之前明确的带外管理操作。

    只有古怪的、小众的、专业的软件安装方法nix才能做到这一点。