出于安全考虑,最好在执行前检查代码的完整性, 避免攻击者篡改软件 。 所以,我的问题是
如何在Linux下签名可执行代码并运行可信软件?
我读过van Doom 等人的工作。 , Linux的签名可执行文件的devise和实现以及 Safford&Zohar的IBM TLC (可信Linux客户端)。 TLC使用TPM控制器,这很好,但是纸张是从2005年开始的,我无法find目前的替代品。
你知道另一种select吗?
更新 :关于其他操作系统的? OpenSolaris的? BSD家庭?
DigSig内核模块执行一个名为bsign
的工具签名的二进制文件的验证。 但是,从Linux内核版本2.6.21开始还没有任何工作。
我意识到这是一个古老的问题,但我现在才发现它。
我写了一个签名的Linux内核可执行文件支持(在版本2.4.3左右),并且有整个工具链来签署可执行文件,在execve(2)
时间检查签名,缓存签名验证信息(清除验证当文件被打开进行写入或修改时),将签名嵌入到任意的ELF程序中等等。它在每个程序的第一次执行时引入了一些性能损失(因为内核必须加载整个文件,而不仅仅是需求页面需要的页面),但是一旦系统处于稳定状态,它就运行良好。
但是我们决定停止追求它,因为它面临着太多的难以证明复杂性的问题:
我们还没有建立对签名库的支持。 签名库还需要修改ld.so
加载器和dlopen(3)
机制。 这不是不可能的,但是使接口复杂化了:我们是否应该让加载器要求内核验证一个签名,还是应该在用户空间中完成计算? 如果验证的这一部分在用户空间中完成,那么如何防止strace(2)
d进程? 我们是否会被迫在这样一个系统上完全禁止strace(2)
?
我们将如何提供自己的装载程序 ?
很多程序是用不能编译成ELF对象的语言编写的。 我们需要为bash
, perl
, python
, java
, awk
, sed
提供针对特定语言的修改,以便每个解释器都能够验证签名。 由于大多数这些程序都是自由格式的纯文本,所以它们缺少将数字签名嵌入到ELF对象文件中的结构。 签名在哪里存储? 在脚本中? 在扩展属性? 在签名的外部数据库中?
许多口译人员对于他们所允许的内容都是敞开的 。 bash(1)
可以使用echo
和/dev/tcp
完全独立地与远程系统进行通信,并且很容易被诱骗执行攻击者需要做的任何事情。 一旦被黑客控制,你就不能相信他们。
签名可执行文件支持的主要动力来自rootkit,取代了系统提供的/bin/ps
, /bin/ps
, /bin/kill
等。 是的,还有其他有用的理由来签署可执行文件。 然而,随着时间的推移,rootkit变得更加令人印象深刻,许多依靠内核黑客来隐藏他们的活动从管理员。 一旦内核被黑客入侵,整个游戏就结束了。 由于rootkit的复杂性,我们希望防止被使用的工具在黑客社区中不受欢迎。
内核的模块加载界面是开放的。 一旦一个进程拥有root
权限,很容易注入一个内核模块而不需要任何检查。 我们也可以为内核模块编写另一个验证器,但内核模块周围的基础结构是非常原始的。
GNU / Linux / FOSS模式实际上鼓励了一种篡改。 用户和发行商必须自由修改(篡改)软件以满足他们的需求。 即使只是重新编译软件(不更改任何源代码)进行定制也是经常进行的,但会破坏二进制代码签名。 因此,二进制代码签名模型不适合GNU / Linux / FOSS。
相反,这种类型的软件更多地依赖于源包的签名和/或安全哈希。 结合可靠和可信的软件包分发模式,可以使其与二进制代码签名一样安全(如果不是更像是对源代码的透明性)。
看看这个: http : //linux-ima.sourceforge.net/
它尚未签名,但仍能验证。
看看美杜莎DS9 。 我很久以前玩过它,但是如果我没有记错的话,你可以注册特定的二进制文件,并且在内核级别上不允许修改。 当然,可以通过本地访问机器来覆盖,但这并不容易。 有一个叫做constable的智能守护进程,检查机器上发生的所有事情,如果发生异常,就会开始尖叫。
我从来没有尝试过,但看看: http : //blog.codenoise.com/signelf-digitally-signing-elf-binaries 。 该解决方案不需要内核支持,看起来像准备去。
签名者的代码可以在http://sourceforge.net/projects/signelf/找到
它并没有解决“在Linux上只运行可信任的代码”的问题,但是通过为程序提供一种方法来检测自身是否存在篡改/破坏,部分解决了这个问题
http://en.wikipedia.org/wiki/PKCS
使用它的PKCS7(S / MIME)标志。 生成自己的证书/私钥对,自签名证书,然后使用PKCS7私钥和证书签名文件。 它将附加证书,然后它可以在运行时使用openssl命令(man smime或只是做openssl的帮助)检查自己。 这是防篡改的,因为即使公用密钥在您发出的文件中,该公钥的S / MIME签名也只能使用您不会分发的私钥生成。 所以,如果文件是由你的证书签名的,它必须由有私钥的人签名,并且由于你没有把私钥给任何人,所以它必须来自你。
以下是如何制作自签名证书。
http://www.akadia.com/services/ssh_test_certificate.html
你必须说服openssl信任你的证书作为权限的根(-CAfile),然后检查它作为根,并且检查文件的证书是你的(散列证书)并检查散列。 请注意,虽然没有记录,但openssl的退出状态反映了您在进行Smime验证时正在检查的符号的有效性。 如果匹配则为0,如果不匹配则为非零。
请注意,所有这一切都不安全,因为如果支票在您的代码中,他们可以简单地删除支票,如果他们想打败你。 唯一可行的方法是在操作系统中安装检查器,并检查你的二进制文件,如果没有签名,就拒绝运行它。 但是由于操作系统中没有检查器,因此无论如何都可以修改linux以删除/绕过它。这真的很好,只是检测损坏的文件,而不是试图阻止人们绕过你。
我可以从Solaris 10和11 OS的角度回答这个问题,所有的二进制文件都被签名。 要验证签名使用“elfsign”…
$ elfsign verify -v /usr/bin/bash elfsign: verification of /usr/bin/bash passed. format: rsa_sha1. signer: O=Oracle Corporation, OU=Corporate Object Signing, OU=Solaris Signed Execution, CN=Solaris 11. signed on: Fri Oct 04 17:06:13 2013.
Oracle最近也为Solaris 11添加了经过验证的引导过程,有关详细信息,请参阅 – Solaris已验证的引导简介
OpenSolaris代码中有一些生产级别的叉子,值得研究的三个是Illumos,SmartOS和OmniOS。