是否在HashiCorp Vault中安全存储Spring Boot应用程序的机密?

时间:2020-03-17 14:04:21

标签: java spring spring-boot hashicorp-vault spring-cloud-vault-config

我已阅读以下教程:Vault Configuration

好,我们安装了Vault服务器,并放置了两对秘密属性:

$ vault kv put secret/gs-vault-config example.username=demouser example.password=demopassword
$ vault kv put secret/gs-vault-config/cloud example.username=clouduser example.password=cloudpassword

Spring Boot应用程序具有以下属性(bootstrap.properties):

spring.application.name=gs-vault-config
spring.cloud.vault.token=00000000-0000-0000-0000-000000000000
spring.cloud.vault.scheme=http
spring.cloud.vault.kv.enabled=true

因此,基于spring.cloud.vault.token应用程序能够读取安全属性(名称和密码),但是spring.cloud.vault.token存储在不安全的位置-bootstrap.properties,该位置存储在代码存储库中。您能解释一下为什么安全吗?

P.S。

我们发现这是不安全的。如何使其安全?我知道可能有几种解决方案可以确保它的安全性,但是一个简单的示例对我来说就足够了。

3 个答案:

答案 0 :(得分:3)

您能解释一下为什么安全吗?

答案是,这是不安全的……如果您这样做的话。例如,Spring Vault reference manual说:

“请仔细考虑您的安全要求。如果您想快速开始使用Vault,可以使用静态令牌身份验证,但是静态令牌不会受到任何进一步的保护。向非预期方的任何披露都可以使Vault与相关的令牌角色一起使用。”

您应该保护您的静态令牌,或者只授予它们访问您很高兴为人们所熟知的文件库中“秘密”的权限。

或者,让您的应用程序使用authenticated method来生成短期动态令牌。


据我了解,最初的问题很难将密码存储在Github上的application.properties文件中。

将静态Vault令牌存储在Github上的application.properties文件中同样糟糕。

有什么区别?

几乎没有区别 1 。这只是使用保险柜的错误方法。


1-有一个小的好处,就是如果发现令牌意外泄漏,可以使令牌无效。但这并不意味着故意发布它是明智的。


那您如何安全地做事?

首先,您必须保护要使用机密的计算机。即使您不打算将实际机密存储在磁盘上,也需要在每个计算机上(安全地)存储一个不同的机密,以便它们可以向保存真实机密的位置进行身份验证。

这里是使用Chef的示例。

  1. 设置一个安全的Chef服务器,该服务器保存您计算机的配置;即所有需要安装的东西的食谱,说明要应用的食谱的节点描述等。

  2. 当引导计算机作为节点时,将为该计算机生成一个密钥对,并在Chef服务器中注册。密钥对也保存在计算机上,必须安全保存。

  3. 然后,您使用Chef客户端运行用于安装和配置服务器的配方。

请注意,这依赖于具有适当安全性的系统来运行Chef服务器。它还依赖于每个节点的足够安全性来保护自己的密钥。

还有其他方法可以执行此操作,但是如果您不能充分保护主机,则将无法进行任何操作。

答案 1 :(得分:1)

spring.cloud.vault.token存储在已签入VCS的application.properties中(例如Git)可能会损害存储在保险柜中的所有机密信息。

解决方案不是将保险柜令牌以纯文本形式存储在application.properties中。有几种选择。

application.properties删除保险柜令牌

只需从spring.cloud.vault.token中删除application.properties,而是通过系统属性-Dspring.cloud.vault.token=00000000-0000-0000-0000-000000000000(启动应用程序时)或环境变量SPRING_CLOUD_VAULT_TOKEN来提供它。如果使用容器(Docker或Kubernetes),则环境变量特别方便。

将加密的保险柜令牌存储在application.properties

如果spring.cloud.vault.token属性是经过加密的,则可以将其保留在application.properties中。

Spring Cloud Config支持使用以{cipher}开头的值解密属性:

spring.cloud.vault.token={cipher}encrypted_vault_token

要使用属性加密和解密,您将需要以下依赖项(例如Gradle):

implementation 'org.springframework.cloud:spring-cloud-context:2.2.2.RELEASE'
implementation 'org.bouncycastle:bcprov-jdk15on:1.64'

对称加密

加密属性的最简单方法是使用对称加密。

使用对称密钥(例如s3cr3t)来访问。

要加密保险柜令牌,您可以将Spring Boot CLISpring Boot Cloud CLI结合使用:

curl "https://repo.spring.io/release/org/springframework/boot/spring-boot-cli/2.2.2.RELEASE/spring-boot-cli-2.2.2.RELEASE-bin.tar.gz" -o spring-boot-cli-bin.tar.gz
tar -xf spring-boot-cli-bin.tar.gz
cd spring-2.2.2.RELEASE
bin/spring install org.springframework.cloud:spring-cloud-cli:2.2.1.RELEASE

bin/spring encrypt 00000000-0000-0000-0000-000000000000 --key s3cr3t
# 507cd1614682535ab8237b448ca73dc74058d3ae9145d63a7381ee67f3046eb1598da6960abdbf2dbf22c47206db5222e45fc74fd6122bc707b61c62f5051e0f

bin/spring decrypt 507cd1614682535ab8237b448ca73dc74058d3ae9145d63a7381ee67f3046eb1598da6960abdbf2dbf22c47206db5222e45fc74fd6122bc707b61c62f5051e0f --key s3cr3t
# 00000000-0000-0000-0000-000000000000

ENCRYPT_KEY环境变量中将对称密钥传递给应用程序。

绝对不要将对称加密密钥检入VCS。

非对称加密

考虑使用公钥和私钥对进行非对称加密,作为对称加密的一种更安全的替代方法。

您需要生成密钥库(而不是对称加密密钥)(使用JDK或keytool附带的openssl实用程序)。

bootstrap.properties中指定以下属性:

  • encrypt.keyStore.location
  • encrypt.keyStore.password
  • encrypt.keyStore.alias
  • encrypt.keyStore.type

密钥库必须安装在encrypt.keyStore.location中指定的位置,并且永远不要签入VCS。

此外,解锁密钥存储区的密码最好在ENCRYPT_KEYSTORE_PASSWORD环境变量中传递。

在Spring Cloud Config中了解key management

答案 2 :(得分:0)

回答您的问题

您能解释一下为什么安全吗?

这不安全!切勿在源代码管理中添加明确的秘密。

我们发现这是不安全的。如何使其安全?

一些提高安全性的方法:

  • 使用环境变量代替属性文件;
  • 在网络级别上仅对工作负载服务器限制对Vault服务器的访问。这样可以保证该网络之外的任何人都不能交换令牌;
  • 每次使用令牌时,Vault都会生成真实但临时的凭证。尽可能将真实凭据的范围缩小为只读;
  • 定期旋转令牌。

关于春季的细节

引导程序属性应仅包含非关键属性。对于关键属性,您可以使用环境变量将它们传递给应用程序。

spring.cloud.vault.token = ${SPRING_CLOUD_VAULT_TOKEN}

摘要

问题仍然是 “谁来保护钥匙?” 。但是保管库令牌实际上是用来保护真正的敏感数据。万一保管库令牌泄漏,您可以仅使令牌失效。

改善应用程序可以访问Vault服务器的限制并减小真实凭证的范围是确保仅运行应用程序的服务器可以通过真实凭证交换令牌并且真实凭证具有最小限度的其他方式尽可能的特权。