简体   繁体   English

在 HashiCorp Vault 中安全地存储 Spring Boot 应用程序的秘密?

[英]Securely storing secrets of a Spring Boot application in HashiCorp Vault?

I've read following tutorial: Vault Configuration我已阅读以下教程: Vault Configuration

Ok we installed the Vault server and put 2 pairs of secret properties:好的,我们安装了 Vault 服务器并放置了 2 对秘密属性:

$ 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 application has following properties( bootstrap.properties ): 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

So based on spring.cloud.vault.token application able to read secure properties(name and password) but spring.cloud.vault.token is stored in the insecure place - bootstrap.properties which is stored in the code repository.因此,基于spring.cloud.vault.token应用程序能够读取安全属性(名称和密码),但spring.cloud.vault.token存储在不安全的地方 - bootstrap.properties存储在代码存储库中。 Could you please explain why it is safe?你能解释一下为什么它是安全的吗?

PS聚苯乙烯

As we found out it is insecure.正如我们发现它是不安全的。 How to make it secure ?如何使其安全? I understand that there are might be several solutions to make it secure but single simplified example would be enough for me.我知道可能有几种解决方案可以使其安全,但单个简化示例对我来说就足够了。

Could you please explain why it is safe?你能解释一下为什么它是安全的吗?

The answer is that it is NOT safe ... if you do it that way.答案是它不安全……如果你那样做。 For example, the Spring Vault reference manual says:例如, Spring Vault 参考手册说:

"Consider carefully your security requirements. Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further. Any disclosure to unintended parties allows Vault use with the associated token roles." “请仔细考虑您的安全要求。如果您想快速开始使用 Vault,静态令牌身份验证是可以的,但静态令牌不再受保护。向非预期方的任何披露都允许 Vault 与相关的令牌角色一起使用。”

You should either protect your static tokens, or only grant them access to "secrets" in the vault which you are happy to be widely known.您应该保护您的静态令牌,或者只授予他们访问您很高兴广为人知的保险库中的“秘密”的权限。

Alternatively, have your application use an authenticated method to generate short-term dynamic tokens.或者,让您的应用程序使用经过身份验证的方法来生成短期动态令牌。


As I understand initial problem it is bad to store passwords in an application.properties file on Github.据我所知,最初的问题是将密码存储在 Github 上的 application.properties 文件中是不好的。

And storing a static Vault token in an application.properties file on Github is equally as bad.在 Github 上的 application.properties 文件中存储静态 Vault 令牌同样糟糕。

What is the difference ?有什么不同 ?

There is almost no difference 1 .几乎没有区别1 This is simply the wrong way to use Vault.这只是使用 Vault 的错误方式。


1 - There is a small advantage in that you could invalidate the token if you discover it leaked by accident. 1 - 有一个小优势,如果您发现令牌意外泄漏,您可以使令牌无效。 But this doesn't mean that it is sensible to publish it deliberately.但这并不意味着故意发布它是明智的。


So how do you do things securely?那么你如何安全地做事呢?

First, you MUST secure the machines where the secrets are going to be used.首先,您必须保护将要使用机密的机器。 Even if you are not going to store the actual secrets on disk, you will need to store a different secret (securely) on each of your machines so that they can authenticate themselves to the place where the real secrets are kept.即使您不打算在磁盘上存储实际的机密,您也需要(安全地)在每台机器上存储不同的机密,以便它们可以在保存真正机密的地方进行身份验证。

Here is an example using Chef.这是一个使用 Chef 的示例。

  1. Set up a secure Chef server that holds the configs for your machines;设置一个安全的 Chef 服务器来保存您机器的配置; ie recipes for all of the things that need to be installed, node descriptions to say what recipes to apply, etc.即所有需要安装的东西的配方,节点描述说明应用什么配方等。

  2. When you bootstrap a machine as a node, a keypair is generated for the machine and registered with the Chef server.当您将机器作为节点引导时,会为该机器生成一个密钥对并注册到 Chef 服务器。 The keypair is also held on the machine, and has to be held securely.密钥对也保存在机器上,必须妥善保管。

  3. Then you use the Chef client to run the recipes that install and configure your server.然后使用 Chef 客户端运行安装和配置服务器的方法。

Note that this relies on having a properly secured system to run the Chef server.请注意,这依赖于具有适当安全的系统来运行 Chef 服务器。 It also relies on each of the nodes being sufficiently secure to protect their own keys.它还依赖于每个节点都足够安全来保护自己的密钥。

There are other ways to do this, but nothing will work if you cannot secure your host sufficiently.还有其他方法可以做到这一点,但如果您不能充分保护您的主机,则无济于事。

Storing spring.cloud.vault.token in the application.properties that is checked into VCS (eg Git) might compromise all secrets stored in Vault.spring.cloud.vault.token存储在检入 VCS(例如 Git)的application.properties中可能会危及存储在 Vault 中的所有机密。

The solution is not to store Vault token in application.properties as a plain text.解决方案不是将 Vault 令牌作为纯文本存储在application.properties中。 There are several options.有几种选择。

Remove Vault token from application.propertiesapplication.properties删除 Vault 令牌

Simply remove spring.cloud.vault.token from application.properties and instead provide it via system property -Dspring.cloud.vault.token=00000000-0000-0000-0000-000000000000 (when starting the application) or environment variable SPRING_CLOUD_VAULT_TOKEN .只需从application.properties删除spring.cloud.vault.token ,而是通过系统属性-Dspring.cloud.vault.token=00000000-0000-0000-0000-000000000000 (启动应用程序时)或环境变量SPRING_CLOUD_VAULT_TOKEN提供它。 Environment variable is especially convenient if you use containers (Docker or Kubernetes).如果您使用容器(Docker 或 Kubernetes),环境变量尤其方便。

Store encrypted Vault token in application.properties将加密的 Vault 令牌存储在application.properties

You can keep spring.cloud.vault.token property in application.properties if it is encrypted.如果已加密,您可以将spring.cloud.vault.token属性保留在application.properties

Spring Cloud Config supports decrypting properties with values starting with {cipher} : Spring Cloud Config支持使用以{cipher}开头的值解密属性:

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

To use properties encryption and decryption you will need the following dependencies (example for Gradle):要使用属性加密和解密,您将需要以下依赖项(例如 Gradle):

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

Symmetric encryption对称加密

The simplest way to encrypt the properties is to use symmetric encryption.加密属性的最简单方法是使用对称加密。

Come up with a symmetric key (for example s3cr3t ).提出一个对称密钥(例如s3cr3t )。

To encrypt Vault token you can use Spring Boot CLI with Spring Boot Cloud CLI :要加密 Vault 令牌,您可以将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

Pass the symmetric key to the application in ENCRYPT_KEY environment variable.将对称密钥传递给ENCRYPT_KEY环境变量中的应用程序。

Symmetric encryption key must be never checked into a VCS.绝不能将对称加密密钥签入 VCS。

Asymmetric encryption非对称加密

Consider asymmetric encryption using public and private key pair as a more secure alternative to symmetric encryption.考虑使用公钥和私钥对的非对称加密作为对称加密的更安全替代方案。

Instead of a symmetric encryption key you need to generate a keystore (using the keytool utility that comes with the JDK or openssl ).您需要生成密钥库而不是对称加密密钥(使用 JDK 或openssl附带的keytool实用程序)。

In the bootstrap.properties specify the following properties:bootstrap.properties指定以下属性:

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

The keystore has to be mounted at the location specified in encrypt.keyStore.location and never checked into a VCS.密钥库必须安装在encrypt.keyStore.location指定的位置,并且永远不会签入 VCS。

Also, password that unlocks the keystore better to pass in ENCRYPT_KEYSTORE_PASSWORD environment variable.此外,解锁密钥库的密码最好传入ENCRYPT_KEYSTORE_PASSWORD环境变量。

Read about key management in Spring Cloud Config.阅读 Spring Cloud Config 中的密钥管理

Answering your questions回答您的问题

Could you please explain why it is safe?你能解释一下为什么它是安全的吗?

It is not safe!不安全! Never put a plain secret in source control.永远不要在源代码管理中放置一个简单的秘密。

As we found out it is insecure.正如我们发现它是不安全的。 How to make it secure?如何使其安全?

Some ways to increase security:一些提高安全性的方法:

  • Use environment variables instead of properties file;使用环境变量而不是属性文件;
  • Restrict the access at the network level to the Vault server only to workload servers.将网络级别对 Vault 服务器的访问限制为仅工作负载服务器。 This guarantees that nobody outside that network can exchange the token;这保证了该网络之外的任何人都不能交换令牌;
  • Vault works generating real but temporary credentials each time the token is used.每次使用令牌时,Vault 都会生成真实但临时的凭据。 Reduce the scope of the real credentials to read-only whenever be possible;尽可能将真实凭证的范围缩小为只读;
  • Rotate the token regularly.定期轮换令牌。

Regarding the Spring specifics关于 Spring 的细节

The bootstrap properties should contain only non-critical properties.引导属性应仅包含非关键属性。 For critical properties, you can pass them to the application using environment variables.对于关键属性,您可以使用环境变量将它们传递给应用程序。

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

Summary概括

The question remains "Who guards the keys?"问题仍然是“谁看管钥匙?” . . But the Vault Token serves actually to protect the real sensitive data.但 Vault Token 实际上用于保护真实的敏感数据。 In case the vault token is leaked, you can invalidate just the token.如果保险库令牌泄露,您可以仅使令牌无效。

Improve the constraints from where applications can access the vault server and reduce the scope of the real credentials are additional ways to ensure that only the servers that run the application can exchange the tokens by the real credentials and the real credentials have the minimum privilege as possible.改进应用程序可以访问 vault 服务器的限制并减少真实凭据的范围是确保只有运行应用程序的服务器才能通过真实凭据交换令牌并且真实凭据具有尽可能低的权限的其他方法.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM