dschadow/CloudSecurity
GitHub: dschadow/CloudSecurity
基于Spring Cloud Config与HashiCorp Vault的云安全配置管理演示项目,涵盖加密配置、动态凭证和密钥管理等多种安全实践。
Stars: 29 | Forks: 10
# 云安全项目指南
 [](https://codecov.io/gh/dschadow/CloudSecurity) [](https://opensource.org/licenses/Apache-2.0)
## 项目概述
本项目演示了使用 Spring Cloud Config 和 HashiCorp Vault 的云安全实现,包含安全配置管理和机密处理的示例。
## 技术栈
- Java 21
- Spring Boot 3.5
- Spring Cloud 2025
- HashiCorp Vault 1.20
- PostgreSQL 17
- Jasypt 用于加密
- SpringDoc OpenAPI
- Docker 用于容器化
- Maven 用于构建管理
## 项目结构
```
CloudSecurity/
├── config-client/ # Basic config client implementation
├── config-client-vault/ # Vault-integrated config client
├── config-server/ # Basic config server
├── config-server-vault/ # Vault-integrated config server
├── standalone-client/ # Independent client implementation
├── config-repo/ # Configuration repository
└── Docker/ # Container configurations
```
## 架构概览
系统设计采用了多层配置和安全管理:
```
+-------------------------------------------------------------------------+
| Client Applications |
| +----------------+ +-------------------+ +------------------+ |
| | Standalone | | Config Client | | Config Client | |
| | Client | | (Basic) | | (Vault) | |
| | [Jasypt] | | | | | |
| +--------+-------+ +---------+---------+ +--------+---------+ |
| | | | |
| | | | |
+-----------|--------------------+---------------------|--------------------+
| | |
v v v
+-------------------------------------------------------------------------+
| Configuration Layer |
| +----------------+ +-------------------+ +------------------+ |
| | Jasypt | | Config Server | | Config Server | |
| | Encryption | | (Basic) | | (Vault) | |
| | | | | | | |
| +----------------+ +--------+----------+ +--------+---------+ |
| | | |
+------------------------------|-----------------------)--------------------+
| |
v v
+-------------------------------------------------------------------------+
| Security & Storage |
| +----------------+ +-------------------+ +------------------+ |
| | Config Repo | | HashiCorp | | PostgreSQL | |
| | (Git) | | Vault | | Database | |
| | | | | | | |
| +----------------+ +-------------------+ +------------------+ |
| |
+-------------------------------------------------------------------------+
```
架构由三个主要层组成:
1. **客户端应用层**
- 使用 Jasypt 加密的独立客户端
- 使用 Spring Cloud Config 的基础配置客户端
- 用于高级机密管理的启用 Vault 的配置客户端
2. **配置层**
- 用于集中配置的基础配置服务器
- 用于安全机密管理的启用 Vault 的配置服务器
- 用于独立运行的 Jasypt 加密
3. **安全与存储层**
- 基于 Git 的配置仓库
- 用于机密管理和动态凭证的 HashiCorp Vault
- 用于应用数据的 PostgreSQL 数据库
### standalone-client
该独立应用程序使用 [Jasypt for Spring Boot](https://github.com/ulisesbocchio/jasypt-spring-boot) 来保护敏感的配置属性。此演示应用程序展示了加密敏感属性的最简单方法,无需依赖其他服务或系统。你需要提供一个名为 `jasypt.encryptor.password` 的环境变量,其值为 `sample-password`,以便在应用程序启动时解密数据库密码。启动后,`http://localhost:8080` 将显示基本的应用程序信息。
### Spring Cloud Config
所有客户端应用程序都使用 [Spring Cloud Config](https://cloud.spring.io/spring-cloud-config/) 来分离代码和配置,因此在启动实际应用程序之前需要运行中的配置服务器。
#### config-server
本项目包含 Spring Cloud Config 服务器,在使用 **config-client** Web 应用程序之前,必须像 Spring Boot 应用程序一样启动它。使用默认配置文件启动配置服务器后,服务器将在端口 8888 上可用,并将使用我的 GitHub 仓库中 **config-repo** 文件夹中提供的配置文件。因此,在没有配置文件的情况下启动配置服务器需要互联网连接来读取配置文件。
有两种应用程序配置可用:
- 具有 [cipher](http://localhost:8888/config-client/cipher) 配置文件的 **config-client**
- 具有 [plain](http://localhost:8888/config-client/plain) 配置文件的 **config-client**
#### config-client
这个基于 Spring Boot 的 Web 应用程序暴露了 REST 端点 `/`、`/users` 和 `/credentials`。根据活动的 Spring 配置文件,使用的配置文件要么是未加密的(**plain**),要么是使用 Spring Config 加密功能保护的(**cipher**)。没有可用的默认配置文件,因此你必须在启动期间提供特定的配置文件。
##### Profile plain
配置文件完全未受保护,即使是敏感的配置属性也以明文形式存储。
##### Profile cipher
此配置文件使用 Config Server 功能来加密敏感属性。它需要对称或非对称密钥。该示例基于非对称加密,并使用通过以下命令创建的 keystore (`server.jks`):
```
keytool -genkeypair -alias configserver -storetype JKS -keyalg RSA \
-dname "CN=Config Server,OU=Unit,O=Organization,L=City,S=State,C=Germany" \
-keypass secret -keystore server.jks -storepass secret
```
Config Server 端点有助于加密和解密数据:
```
curl http://localhost:8888/encrypt -d secretToEncrypt
curl http://localhost:8888/decrypt -d secretToDecrypt
```
## 构建与运行
1. 构建项目:
mvn clean install
2. 启动基础设施:
cd Docker
docker compose up -d
3. 初始化 Vault:
- 在 http://localhost:8200 打开 Vault UI
- 使用以下 unseal 密钥(5 个中的任意 3 个):
Key 1: ndPiS12Q92PqSdahBL4xFkDSjHTivINXQeC62jUv6tVa
Key 2: 8FpTPAQSFj2j2NyAt1V47iZtBn4g+a3V5hgc6L6ogiw5
Key 3: xRDWjq+0n72AjfC6Zt19Aiw3XCnMBJ424QoKATDROi+F
Key 4: wBEG41KMWWpYbhYwtSl/+0hYOhSNQGhsvH8T1FZiJh4w
Key 5: YJ+WiIAzWDatj3eAiiULjw/BoNF+30DWsrFqs6xnDadR
- 初始 Root Token:`hvs.WzBcwSIguPzLnhfJmPaCIMnK`
4. 按顺序运行应用程序:
- 启动 config-server 或 config-server-vault
- 启动客户端应用程序
## 测试
- 每个模块都有 JUnit 测试
- 运行测试:`mvn test`
- JaCoCo 测试覆盖率报告会自动生成
- 测试报告位置:`target/site/jacoco/index.html`
## 手动 Vault 配置
如果你不想使用已配置的 Vault Docker 容器,可以在下面找到初始化 Vault 所需的所有命令:
```
vault server -config Docker/config/file-storage.hcl
export VAULT_ADDR=http://127.0.0.1:8200
vault operator init
export VAULT_TOKEN=[Root Token]
vault operator unseal [Key 1]
vault operator unseal [Key 2]
vault operator unseal [Key 3]
```
按顺序执行以下命令以启用所需的后端和其他服务并提供所需数据:
```
# 启用 secrets backend
vault secrets enable -path=secret kv-v2
# 为 config-client-vault 应用提供配置数据
vault kv put secret/Config-Client-Vault config.client.vault.application.name="Config Client Vault" config.client.vault.application.profile="vault"
# 导入 policy
vault policy write config-client-policy Docker/policies/config-client-policy.hcl
# 为 config-client-vault 创建 token
vault token create -policy=config-client-policy
# 启用并配置 AppRole 认证
vault auth enable approle
# 创建 TTL 为 24 小时的 roles(可在首次创建后的 48 小时内续订)
vault write auth/approle/role/config-client \
token_ttl=24h \
token_max_ttl=48h \
token_policies=config-client-policy
# 使用返回的 role-id 更新 config-client-vault/application.yml
vault read auth/approle/role/config-client/role-id
# 使用返回的 secret-id 更新 config-client-vault/application.yml
vault write -f auth/approle/role/config-client/secret-id
# 启用 Transit backend 并提供一个 key
vault secrets enable transit
vault write -f transit/keys/symmetric-sample-key
# 启用动态数据库 secrets
vault secrets enable database
# 创建一个 all privileges role
vault write database/roles/config_client_vault_all_privileges \
db_name=config_client_vault \
creation_statements="CREATE ROLE \"{{name}}\" \
WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO \"{{name}}\"; \
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO \"{{name}}\";" \
revocation_statements="ALTER ROLE \"{{name}}\" NOLOGIN;" \
default_ttl="24h" \
max_ttl="48h"
# 创建数据库连接(数据库必须已存在,请使用 "CREATE DATABASE config_client_vault;" 创建)
vault write database/config/config_client_vault \
plugin_name=postgresql-database-plugin \
allowed_roles="*" \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/config_client_vault?sslmode=disable" \
username="postgres" \
password="password"
# 强制 root 用户轮换(这将破坏现有的 root 密码,请确保您有另一个密码)
vault write --force /database/rotate-root/config_client_vault
# 创建新凭证
vault read database/creds/config_client_vault_all_privileges
```
标签:DevSecOps, Docker, HashiCorp Vault, Jasypt, Java 21, Maven, OpenAPI, PostgreSQL, Spring Boot, Spring Cloud, Spring Cloud Config, StruQ, 上游代理, 域名枚举, 安全防御评估, 容器化部署, 微服务安全, 敏感数据保护, 数据加密, 测试用例, 漏洞验证, 请求拦截, 身份认证与访问控制, 配置服务器