在 Linux 上安全地存储应用程序机密

信息安全 linux 密钥管理 防御 权限
2021-09-08 17:51:25

我有一个 linux 应用程序需要读取一个秘密来解密一些数据。该应用程序还允许用户在运行时更改加密密码。该应用程序将在单独的用户帐户下运行,并且密钥当前位于该用户拥有的文件中。我正试图想办法改善这种情况,因为密码在文件中是明文的。

应用程序可以以 root 身份启动,然后将权限授予应用程序用户。这样,秘密文件可以由 root 拥有,但是除非我以 root 身份运行另一个守护程序,否则密码更改方案会中断。

我基本上是想防止秘密在磁盘上以明文形式存在,并且没有人在循环中引导加密过程,可以做的最好的事情就是即使有人得到代码,也很难获得秘密执行。

任何人都可以分享任何关于我如何改善当前情况的建议吗?keyctl 是适用于这里的东西,还是通常只用于存储内核机密的东西?

任何建议将不胜感激!

3个回答

您的服务不应正常root运行使用单独的用户来存储机密是一种明智的预防措施,但是存储具有root所有权的文件并不比使用另一个专用用户更好。只要您的秘密文件具有600或更少的权限,它就会对其他非root用户安全。无论如何,任何正在运行的东西root都具有完全访问权限。(除非您正在运行一些复杂的 SELinux 设置)

为这个单一应用程序使用两个用户以将秘密管理与正常操作隔离开来可能会有所帮助。要么有两个运行实时通信的守护程序,要么有实用程序命令来操作秘密,通过sudo.

您应该考虑潜在的攻击媒介。

  • 如果配置正确,SQLi 不会授予文件系统访问权限,但路径遍历攻击可以。您应该保护您的应用程序免受其他类型的攻击。

  • C 库中的漏洞利用(即运行 HTTPS 加密、图像处理等的 OpenSSL)可能是可能的。在暴露于网络的进程上使用单独的用户可以帮助限制范围或增加攻击的难度。

  • 来自其他攻击媒介的入侵可能是一个问题。(SSH,机器上的其他服务)确保任何可能root访问的东西都得到很好的保护。

所有这些考虑因素都应该有助于您保护机密本身。现在的问题是,秘密真的需要明文存储吗?

在最基本的层面上,是的,秘密必须存储在某个地方才能使用。它至少必须存储在内存中,而且还需要某种永久存储。

除了我们讨论过的用户分离之外,将机密卸载到单独的硬件安全模块甚至是单独的小型计算机可能会有所帮助。(即树莓派)这里有一些关于物理分离的讨论

在极少数情况下,秘密可以在永久存储中自行加密。

如果您担心硬盘驱动器被盗(将机器的其余部分留在后面),那么您可以有一个启动脚本来查询其他一些硬件的唯一标识符,并使用良好的基于​​密码的密钥派生来派生加密密钥功能; 解密秘密。

如果客户可以提供一部分秘密,那将是有帮助的。我在这里概述了一种从用户密码和会话令牌派生解密密钥的方法。这是一个复杂而有效的系统,它专注于限制一个秘密的存储时间,即使是在内存中也是如此。(假设您不需要自动密码重置)

你所拥有的是传统的做事方式。例如,Tomcat 建议使用 OWASP concurring来这样做。所以,你所拥有的还不错。

但是,还有其他方法可以做到这一点 - 硬件安全模块是专为密钥存储而设计的有限访问存储。Hashicorp 的 Vault、KeyWhiz 和类似技术是秘密管理系统,基本上是试图成为软件 HSM。当然,所有这些技术都需要能够对流程进行身份验证——它们的优势在于它们有多种机制来实现这一点。您可以使用 root 访问密钥,然后该密钥仅在内存中提供给 Web 用户 - 它可以使用该密钥访问 HSM/Vault/KeyWhiz 以便能够访问和更改实际密钥。还有其他机制——AWS 特定的使用 EC2 密钥的机制,还有很多其他机制。你也许能找到一些网格很好的东西。

我个人的观点是,经过验证的真正受限用户(仅用于此目的)和仅限该用户的受限文件并不是一个糟糕的方法。但是,在其他选项可能的情况下,它的扩展性并不好。

如果秘密以任何无需人工干预即可被应用程序读取的方式存储在服务器上,那么它至少可以被机器上的 root 读取。

文件是纯文本格式并不重要;它只能受权限保护,root 可以绕过这些权限。加密文件(或它所在的文件系统)只有在加密密钥仅对读取文件的进程可用并且需要外部干预(和验证)时才会有所帮助;您只是将访问秘密的问题转移到其他地方。

即使您保留对系统上所有帐户的控制 - 将其构建为设备,但这仍然会留下对系统进行物理访问的问题。如果您对可以确保物理完整性感到高兴,那么您将面临将系统作为设备维护的问题——如何安装补丁?

我不相信即使在硬件中的 hsm 也能提供完全安全的解决方案,而不是使正常访问过于复杂(虽然也很复杂,但不能防止未经授权的访问)。

鉴于任何解决方案都会对您的期望有所妥协,您需要更具体地了解约束(开发成本、单位成本、预期数量)以及更多关于 thret 模型的细节。