是否有一个外壳程序可以检查以确保代码已签名?


19

我本周在搞弄PowerShell,发现需要对脚本进行签名才能运行它们。Linux中是否有与阻止bash脚本运行相关的类似安全功能?

我知道,与此类似的唯一功能是需要特定密钥的SSH。


2
听起来有点像打包签名的临时解决方案。我不知道Windows是否像Linux一样具有加密软件包签名。
2016年

6
@ leeand00脚本是软件包的一种特殊情况,我看不出要指出这种情况的任何意义。
吉尔斯(Gillles)“所以-别再邪恶了”

2
我最喜欢的机制是ChromeOS的执行方式-将唯一未标记的文件系统noexec放在dm-verity签名块设备的只读分区上。
查尔斯·达菲,2016年

1
source.android.com/security/verifiedboot讨论了Android对这一功能(最初为ChromeOS)的采用。
查尔斯·达菲,2016年

1
您可以将bash视为一堆可以在命令行界面中手动键入的命令。当您仍然可以在命令行中键入内容时,限制脚本有什么意义?
陈鼎一

Answers:


11

如果要锁定用户通过脚本运行脚本的能力,sudo则可以使用该digest功能。
您可以指定脚本/可执行文件的哈希值,然后在执行之前对其sudoers进行验证sudo。因此,尽管它与签名不同,但它为您提供了一个基本保证,即至少在不修改sudoers的情况下,脚本也没​​有被修改。

如果命令名称带有Digest_Spec前缀,则该命令仅在可以使用指定的SHA-2摘要进行验证的情况下才成功匹配。这在调用sudo的用户对命令或其父目录具有写访问权的情况下很有用。支持以下摘要格式:sha224,sha256,sha384和sha512。可以以十六进制或base64格式指定字符串(base64更紧凑)。有几种实用程序可以生成十六进制格式的SHA-2摘要,例如openssl,shasum,sha224sum,sha256sum,sha384sum,sha512sum。

http://www.sudo.ws/man/1.8.13/sudoers.man.html


在我了解SE Linux并正确完成之前,这会一直困扰着我。
leeand00

13

是的,没有。

Linux软件发行版与Windows软件发行版有些不同。在(非嵌入式)Linux世界中,分发软件的主要方法是通过分发(Ubuntu,Debian,RHEL,Fedora,Arch等)进行分发。所有主要发行版都已经系统地签署了其软件包约十年。

如果软件是独立分发的,则由供应商来决定他们将如何发布软件。好的供应商提供与主要发行版兼容的软件包源(没有针对所有Linux的统一发行机制:软件发行版是发行版之间区别的主要点之一),并由供应商的密钥签名。Linux发行版很少充当第三方供应商的签名机构(Canonical与Ubuntu合作伙伴可以这样做,但是覆盖的供应商很少),我认为所有主要发行版都使用PGP信任网络而不是TLS公钥基础结构,因此由用户确定他们是否要信任密钥。

没有特殊的机制可以从包含本机可执行文件,数据文件或多个文件的软件包中挑选出包含单个脚本的软件包。通用脚本解释器也没有内置任何签名验证,因为验证软件包与运行脚本完全是正交的。

我认为Windows用其来源注释文件,并且需要用户确认才能运行其来源是“下载”而不是“本地”的文件。Linux确实没有类似的机制。最接近的是执行权限:下载的文件没有执行权限,用户需要显式启用它(chmod +x在命令行或文件管理器中的等效操作)。


2
FWIW,可以在此PowerShell之上配置(通过策略设置)以仅执行签名的脚本,并且可以配置此策略,以便必须对所有脚本进行签名,或者仅对“远程源”脚本进行签名,或者不对脚本进行签名。它在具有密钥管理和中央策略管理的AD环境中效果最佳。可以绕过它:-)
史蒂芬·哈里斯

@StephenHarris好吧,如果您将其设置为绕过...
leeand00

@ leeand00-显然base64编码也可以绕过,但我不知道在PowerShell的较新版本中是否已将其关闭。
史蒂芬·哈里斯

1
@ leeand00-参见darkoperator.com/blog/2013/3/5/…以获得一些乐趣:-)基本上将base64编码的脚本作为参数传递给命令行:-)足够容易包装!
史蒂芬·哈里斯

2
SeLinux使用其来源注释文件。这是它的主要前提之一。
loa_in_


8

一句话,“不”。

Linux并没有真正区分可执行文件和脚本。一#!开始是一种告诉内核运行哪个程序来评估输入的方法,但这并不是执行脚本的唯一方法。

因此,例如,如果我有一个脚本

$ cat x
#!/bin/sh 
echo hello

然后我可以使用命令运行

$ ./x

这将导致内核尝试执行它,发现#!并随后有效运行/bin/sh x

但是,我也可以运行以下任一变体:

$ sh ./x
$ bash ./x
$ cat x | sh
$ cat x | bash
$ sh < x

甚至

. ./x

因此,即使内核尝试在exec层上强制执行签名,我们也可以通过仅使用脚本作为参数运行解释器来绕过此操作。

这意味着签名代码必须在解释器中。还有什么会阻止用户在没有签署强制执行代码的情况下编译自己的Shell副本?

解决此问题的标准方法不是使用签名,而是使用强制访问控制(MAC),例如SELinux。使用MAC系统,您可以确切指定允许每个用户运行和过渡层的内容。因此,例如,您可以说“普通用户可以运行任何东西,但Web服务器和CGI进程只能访问/var/httpd目录中的内容;其他所有内容均被拒绝”。


1
This means that signing code would have to be in the interpreter itself. And what would stop a user from compiling their own copy of a shell without the signing enforcement code?如果用户没有签名密钥,则不允许执行任何未签名的可执行文件。已经有各种各样的* nix项目。
alzee

2

Linux发行版通常具有gnupg。在我看来,您想要的只是一个简单的bash包装器,它针对参数脚本检查分离的gpg签名,并且仅在检查成功后才继续运行脚本:

#!/bin/sh
gpgv2 $1.asc && bash "$@"

这唯一不存在的事情是运行一个人自己编写的脚本......
leeand00

2

立即想到的反问是“您为什么要阻止用户运行他们编写的程序 ”存在几种可能性:

  1. 首先,根本不可能检测出谁编写了代码。脚本文件的所有者就是实际保存该文件内容的人,无论它来自何处。因此,强制签名只是确认对话框的一个复杂替代: “您确定要这样做吗?” 在Linux中,此问题的一部分可以通过已签名的软件包透明解决,并且可以通过默认情况下用户访问受限的事实来缓解。还希望用户知道运行其他人的代码可能很危险*。
  2. 同样,对脚本进行签名比保存文件要复杂得多。在最佳情况下,这会提示用户意识到他们正在执行与对文档签名相似的操作,并应在继续操作之前检查其内容。最有可能的是,它只是确保了允许用户运行脚本的最低水平的技术水平。在最坏的情况下,它表明愿意跳很多来运行他们想要的东西。假定在Linux *上具有技术水平。
  3. 当在命令行中键入/粘贴一系列命令时,人们更有可能检测到明显的恶意代码。通常,要复制和粘贴的纯文本摘要比执行适当有害的操作所需的一系列命令要小。用户还可以仔细地复制和粘贴每行,以了解发生的情况。使用脚本,用户可能根本没有看过代码。这可能是签名脚本的有用应用程序,但是在您第12次这样做之后,却以自满的自负代价。

*随着越来越多的人开始使用Linux,这种情况可能越来越不真实。


1

系统发展不同的原因是Linux具有'exec'文件属性,而Windows使用文件扩展名来确定可执行性。

因此,在Windows中,很容易诱使用户下载扩展名为“ .exe”,“。bat”,“。scr”的文件,这些文件默认情况下是隐藏的。双击该文件将使您可以执行任意代码。因此,建立了一种大型的起源跟踪和可执行文件/脚本签名机制来减轻这种风险。

在Linux上,您可能可以将文件发送给用户,但是您不能轻易地强制设置'exec'位。另外,可以使整个文件系统为“ noexec”。

在任何情况下,都可以通过调用解释器来显式运行脚本。您甚至可以在运行时创建shell脚本并将其通过管道传递到“ sh”,或运行“ sh -c”。


0

按照惯例,许多归档程序不会在包含的文件上保留执行位。这使得不可能运行任意可执行文件。好吧,差不多。

关键是,在另一个答案中描述的缺少执行位的内容并不能阻止您将此类脚本直接传递给bash。尽管大多数此类脚本都是bash脚本是有争议的,但是shebang可以将任何程序指定为解释器。这意味着,如果用户决定忽略可执行语义,则取决于用户运行适当的解释器。

尽管数量不多,但这几乎涵盖了防止仅在内核和shell上在* nixes上运行不受信任的可执行文件的情况。

正如我在评论中提到的那样,还有另一层保护- SeLinux可以根据一组规则跟踪文件的来源。SeLinux例如,即使您复制并移动文件,设置也不会允许root用户运行从Internet下载的具有可执行位集的可执行文件。可以添加一条规则,即此类文件只能通过另一个将检查签名的二进制文件运行,这与您在问题中提到的没有什么不同。

因此,最后是通常预安装的工具的配置问题,答案是肯定的


许多归档程序不会在包含的文件上保留执行位 ..嗯,当您实际上想将其用于归档时,这是一个障碍。幸运的是tar 确实保留了执行位。
pjc50

您必须使用tar -p source
loa_in_

-p, --preserve-permissions, --same-permissions表示提取有关文件权限的信息(超级用户默认)
loa_in_

不,您不需要-p。我可以看到手册页上的内容,但事实并非如此。touch permtest; chmod +x permtest; tar cf permtest.tar.gz permtest; rm permtest; tar xf permtest.tar.gz; ls -l permtest-在这里可执行,我不是root。
domen

然后,我将尝试改善答案。
loa_in_
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.