在 webapp 的数据库中存储加密密码的合理方法,Linux

信息安全 密码 php mysql
2021-08-12 02:29:36

这个问题通常与此处提出的过去问题相似,但我还没有看到与 Linux 相关的问题。

手头的案例:一个 PHP Web 应用程序有一个 MySQL 后端。作为其功能的一部分,它访问其他远程 MySQL 主机并在这些主机上发出一些查询。

为此,PHP 应用程序需要这些远程数据库的凭据。它存储/获取此类凭据的合理方法是什么?

要求应用程序的用户自己不要提供此类凭据。此外,此应用程序可能有数十个用户。

该应用程序的所有用户都通过 LDAP 进行识别。该应用程序和整套 MySQL 服务器位于同一内部网络中(需要两步 VPN 验证)。整个设置在 Linux 机器上运行。

这个问题的合理解决方案是什么?

4个回答

您只需要将配置存储在一个文件中,该文件只能由运行 PHP 的用户访问。您可以阻止 Web 用户访问该文件,但 PHP 必须能够获取凭据,并且无论您做什么,它们都将不受保护。你可以给应用程序提供的任何秘密都可能被发现,因此尝试制作一些复杂的链并没有任何真正的优势。

除了配置文件之外,您还应该确保您的网络服务器使用的 SQL 帐户只能从网络服务器的 IP 使用,并且它只具有网络服务器所需的权限。如果您的网络服务器被黑客入侵,那么他们将获得网络服务器对数据库的访问权限,但如果您的网络服务器被黑客入侵,他们也可以替换脚本以使网络服务器无论如何都可以访问它。

我想你在专用服务器上?如果您在共享主机上,几乎不可能保护 PHP 脚本。

一个合理的方法是将密码存储在一个专用的配置文件中,并限制文件的权限,这样只有所有者才能读取

我希望人们会喊“哦,但他们没有加密”。问题是,您的应用程序需要明文密码才能连接到数据库。因此,如果您对密码进行加密,您还需要有可用的密钥,这与这一点无关。我见过各种疯狂的建议来改进这一点,但他们所做的只是增加了复杂性而没有增加任何有意义的安全性。

另一种解决方案是在您的应用程序中直接实现 ssh 客户端并依赖第三方库(例如JSch )或扩展其中一个ssh/ssh-agent以直接从您的数据库中接收和解密密钥。

*EDIT*

重要的是您试图通过将密钥存储在加密的数据库中来实现。

能够访问临时私钥文件的攻击者也将能够读取 ssh 客户端进程的内存(因此无论如何都可以获取密钥数据),因为这两个数据必须具有基本相同的访问权限 - 尝试隐藏文件似乎并没有使它更安全。

如果您为 db、webapp 和 ssh 连接使用不同的用户,通过将密钥存储在 db 中,在 webapp 中解密并将其提供给 ssh,您只是通过在整个过程中传播密钥来打开潜在的攻击向量。如果您只为所有这些(db、app、ssh)使用一个用户,那么除了代码复杂性之外,您将一无所获。

唯一的优势似乎是更容易将系统转移到不同的主机,并且在 db 数据被盗但 webapp(其中 AFAIU 包含解密算法和密码)不会被盗的情况下获得潜在收益。但这可能吗?

也就是说,如果您想保护密钥,您还可以使用 ssh 对密钥的内部加密,并在启动服务时将它们加载到 ssh-agent 中(记住在停止时将其删除!)。但请再次记住,ssh-agent 将内存中的密钥保持为未加密状态,因此可能会被读取。再说一遍:这是您要解决的问题吗?

如果您只需要保护两台机器之间的通信,stunnel可能比 ssh 提供更好的服务。

关于问题标题的通用答案

有两种方法可以做到这一点。

1. 密码未存储在服务器中

这可能是,但当然,如果没有这个基本密钥,任何事情都无法工作!

在这种情况下,您的应用程序服务器必须在每次启动时询问密码

这需要人工管理员负责在每次发生任何故障和/或维护意味着服务器重新启动时启动服务器。

2. 将密码存储在服务器中。

当然,用于提供网页服务的权限级别与用于管理服务器的权限级别不同!

但这是唯一真正重要的事情。

您可以进行一些加固:使用隐藏文件、图片隐写或其他方式隐藏密码,但这有点没用:

唯一重要的是防止特权升级

一旦坏人在您的服务器中获得高权限,按照引导过程逐步检索服务器用于读取其凭据的方式就像吃一块蛋糕一样容易。

关于在 GNU/Linux 上构建的应用程序的通用答案。

确保在复杂结构化系统上正确存储所有凭据的最简单方法是仅安装带有基本系统的Debian GNU/Linux,而不是首先按照 Debian 文档安装所需的服务器。

全部正确安装后,我会花很多时间浏览所有文档,然后再进行自己的配置。

有一个测试步骤,使它们在我的本地域中运行。

只有当我认为已经充分理解了它的工作原理时,我才能将它放在公共网络上。