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