我本周在搞弄PowerShell,发现需要对脚本进行签名才能运行它们。Linux中是否有与阻止bash脚本运行相关的类似安全功能?
我知道,与此类似的唯一功能是需要特定密钥的SSH。
noexec
放在dm-verity签名块设备的只读分区上。
我本周在搞弄PowerShell,发现需要对脚本进行签名才能运行它们。Linux中是否有与阻止bash脚本运行相关的类似安全功能?
我知道,与此类似的唯一功能是需要特定密钥的SSH。
noexec
放在dm-verity签名块设备的只读分区上。
Answers:
如果要锁定用户通过脚本运行脚本的能力,sudo
则可以使用该digest
功能。
您可以指定脚本/可执行文件的哈希值,然后在执行之前对其sudoers
进行验证sudo
。因此,尽管它与签名不同,但它为您提供了一个基本保证,即至少在不修改sudoers的情况下,脚本也没有被修改。
如果命令名称带有Digest_Spec前缀,则该命令仅在可以使用指定的SHA-2摘要进行验证的情况下才成功匹配。这在调用sudo的用户对命令或其父目录具有写访问权的情况下很有用。支持以下摘要格式:sha224,sha256,sha384和sha512。可以以十六进制或base64格式指定字符串(base64更紧凑)。有几种实用程序可以生成十六进制格式的SHA-2摘要,例如openssl,shasum,sha224sum,sha256sum,sha384sum,sha512sum。
是的,没有。
Linux软件发行版与Windows软件发行版有些不同。在(非嵌入式)Linux世界中,分发软件的主要方法是通过分发(Ubuntu,Debian,RHEL,Fedora,Arch等)进行分发。所有主要发行版都已经系统地签署了其软件包约十年。
如果软件是独立分发的,则由供应商来决定他们将如何发布软件。好的供应商提供与主要发行版兼容的软件包源(没有针对所有Linux的统一发行机制:软件发行版是发行版之间区别的主要点之一),并由供应商的密钥签名。Linux发行版很少充当第三方供应商的签名机构(Canonical与Ubuntu合作伙伴可以这样做,但是覆盖的供应商很少),我认为所有主要发行版都使用PGP信任网络而不是TLS公钥基础结构,因此由用户确定他们是否要信任密钥。
没有特殊的机制可以从包含本机可执行文件,数据文件或多个文件的软件包中挑选出包含单个脚本的软件包。通用脚本解释器也没有内置任何签名验证,因为验证软件包与运行脚本完全是正交的。
我认为Windows用其来源注释文件,并且需要用户确认才能运行其来源是“下载”而不是“本地”的文件。Linux确实没有类似的机制。最接近的是执行权限:下载的文件没有执行权限,用户需要显式启用它(chmod +x
在命令行或文件管理器中的等效操作)。
Linux没有提供基于数字签名限制bash脚本执行的功能。
关于认证二进制可执行文件,有一些工作。有关信息,请参见https://lwn.net/Articles/488906/。
一句话,“不”。
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
目录中的内容;其他所有内容均被拒绝”。
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项目。
立即想到的反问是“您为什么要阻止用户运行他们编写的程序? ”存在几种可能性:
*随着越来越多的人开始使用Linux,这种情况可能越来越不真实。
系统发展不同的原因是Linux具有'exec'文件属性,而Windows使用文件扩展名来确定可执行性。
因此,在Windows中,很容易诱使用户下载扩展名为“ .exe”,“。bat”,“。scr”的文件,这些文件默认情况下是隐藏的。双击该文件将使您可以执行任意代码。因此,建立了一种大型的起源跟踪和可执行文件/脚本签名机制来减轻这种风险。
在Linux上,您可能可以将文件发送给用户,但是您不能轻易地强制设置'exec'位。另外,可以使整个文件系统为“ noexec”。
在任何情况下,都可以通过调用解释器来显式运行脚本。您甚至可以在运行时创建shell脚本并将其通过管道传递到“ sh”,或运行“ sh -c”。
按照惯例,许多归档程序不会在包含的文件上保留执行位。这使得不可能运行任意可执行文件。好吧,差不多。
关键是,在另一个答案中描述的缺少执行位的内容并不能阻止您将此类脚本直接传递给bash
。尽管大多数此类脚本都是bash
脚本是有争议的,但是shebang可以将任何程序指定为解释器。这意味着,如果用户决定忽略可执行语义,则取决于用户运行适当的解释器。
尽管数量不多,但这几乎涵盖了防止仅在内核和shell上在* nixes上运行不受信任的可执行文件的情况。
正如我在评论中提到的那样,还有另一层保护- SeLinux
可以根据一组规则跟踪文件的来源。SeLinux
例如,即使您复制并移动文件,设置也不会允许root用户运行从Internet下载的具有可执行位集的可执行文件。可以添加一条规则,即此类文件只能通过另一个将检查签名的二进制文件运行,这与您在问题中提到的没有什么不同。
因此,最后是通常预安装的工具的配置问题,答案是肯定的。
tar
确实保留了执行位。
-p, --preserve-permissions, --same-permissions
表示提取有关文件权限的信息(超级用户默认)
touch permtest; chmod +x permtest; tar cf permtest.tar.gz permtest; rm permtest; tar xf permtest.tar.gz; ls -l permtest
-在这里可执行,我不是root。