使用 HashiCorp Vault 管理機密資訊、動態憑證、加密即服務,保護應用程式敏感資料
專案簡介
HashiCorp Vault 是一個機密管理和資料保護平台。提供安全存取 token、密碼、憑證、加密金鑰等敏感資料的方式,支援動態機密生成和加密即服務。
GitHub Stars: 35K+
核心功能
- 機密儲存 - 安全存放敏感資料
- 動態機密 - 自動生成短期憑證
- 加密服務 - Transit 引擎加解密
- 身份驗證 - 多種認證方式
- 稽核日誌 - 完整操作記錄
快速部署
Docker(開發模式)
1
2
3
4
5
6
7
| docker run -d \
--cap-add=IPC_LOCK \
-e 'VAULT_DEV_ROOT_TOKEN_ID=myroot' \
-e 'VAULT_DEV_LISTEN_ADDRESS=0.0.0.0:8200' \
-p 8200:8200 \
--name vault \
hashicorp/vault
|
Docker Compose(生產模式)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| version: '3.8'
services:
vault:
image: hashicorp/vault
cap_add:
- IPC_LOCK
ports:
- "8200:8200"
environment:
- VAULT_ADDR=http://0.0.0.0:8200
volumes:
- ./vault/config:/vault/config
- vault-data:/vault/data
command: server
volumes:
vault-data:
|
設定檔
1
2
3
4
5
6
7
8
9
10
11
12
13
| # vault/config/config.hcl
ui = true
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 1
}
storage "file" {
path = "/vault/data"
}
api_addr = "http://0.0.0.0:8200"
|
初始化與解封
初始化
1
2
3
4
| export VAULT_ADDR='http://127.0.0.1:8200'
# 初始化(產生 5 把金鑰,需要 3 把解封)
vault operator init -key-shares=5 -key-threshold=3
|
解封
1
2
3
| vault operator unseal <key-1>
vault operator unseal <key-2>
vault operator unseal <key-3>
|
登入
1
| vault login <root-token>
|
KV 機密引擎
啟用 KV v2
1
| vault secrets enable -path=secret kv-v2
|
儲存機密
1
2
3
| vault kv put secret/myapp/config \
username="admin" \
password="s3cr3t"
|
讀取機密
1
2
3
4
5
6
7
| vault kv get secret/myapp/config
# JSON 格式
vault kv get -format=json secret/myapp/config
# 特定欄位
vault kv get -field=password secret/myapp/config
|
版本控制
1
2
3
4
5
6
7
8
| # 列出版本
vault kv metadata get secret/myapp/config
# 讀取舊版本
vault kv get -version=1 secret/myapp/config
# 刪除特定版本
vault kv delete -versions=2 secret/myapp/config
|
動態機密
資料庫機密引擎
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # 啟用引擎
vault secrets enable database
# 設定 MySQL 連線
vault write database/config/mysql-db \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(mysql:3306)/" \
allowed_roles="mysql-role" \
username="vault" \
password="vault-password"
# 建立角色
vault write database/roles/mysql-role \
db_name=mysql-db \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; GRANT SELECT ON mydb.* TO '{{name}}'@'%';" \
default_ttl="1h" \
max_ttl="24h"
# 取得動態憑證
vault read database/creds/mysql-role
|
AWS 機密引擎
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| # 啟用引擎
vault secrets enable aws
# 設定 AWS
vault write aws/config/root \
access_key=AKIAIOSFODNN7EXAMPLE \
secret_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
region=us-east-1
# 建立角色
vault write aws/roles/s3-read \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*"
}
]
}
EOF
# 取得 AWS 憑證
vault read aws/creds/s3-read
|
Transit 加密引擎
啟用引擎
1
| vault secrets enable transit
|
建立加密金鑰
1
| vault write -f transit/keys/my-key
|
加密資料
1
2
3
4
5
6
7
8
9
10
| # 加密(base64 編碼輸入)
vault write transit/encrypt/my-key \
plaintext=$(echo "secret data" | base64)
# 解密
vault write transit/decrypt/my-key \
ciphertext="vault:v1:abc123..."
# 解碼結果
echo "c2VjcmV0IGRhdGE=" | base64 -d
|
身份驗證
Token
1
2
3
4
5
6
7
8
| # 建立 Token
vault token create -policy=my-policy -ttl=1h
# 查看 Token
vault token lookup <token>
# 撤銷 Token
vault token revoke <token>
|
AppRole
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| # 啟用 AppRole
vault auth enable approle
# 建立角色
vault write auth/approle/role/my-app \
token_policies="my-policy" \
token_ttl=1h \
token_max_ttl=4h
# 取得 Role ID
vault read auth/approle/role/my-app/role-id
# 取得 Secret ID
vault write -f auth/approle/role/my-app/secret-id
# 登入
vault write auth/approle/login \
role_id=xxx \
secret_id=yyy
|
Kubernetes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # 啟用 K8s 認證
vault auth enable kubernetes
# 設定
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes:443" \
kubernetes_ca_cert=@ca.crt
# 建立角色
vault write auth/kubernetes/role/my-app \
bound_service_account_names=my-app \
bound_service_account_namespaces=default \
policies=my-policy \
ttl=1h
|
政策管理
建立政策
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # my-policy.hcl
path "secret/data/myapp/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
path "database/creds/mysql-role" {
capabilities = ["read"]
}
path "transit/encrypt/my-key" {
capabilities = ["update"]
}
path "transit/decrypt/my-key" {
capabilities = ["update"]
}
|
1
| vault policy write my-policy my-policy.hcl
|
應用程式整合
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
| import hvac
client = hvac.Client(url='http://localhost:8200', token='myroot')
# 讀取機密
secret = client.secrets.kv.v2.read_secret_version(path='myapp/config')
password = secret['data']['data']['password']
# 寫入機密
client.secrets.kv.v2.create_or_update_secret(
path='myapp/config',
secret={'username': 'admin', 'password': 'new-password'}
)
|
Kubernetes Sidecar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| apiVersion: v1
kind: Pod
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "my-app"
vault.hashicorp.com/agent-inject-secret-config: "secret/data/myapp/config"
spec:
serviceAccountName: my-app
containers:
- name: app
image: my-app
volumeMounts:
- name: vault-secrets
mountPath: /vault/secrets
|
相關連結
延伸閱讀