我有一个公开 REST API 的应用程序,该 API 需要一些秘密才能启动,例如数据库密码、p12 密钥库密码或 HS512 密钥以用于发布令牌。这些值是从应用程序环境中提取的。我将把应用程序部署到 AWS EC2。我想出了 4 个选项来传递这些值:
- 由于环境变量通过 switch 到
java
命令传递 - 这将非常不方便 - 创建一个 bash 脚本,其中存储在纯文本中的硬编码密码执行
java
命令 - 这将使连接到 EC2 实例的任何人都可以使用它们。 - 与上面相同,但不是以纯文本形式存储秘密,而是使用对称密钥对其进行加密,并让脚本提示它并使用解密的值运行应用程序。
- AWS 秘密管理器——这对于一个简单的 Web 应用程序来说似乎有点过头了,而且还会带来成本。
这样做的正确方法是什么?选项3甚至有意义吗?
选项 1 和 2 - 将任何秘密硬编码或与您的应用程序捆绑在一起绝不是一个好主意。
选项 3 - 好多了,但是您要如何处理解密的值?将它们存储到属性文件中?那么,任何连接到 EC2 的人都可以访问它们。即使您通过环境变量传递秘密
/proc/$PID/environ
,任何有足够权限来打开该文件的人仍然可以读取它们。选项 4 - 虽然它的成本很低(每月 0.40 美元),但它是最好的方法。该应用程序可以直接与Secrets Manager对话以使用EC2 实例角色检索密钥,并且可以使用它们而无需将它们存储在任何中间文件或环境变量中。
问题是任何可以访问实例的人也可以使用相同的 EC2 角色从 SSM 读取 Secret。
底线是 - 不要让任何不受信任的人访问该实例。如果应用程序能够以某种方式获取秘密,那么任何拥有该实例的管理员(root)访问权限的人都可以。几乎没有办法解决它。
有一个选项 5 - 如果您认为与 Secrets Manager 相关的成本太高,请将它们加密存储在 Parameter Store 中。
一切都说我对选项 5 的@MLu 也适用于选项 4。
Secrets Manager 附带了每 X 天自动轮换秘密的选项,这也很有用。
关于该主题的一些链接: