抢占先机
VMware 提供培训和认证,助您加速进步。
了解更多在我之前关于使用 Vault 管理秘密的帖子中,我向您介绍了 Vault 以及如何使用通用秘密后端存储任意秘密。Vault 不仅可以管理 API 密钥、密码和其他敏感字符串数据等秘密数据。今天,我们将探讨 Vault 与数据库、服务和证书的集成。
就数据库而言,获取数据库凭据的常规流程是请操作员或自助工具为您提供凭据,以便您的应用程序可以登录数据库。此时,凭据被认为是静态的。凭据通常在数据库迁移或发生安全漏洞时才会更改。
使用Spring Cloud Vault,您可以将用户名和密码存储在 Vault 中,而不是存储在应用程序配置中。Spring Config Server 也是一个不错的选择;它允许您在配置仓库中存储加密的秘密。您的凭据受到保护。
存在一个注意事项:长期存在的凭据很容易被泄露。泄露的凭据可能允许非预期方访问。一些数据库对源主机实施了限制。在某些情况下,数据库用户可以被限制在主机组内。这种限制可以防止从其他主机访问。但是,每个有权访问许可机器的用户和进程仍然可以使用泄露的凭据。那么如何发现这种泄露呢?如果您的数据被泄露到公共领域或互联网上,您可能会发现泄露,但这并非总是如此。在其他情况下,非预期方可能会读取或更改您的数据,并且很确定泄露会在相当长一段时间内不被发现。
让我们将凭据的生命周期缩短。
Vault 提供了与各种系统的多种集成。其中一些集成了PostgreSQL和MySQL作为秘密后端。秘密后端可以提供秘密。在这种情况下,秘密后端并不意味着秘密数据存储在 PosgreSQL/MySQL 中。它意味着 Vault 可以按需为数据库创建(和撤销)用户。
要生成数据库凭据,您首先需要设置一个角色。角色控制数据库凭据生成的权限上下文。角色定义与凭据关联的权限。如果您运行不同的应用程序,并且每个应用程序需要不同的数据库权限,那么这个概念就很有用。角色还定义了获取的凭据的最大租约时间。在 Vault 术语中,租约是凭据有效的持续时间。一旦凭据过期,Vault 就会从数据库系统中撤销它们。某些数据库,例如 PostgreSQL,内置了密码过期支持,使用 CREATE ROLE … VALID UNTIL …
子句。
那么如何开始使用 Vault 和 MySQL 呢?
您需要一个已初始化并解除封印的 Vault 服务器和一个正在运行的 MySQL 服务器。请参阅上一篇帖子了解如何设置 Vault。
然后,您可以设置 MySQL 后端以及连接详情和角色声明。
首先,使用以下命令挂载 mysql
秘密后端:
$ vault mount mysql
Successfully mounted 'mysql' at 'mysql'!
每个挂载对应一个 MySQL 服务器。如果您想为多个服务器生成凭据,则需要使用不同的路径多次挂载后端。
后端挂载后,您需要提供由用户名/密码组合以及主机和端口组成的控制连接详细信息。控制连接用于创建和撤销用户。
$ vault write mysql/config/connection \
connection_url="root:root@tcp(127.0.0.1:3306)/"
Success! Data written to: mysql/config/connection
角色包含用于用户创建和授权的脚本。如果需要,您可以包含多个命令。Vault 将在每次生成凭据时执行这些命令。
$ vault write mysql/roles/readonly \
sql="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';"
Success! Data written to: mysql/roles/readonly
Vault 现在已准备好为 readonly
角色生成凭据。您可以使用以下命令获取凭据:
$ vault read mysql/creds/readonly
Key Value
--- -----
lease_id mysql/creds/readonly/2e7cd1d0-e313-158e-c9a4-1dd3c3277642
lease_duration 2592000
lease_renewable true
password 04cf512a-57f8-d146-9cf5-ec2bd829ca8c
username token-10a8b69f-a
并使用 mysql
控制台应用程序验证它们是否工作:
$ mysql -h 127.0.0.1 -utoken-10a8b69f-a -p04cf512a-57f8-d146-9cf5-ec2bd829ca8c
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
...
现在我们知道我们的 Vault/MySQL 集成正在工作,我们可以在 Spring Boot 应用程序中结合 Spring Cloud Vault 使用它。
获取一个 Spring Boot 项目。start.spring.io 是一个不错的起点。
在您的项目中包含 Spring Cloud Vault Starter、Database 依赖项、spring-jdbc
和 MySQL 驱动程序。将以下代码添加到您的构建配置文件中。这些行包含所有必需的依赖项。
Maven
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-starter-config</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-config-databases</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
Gradle
repositories {
maven {
url 'https://repo.spring.io/libs-snapshot'
}
}
dependencies {
compile("org.springframework.cloud:spring-cloud-vault-starter-config:1.0.0.BUILD-SNAPSHOT")
compile("org.springframework.cloud:spring-cloud-vault-config-databases:1.0.0.BUILD-SNAPSHOT")
compile("org.springframework:spring-jdbc:4.3.1.RELEASE")
compile("mysql:mysql-connector-java:5.1.39")
}
Spring Cloud Vault 默认使用通用秘密后端。在我们的案例中,我们不需要通用后端。因此,我们需要禁用 generic
后端并启用 MySQL 后端。所有配置都需要在引导配置中指定。在本例中,我们使用 src/main/resources
中的 bootstrap.yml
。
spring.cloud.vault:
token: 9a63de21-8af7-311a-9a5a-151b6a0d4795
scheme: http
generic:
enabled: false
mysql:
enabled: true
role: readonly
spring.datasource.url: jdbc:mysql://127.0.0.1:3306
我们没有在配置文件中添加任何数据库凭据。这些通常是 spring.datasource.username
和 spring.datasource.password
。
spring.cloud.vault.scheme
被设置为 http
,因为我们以纯文本 HTTP 模式启动了 Vault(spring.cloud.vault.scheme
默认值为 https
)。生产环境中请勿这样做。纯文本模式会使整个秘密故事变得无用,因为网络上的所有监听者都可以看到您的秘密。请注意,示例中使用的 token 是根 token。
您可以使用以下命令创建新的 token:
$ vault token-create
Key Value
--- -----
token 728d26ae-53a6-d8b6-d7a0-c5f62238ea55
token_accessor 2fd7dcba-39d0-04d3-8d6b-096c3529cf14
token_duration 0
token_renewable true
token_policies [root]
显然,这就是您将 Vault MySQL 集成与 Spring Boot 应用程序所需做的一切。
让我们快速为您的应用程序添加一些代码,以便您可以测试与实际代码的集成。
@SpringBootApplication
public class MySqlApplication {
public static void main(String[] args) {
SpringApplication.run(MySqlApplication.class, args);
}
@Autowired
DataSource dataSource;
@PostConstruct
private void postConstruct() throws Exception {
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("SELECT CURRENT_USER();");
resultSet.next();
System.out.println("Connection works with User: " + resultSet.getString(1));
resultSet.close();
}
}
然后启动您的应用程序。代码会产生如下输出:
与 User: token-... 的连接正常
Spring Cloud Vault 在启动时获取数据库凭据,并使用默认属性名存储它们,以便 Spring Boot 可以获取这些凭据。
Vault 支持其他几种集成。我们已经为我们在 Spring Boot 中支持的集成构建了支持。
您可以使用以下服务和数据库:
您可以在我们的示例仓库中查看完整示例:https://github.com/mp911de/spring-cloud-vault-config-samples。