领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多在我之前关于 使用 Vault 管理密钥 的文章中,我向您介绍了 Vault 以及如何使用通用密钥后端存储任意密钥。Vault 不仅可以管理密钥数据,例如 API 密钥、密码和其他敏感的字符串类型数据。今天,我们将了解 Vault 与数据库、服务和证书的集成。
在数据库方面,获取凭据的常规工作流程是请求某个操作员或自助服务工具为您提供凭据,以便您的应用程序可以登录到数据库。此时,凭据被视为静态的。如果数据库迁移或发生安全漏洞,通常会更改凭据。
使用 Spring Cloud Vault,您可以将用户名和密码存储在 Vault 中,而不是您的应用程序配置中。 Spring Config Server 也是一个不错的选择;它允许您在配置存储库中 存储加密的密钥。您的凭据受到保护。
有一个需要注意的地方:长期有效的凭据很容易泄漏。泄漏的凭据可能会授予未经授权的访问。一些数据库对源主机实施限制。在某些情况下,可以将数据库用户限制为一组主机。该限制可以阻止来自其他主机的访问。但是,每个有权访问已授权机器的用户和进程都可以使用泄漏的凭据。但是,您如何发现这种泄漏呢?如果您的数据泄漏到公众或互联网上,您可能会发现泄漏,但情况并非总是如此。在其他情况下,未经授权的方可能会读取或更改您的数据,并且可以肯定的是,泄漏会在相当长的一段时间内未被发现。
让我们使凭据的有效期变短。
Vault 提供了与各种不同系统的集成。其中一些与 PostgreSQL 和 MySQL 集成作为密钥后端。密钥后端可以提供密钥。在这种情况下,密钥后端并不意味着密钥数据存储在 PostgreSQL/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、数据库依赖项 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
)。在生产环境中不要这样做。纯文本使整个密钥故事毫无用处,因为网络上的所有侦听器都可以看到您的密钥。请注意,示例中使用的令牌是根令牌。
您可以使用以下命令创建新令牌:
$ 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();
}
}
然后启动您的应用程序。代码会生成如下输出:
连接使用用户:token-...
Spring Cloud Vault 在启动时获取数据库凭据,并使用默认属性名称存储这些凭据,以便 Spring Boot 可以选择这些凭据。
Vault 支持其他一些集成。我们为我们还在 Spring Boot 中支持的集成构建了支持。
您可以使用以下服务和数据库
您可以在我们的示例存储库中查看完整的示例:https://github.com/mp911de/spring-cloud-vault-config-samples。