Spring Data 从保险库或其他受保护的源读取 MongoDB 密码

Tho*_*mas 3 java security credentials spring-data-mongodb spring-boot

目前,我的 spring-boot 应用程序无需凭据即可连接到本地 MongoDB。为了能够在客户处安装它,我需要提供使用用户名和密码进行数据库连接的功能。我正在使用 application.properties 文件,该文件当前仅包含与数据库相关的这 3 行:

spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=myApp
Run Code Online (Sandbox Code Playgroud)

还有另外两个:

spring.data.mongodb.username
spring.data.mongodb.password
Run Code Online (Sandbox Code Playgroud)

但当然,我不想在这个文件中使用纯文本形式的密码,或者更糟糕的是在我们的 git 中。一种选择是将它们作为启动脚本的参数提供,但它又可以在流程详细信息中作为纯文本读取。

我已经使用Jasypt在属性文件中看到了一些加密,但我不明白这种方法在我的情况下如何工作。我从未明确使用这些属性,因为它们是由 spring 自动获取来进行连接的。

最安全的方法是什么?

mp9*_*1de 7

TL; DR

\n\n

这取决于您的安全/风险状况,哪种方法是可以接受的。

\n\n

读的时间越长

\n\n

您的问题是:最安全的方法是什么?

\n\n

这个问题的一个简单答案是不在任何地方存储密码,而是让操作员输入密码。显然,这不是您正在寻找的答案,就像数据中心的服务器甚至云中的虚拟机一样这种方法不可行。

\n\n

要了解哪种方法足够安全以及哪种方法可以接受,重要的是要了解您的组织背景、其接受风险的意愿以及由此产生的后果,这是处理机密的要求。此评估可能会导致,对于一个组织来说,以纯文本形式存储凭据可能是很好的(因为环境是安全的或者与暴露的秘密相关的威胁较低),而其他组织则需要通过适当的密钥管理和审核进行加密。

\n\n

您已经描述过在 Git 中存储凭据不是正确的选择。所以我假设您正在寻找一种以某种方式保护实际秘密的方法。保护可以发生在不同的层面上:

\n\n
    \n
  • 将机密存储在受保护的位置并应用访问控制\n\n
      \n
    • 受访问保护的主机上的环境变量
    • \n
    • 受权限保护的访问控制文件
    • \n
  • \n
  • 以加密形式存储机密\n\n
      \n
    • 加密该值并将其存储在文件中。这里你需要考虑谁有权访问这个文件以及密钥管理如何。引入了先有鸡还是先有蛋的问题
    • \n
    • 加密该值并将其存储在内存中。尽管如此,您仍然需要解决密钥管理问题。
    • \n
  • \n
  • 正在从受信任的来源检索机密\n\n
      \n
    • 凭证由操作人员输入(不太可行)
    • \n
    • 请求服务机构为您提供凭证。远程服务保护秘密并允许您/您的应用程序询问秘密。
    • \n
  • \n
\n\n

可能还有更多的可能性,但我们现在就先讨论这些。与上述可能性相关联的一方面是将凭证从源传输到目标目的地。传输通常跨越一对多的参与方,并且每一方都需要以某种方式受到信任(即,您必须确保某一方不会泄露您的凭据)。这种模式也称为信任链。如果信任链中的每一跳都是已知的,不会暴露您的凭据,那么您可以对此上下文使用特定的保护模式做出反应。如果您发现一个薄弱的链接会增加暴露的风险(例如公共文件夹、操作员的查找),那么您再次需要根据您的需要提高保护级别。

\n\n

话虽如此,让我们看看 Spring Boot 可以应用哪些秘密保护:

\n\n

环境变量

\n\n

您可以使用环境变量或系统属性来存储配置。易失性方面与持久性(例如,基于文件的)存储不同。可以在应用程序启动之前/启动时设置变量。

\n\n

环境变量示例:

\n\n
export SPRING_DATA_MONGODB_USERNAME=\xe2\x80\xa6\nexport SPRING_DATA_MONGODB_PASSWORD=\xe2\x80\xa6\n\njava -jar my-app.jar\n
Run Code Online (Sandbox Code Playgroud)\n\n

系统属性示例:

\n\n
java -jar my-app.jar -Dspring.data.mongodb.username=\xe2\x80\xa6 -Dspring.data.mongodb.password=\xe2\x80\xa6\njava -jar my-app.jar --spring.data.mongodb.username=\xe2\x80\xa6 --spring.data.mongodb.password=\xe2\x80\xa6\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,环境变量/命令行可以由/proc文件系统和工具进行内省,例如ps

\n\n

有关更多详细信息,请参阅有关外部化配置的参考文档。

\n\n

加密的配置属性

\n\n

Spring Cloud 为各个属性提供了加密支持。您可以使用不同的密钥和密钥类型(对称、非对称)加密选定的属性。此方法允许您选择应加密的属性,而无需加密整个文件。

\n\n

环境变量示例:

\n\n

应用程序属性

\n\n
spring.data.mongodb.password={cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,此方法引入了财产密钥管理的要求。

\n\n

有关更多详细信息,请参阅Spring Cloud Config 加密和解密的参考文档。

\n\n

应用程序控制的秘密

\n\n

Spring Boot 中的配置属性是从 s 获取Environment并提供的PropertySource。您可以贡献财产或整个PropertySource在启动 Spring Boot 之前,

\n\n

添加示例PropertySource

\n\n
SpringApplication app = new SpringApplication(DemoApplication.class);\napp.addInitializers(new ApplicationContextInitializer<ConfigurableApplicationContext>() {\n    @Override\n    public void initialize(ConfigurableApplicationContext applicationContext) {\n        applicationContext.getEnvironment().getPropertySources().addFirst(\xe2\x80\xa6);\n    }\n});\n\napp.run(args);\n
Run Code Online (Sandbox Code Playgroud)\n\n

添加属性的示例:

\n\n
SpringApplication app = new SpringApplication(DemoApplication.class);\napp.setDefaultProperties(Collections.singletonMap("spring.data.mongodb.password", "\xe2\x80\xa6"));\n\napp.run(args);\n
Run Code Online (Sandbox Code Playgroud)\n\n

远程配置属性

\n\n

Spring Cloud Config 允许您集中由 Spring Cloud Config Server 提供的配置。属性不再存储在本地,而是由配置服务提供,该服务的保护方式与应用程序保护级别不同。要设置 Spring Cloud Config Server,您需要额外的服务并将客户端依赖项集成到您的应用程序中。

\n\n

请注意,这种方法并不能解决整体问题,而只是将其转移给其他人的责任。

\n\n

有关更多详细信息,请参阅Spring Cloud Config Server上的参考文档。

\n\n

使用机密管理

\n\n

如果您能负担得起 Secrets Management,例如 HashiCorp Vault、CredHub、Azure KeyVault、Kubernetes Secrets,那么您可以利用平台/Secrets Management 系统的功能对您的凭据应用保护。

\n\n

秘密管理系统通常为您处理加密、审核和访问控制。这些系统保留凭证的加密副本。一旦您请求凭证(通常通过 TLS 安全连接),系统就会检查您/您的应用程序是否被允许访问该机密。

\n\n

其中一些系统还提供动态秘密。根据需要为特定应用程序实例生成动态秘密。如果您的应用程序想要连接到 MongoDB,机密管理系统将创建一个凭证对并将其服务器到您的应用程序。当您的应用程序停止时,机密管理系统将撤销凭据。

\n\n

有关更多详细信息,请参阅Spring Cloud Vault的参考文档。

\n