PHP - 如何缓存从 AWS KMS Parameter Store 检索的数据库凭证

Posted

技术标签:

【中文标题】PHP - 如何缓存从 AWS KMS Parameter Store 检索的数据库凭证【英文标题】:PHP - How to cache database credentials retrieved from AWS KMS Parameter Store 【发布时间】:2021-06-29 19:15:27 【问题描述】:

我正在运行一个 php 应用程序,该应用程序使用用户名和密码连接到 RDS 数据库以向客户端提供数据。 使用 AWS SSM 客户端从 AWS KMS 检索用户名和密码作为加密字符串。 我对 PHP 应用程序的每个请求都执行此操作,以打开与数据库的连接。

所以流程看起来像这样

传入请求 -> 从 AWS 检索数据库凭证 -> 打开数据库连接 -> 查询 -> 返回数据

在此流程中,每个请求都会发送到 AWS 以获取数据库凭证,使用 KMS 对安全字符串进行解密,最终结果是 KMS 的高使用率导致更高的账单。 它还会为每个 API 请求引入延迟。

我想知道是否有一些 PHP 缓存库可以用来在 EC2 实例本地安全地存储凭据,这样我就不需要一直获取它。

我阅读了很多论坛,我看到有些人说将它们存储在 root 之外的文件中,甚至 .env 之外的 root 也可以,其他人说使用 memcache,但大多数人们说缓存凭据只是一种不可行的模式。

我知道没有 100% 安全这样的事情,但是任何关于缓存凭据的建议以及用于 PHP 的流行工具是什么,我们将不胜感激。

【问题讨论】:

RDS Proxy的使用怎么样?这样您就不需要为每个新请求都重新连接? 【参考方案1】:

也许您可以将您的凭据存储在快速访问的 Redis 实例中,这样您就不会不断地访问 KMS 和 SSM Parameter Store 服务,但在这种情况下,我建议您在 Redis 中设置一个非常低的 TTL,这样这些凭据可以在短时间内失效,以避免任何安全事件。使用此解决方案,您可以实现一个始终从 redis 请求凭据的 Singlenton 模式,如果您没有这些凭据,则从 SSM 请求它们并临时存储它们以供以后使用。

** redis 实例应与服务器/应用程序具有直接信任关系,以缓解安全事件。

【讨论】:

感谢您的推荐。我尝试了 Redis,它工作得很好。我喜欢缓存数据保留在内存中而不是在任何地方持久化的事实。你能给我一些关于黑客如何访问 Redis 以获取缓存数据的想法/建议吗?我的服务器位于 ALB 后面,不向公众开放。我假设他们需要进入服务器才能访问 Redis,但是如果是这种情况,他们将能够运行 SSM 以获取任何数据吗?所以你会说在我的情况下,Redis 非常安全吗? 您好,例如,如果您的整个解决方案都在 AWS 上,那么一种非常真实的攻击形式是黑客窃取凭证并连接到 AWS 控制台,从该攻击向量黑客无法访问您的 EC2 实例,因为它们不能拥有 .pem 文件,但如果您的 Redis 服务未经过身份验证,它可以创建连接到 Redis 并获取其托管的所有信息的 Lambda / Ec2 服务。我知道这听起来有点偏执,但如果你的解决方案是针对一家大公司的,你就会知道这是经常发生的事情。【参考方案2】:

原来高额费用是由于有太多使用 KMS 进行解密的安全字符串参数造成的。 我将大部分参数转换为普通字符串类型,仅将敏感字符串保留为加密类型,从而整体减少了 KMS 的使用。 在 AWS 文档中,我忽略了它指出“Parameter Store 不收取创建 SecureString 参数的费用,但使用 AWS KMS 加密的费用确实适用” 同样对于缓存库,我发现 phpfastcache 真的很容易使用。不过,我决定暂时保持这种方式,因为 KMS 的定价在 KMS 使用量减少的情况下似乎合理。

【讨论】:

以上是关于PHP - 如何缓存从 AWS KMS Parameter Store 检索的数据库凭证的主要内容,如果未能解决你的问题,请参考以下文章

AWS KMS客户端未返回别名

DynamoDB 如何使用 AWS KMS

使用默认 aws/S3 KMS 密钥对解密对象进行跨账户访问

AWS lambda 和 kms 密钥别名

java AWS中的AWS KMS decryptRequest

使用 Cloudformation 创建 KMS 密钥时出现消息“没有 IAM 权限来处理 AWS::KMS::Key 资源上的标签”