考虑以下Spring Boot应用程序的application.properties文件。
# Spring configuration parameters
spring.application.name=MyApplication
server.port=${SERVICE_PORT:8080}
# SSL Configuration
server.ssl.key-store-type=JKS
server.ssl.key-store=classpath:keystore/keystore.jks
server.ssl.key-store-password=${KEYSTORE_PASSWORD}
server.ssl.key-alias=my-alias
server.ssl.enabled=true
# Security configuration
keycloak.realm = ${AUTHENTICATION_REALM}
keycloak.auth-server-url = https://${AUTHENTICATION_HOST}:${AUTHENTICATION_PORT}/
keycloak.ssl-required = external
keycloak.resource = ${AUTHENTICATION_CLIENT}
keycloak.credentials.secret = ${AUTHENTICATION_SECRET}
keycloak.use-resource-role-mappings = true
keycloak.bearer-only = true
keycloak.truststore=classpath:keystore/cacerts.jks
keycloak.truststore-password=${TRUSTSTORE_PASSWORD}
# Database configuration
spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT:3306}/mydatabase
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASSWORD}
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
从安全角度来看,我正在调查使用HashiCorp Vault安全存储和管理应用程序所需机密的可能性。根据秘密的种类,可以进行以下区分。
SERVICE_PORT
、AUTHENTICATION_REALM
、AUTHENTICATION_HOST
、AUTHENTICATION_PORT
、AUTHENTICATION_CLIENT
、DB_HOST
和DB_PORT
不包含高度敏感的信息,并且可以被认为是不随时间变化的。将这些值作为环境参数存储在docker compose文件中是否被认为是安全和常见的做法KEYSTORE_PASSWORD
、TRUSTSTORE_PASSWORD
和AUTHENTICATION_SECRET
等参数是敏感的,但不会随着时间的推移而(经常)更改,因为更改这些密码需要更改/更新相应的密钥库文件。将这些值存储为关键价值机密有意义吗- 像
DB_USER
和DB_PASSWORD
这样的参数极易被滥用,需要非常小心地处理。由于这些值的性质,我想将它们存储为动态生成的秘密。这也有道理吗
我在网上找到了一系列教程和文章,介绍如何将Vault集成到Spring Boot中。不幸的是,没有一篇文章描述在同一应用程序中使用多个秘密引擎。
- 是否可以在同一个Spring Boot应用程序中使用多个秘密引擎(键值和数据库)?如果是,bootstrap.yml文件应该是什么样子?我正在努力寻找合适的配置
- 什么是最好的方法?让Spring Boot使用
spring-cloud-starter-vault-config
处理机密的检索,或者通过产生应用程序不同Docker容器的某种编排机制处理机密检索。目前,我正在使用docker compose,其中包含Spring所需的所有秘密,这当然是一个非常糟糕的主意
EDIT01
在前面提到的application.properties文件中添加以下配置可以解决KV机密引擎中访问机密的问题。
# Vault Server Configuration
spring.cloud.vault.host=${VAULT_HOST:localhost}
spring.cloud.vault.port=${VAULT_PORT:8200}
spring.cloud.vault.scheme=http
spring.cloud.vault.connection-timeout=5000
spring.cloud.vault.read-timeout=15000
spring.cloud.vault.authentication=TOKEN
spring.cloud.vault.token=${VAULT_TOKEN}
spring.config.import=vault://secrets/my-application, vault://database
# Vault Common Secrets Configuration
spring.cloud.vault.kv.enabled=true
spring.cloud.vault.kv.backend=secrets
为了访问数据库的动态机密,我在pom.xml文件中添加了spring-cloud-starter-vault-config
之外的spring-cloud-vault-config-databases
依赖项,并在application.properties中添加了以下配置
# Vault Database Secrets Configuration
spring.cloud.vault.database.enabled=true
spring.cloud.vault.database.backend=database
spring.cloud.vault.database.role=ROLE_MANAGE_USERS
spring.cloud.vault.database.static-role=false
spring.cloud.vault.database.username-property=DB_USER
spring.cloud.vault.database.password-property=DB_PASSWORD
Vault上的动态秘密引擎的配置已经完成,并且似乎可以工作。我可以使用UI生成凭据,允许我登录MySQL数据库并执行任务。所以我认为那里的一切都是正常的。
Spring Boot应用程序本身无法检索数据库凭据,导致抛出Access denied for user '${DB_USER}'@'172.19.0.1' (using password: YES)
错误消息。
正如我发现的一些教程中所解释的,我也尝试将每个与Vault相关的配置放在bootstrap.properties文件中,但KV机密在这种配置下不再有效。我还试图分别在application.properties和bootstrap.properties中拆分KV和数据库机密,但这似乎也不起作用。。。
我还试图将${}
放在DB_USER
和DB_PASSWORD
周围。不幸的是,没有效果。
显然,配置似乎缺少了一些东西(可能是非常基本的),但我似乎不明白。。。
感谢你阅读我的问题并为我指明正确的方向。
我添加了我的发现作为答案,以供未来参考,其他用户也在努力实现这一点。原来初始配置有一些错误。
首先,我必须删除
spring.datasource.username=${DB_USER}
spring.datasource.password=${DB_PASSWORD}
其次,我不得不替换
spring.cloud.vault.database.username-property=DB_USER
spring.cloud.vault.database.password-property=DB_PASSWORD
带有
spring.cloud.vault.database.username-property=spring.datasource.username
spring.cloud.vault.database.password-property=spring.datasource.password
这会自动将正确的spring.datasource.username
和spring.datasource.password
属性添加到配置中,这样就不必再显式定义它们了。
最后,验证您的Vault配置是否配置了两个机密引擎:一个名为数据库(用于数据库动态机密),另一个名为主机密的(用于静态键值机密)。
secrets秘密引擎应包含与spring.config.import
属性中指定的值同名的秘密(在本例中为vault://secrets/我的应用程序)。该秘密引擎定义了用作KEYSTORE_PASSWORD
、TRUSTSTORE_PASSWORD
和AUTHENTICATION_SECRET
的值。
数据库机密引擎的名称应与属性spring.cloud.vault.database.backend
的值相同(在本例中为数据库)。由于此机密引擎管理数据库的动态机密,因此Vault会按需创建适当的用户名和密码。确保为Vault中的每个数据库配置正确的数据库连接和角色。还要检查负责创建用户名和密码凭据的数据库用户的权限。
关于我帖子中的其他问题:
- 是否可以在同一个Spring Boot应用程序中使用多个秘密引擎(键值和数据库)?如果是bootstrap.yml文件看起来像?我正在努力寻找合适的这样做的配置
=>是的,你可以也不需要bootstrap.yml文件
- 什么是最好的方法?让Spring Boot处理使用
spring-cloud-starter-vault-config
或通过某种产生的编排机制处理秘密检索应用程序的不同Docker容器。目前我正在使用docker由一组环境参数组成,这些参数包含春天需要的秘密,这是一个非常糟糕的主意
=>由于我目前使用的是docker compose,所以我决定让Spring来处理机密的检索。这里肯定还有改进的空间