此产品为配合dapr作为项目中秘钥数据存储使用
官方教程地址:https://developer.hashicorp.com/vault/tutorials/getting-started
Vault 带有各种称为秘密引擎和 身份验证方法的可插入组件,允许您与外部系统集成。这些组件的目的是管理和保护您在动态基础设施中的秘密(例如数据库凭证、密码、API 密钥)。
应用服务常常需要存取各种各样的机密信息,比如,数据库的访问凭证,依赖的外部服务的Token
和Key
,服务之间的通信凭证等等。在每个这样的应用中都重复实现机密信息的存取、更新与吊销等管理操作相当繁重,而且容易出问题。HashiCorp公司的开源项目Vault就将这部分工作以独立服务方式来实现,需要机密信息操作的应用可以与Vault服务交互完成相应的操作。
Vault的应用场景非常广泛,如:
Vault架构非常清晰,如下图所示,主要分为三部分:
Secrets Engine
和Auth Method
。Secrets Engine
负责实际机密信息处理功能的实现,各种不同的Secrets Engine
有着不同的功能服务,Auth Method
提供各种不同的身份校验方法。这两个组件都依赖Plugin机制实现,如果官方提供的功能不满足需求,还可以自己写相应Plugin实现特有功能或身份校验方法。
Vault服务部署启动后,处于”密封(sealed
)”状态,此时不能提供服务。在该服务能接受请求前,需要初始化和”解封(unseal
)”两个步骤。
Vault初始化时内部会生成一个加密密钥(Encryption Key
), 这个密钥用于加密数据,对外是不可见的。Vault会再生成一个Master key
来加密Encryption Key
来保护它。Vault会使用Shamir密钥分享算法
将MasterKey
分割成若干份KeyShares
,而根据其中的若干份KeyShares
可以计算出原来的MasterKey
。默认配置的KeyShares
是5
,还原所需要的份数为3
。我们需要记录好所生成的KeyShares
, Vault自身并不保存MasterKey
。当我们忘记KeyShares
后,我们就无法得到MasterKey
, 从而数据也无法解密。
解封(Unseal
)过程就是使用若干份KeyShares
计算得到MasterKey
, 解封之后,Vault就可以通过HTTP API对外提供服务了。
Vault接收到请求后需要先校验身份请求者身份信息,有多种Auth method
可以选择,比如用户名/密码、Github帐号等等。支持的方法可以参考官方文档。身份校验通过后,Vault会根据身份所关联的策略检查该资源请求是否合法。root
策略是内置的策略,它允许访问任何资源。Vault管理用户可以创建更细粒度的资源访问控制策略。除非在策略中明确允许访问某种资源,否则Vault会禁止访问。更深入了解策略可以参考官方文档
身份校验和策略检测都通过后,Vault会给该客户端分配一个Token
。后续的请求都需要携带该token
,类似于WEB访问的cookie
机制。在Vault中,URL路径会关联一个Secrets Engine
。Vault的路由组件会将特定的URL请求路由所关联的Secrets Engine
来处理。
引擎概念:引擎就是存储、加密、解密数据的组件。
简单的引擎组件 kv引擎 不涉及加密解密,只是简单的存储和读取
`transit 引擎 加密存储数据,读取时解密
支持的引擎类型:
- AWS
- Consul
- Cubbyhole
- Database(多种)
- Identity
- Key/Value
- Nomad
- PKI
- RabbitMQ
- SSH
- TOTP
- Transit
Secret 类型
Key-Value:
简单的静态键值对,仅有版本化或非版本化区别,无过期概念
动态生成的凭据:
由Vault根据客户端请求生成
加密密钥:
用于使用客户端数据执行加密功能
这个类型的秘密引擎处理加密,解密,签名等加密功能。所有这些操作都使用Vault内部生成和存储的加密密钥。除非明确告知,否则Vault将永远不会公开给定的加密密钥
目前只有Transit引擎 支持,
可设置策略,指定某个秘钥的权限
设置方式:
创建文件夹 vaultcli 文件夹
创建 docker-compose.yaml 文件
创建config.hcl配置文件
Vault解密脚本.bat 此脚本在每次重启后进行解密使用
vault-UnsealKeys.txt 此内容为Vault解密Key
需要将key复制到此文件中
docker-compose.yaml 文件
x1version"3.8"
2
3services
4
5 vault
6 image vault latest
7 ports
8"8200:8200"
9 volumes
10 ./vault/config:/vault/config
11 ./vault/policies:/vault/policies
12 ./vault/data:/vault/data
13 environment
14 VAULT_ADDR=http://0.0.0.0:8200
15 VAULT_API_ADDR=http://0.0.0.0:8200
16 VAULT_ADDRESS=http://0.0.0.0:8200
17 cap_add
18 IPC_LOCK
19 command vault server -config=config.hcl
20
config.hcl 文件
xxxxxxxxxx
161storage "mysql" {
2 address ="192.165.10.102:3306" #修改本机数据库配置
3 database = "vault"
4 username = "root"
5 password = "sa123"
6}
7listener "tcp" {
8 address = "0.0.0.0:8200"
9 tls_disable = "true"
10}
11
12disable_mlock = true
13default_lease_ttl= "168h",
14max_lease_ttl= "0h",
15api_addr = "http://0.0.0.0:8200"
16ui = true
xxxxxxxxxx
21# cmd 命令 创建容器
2docker-compose up
将显示保管库的日志:
导出 VAULT_ADDR='http://0.0.0.0: 8200 '
根令牌:75de9b20-16fa-5a1e-2e9a-39c86caef504
需要上面的 2 条数据来导出根令牌和主机地址:
xxxxxxxxxx
21export VAULT_TOKEN=75de9b20-16fa-5a1e-2e9a-39c86caef504
2export VAULT_ADDR='http://127.0.0.1:8200'
可访问的Url
web可视化界面 > http://127.0.0.1:8200
查看Vault状态地址 > http://127.0.0.1:8200/v1/sys/seal-status
xxxxxxxxxx
121vault status #查看vault状态
2vault operator unseal <key> #base64位秘钥 输入次数与设置的最低次数一致才能解封,key为初始化生成的
3vault token create -ttl 1m #创建临时token,1分钟失效
4vault secrets list #查询创建的secret引擎
5vault secrets enable kv #创建kv类型的引擎
6vault secrets enable transit #创建transit类型的引擎
7
8vault kv put kv/hello foo=bar dummy=demo #创建名为hello 的kv集合,数据为 foo=bar dummy=demo
9vault kv get kv/hello #读取hello的参数
10vault kv put kv/hello foo=bar dummy=demo2 #同样的key写入不同数据则会产生新的版本
11vault kv get -version=1 kv/hello #设置不同版本读取不同版本的数据
12
xxxxxxxxxx
111mkdir vaultcli #创建文件夹
2kubectl create namespace vault #创建命名空间
3
4#安装vault
5 # 添加 valut 仓库
6helm repo add hashicorp https://helm.releases.hashicorp.com
7# 查看 vault 版本号
8helm search repo hashicorp/vault -l | head
9# 下载某个版本号的 vault
10helm pull hashicorp/vault --version 0.20.1 --untar
11
创建 custom-values.yaml 配置文件
官方配置参数介绍:
https://www.vaultproject.io/docs/platform/k8s/helm/configuration#externalvaultaddr
官方安装配置:
修改配置文件中的数据库地址
storage "mysql" { address = "192.165.10.102:3306" # 修改此处的数据库连接地址 username = "root" # 用户名 password = "sa123" # 密码 database = "vault" # 数据库名称 ha_enabled = "true"
注意:当服务器重启或服务重启,需要重新解密pod,否则无法使用
xxxxxxxxxx
1251#创建配置文件
2vim custom-values.yaml
3
4global
5 # enabled is the master enabled switch. Setting this to true or false
6 # will enable or disable all the components within this chart by default.
7 enabledtrue
8 # TLS for end-to-end encrypted transport
9 tlsDisabletrue
10
11injector
12 # True if you want to enable vault agent injection.
13 enabledtrue
14
15 replicas1
16
17 # If true, will enable a node exporter metrics endpoint at /metrics.
18 metrics
19 enabledfalse
20
21 # Mount Path of the Vault Kubernetes Auth Method.
22 authPath"auth/kubernetes"
23
24 #certs:
25 # # secretName is the name of the secret that has the TLS certificate and
26 # # private key to serve the injector webhook. If this is null, then the
27 # # injector will default to its automatic management mode that will assign
28 # # a service account to the injector to generate its own certificates.
29 # secretName: null
30
31 # # caBundle is a base64-encoded PEM-encoded certificate bundle for the
32 # # CA that signed the TLS certificate that the webhook serves. This must
33 # # be set if secretName is non-null.
34 # caBundle: ""
35
36 # # certName and keyName are the names of the files within the secret for
37 # # the TLS cert and private key, respectively. These have reasonable
38 # # defaults but can be customized if necessary.
39 # certName: tls.crt
40 # keyName: tls.key
41
42server
43 # Resource requests, limits, etc. for the server cluster placement. This
44 # should map directly to the value of the resources field for a PodSpec.
45 # By default no direct resource request is made.
46
47 # Enables a headless service to be used by the Vault Statefulset
48 service
49 enabledtrue
50 # Port on which Vault server is listening
51 port8200
52 # Target port to which the service should be mapped to
53 targetPort8200
54
55
56 # This configures the Vault Statefulset to create a PVC for audit
57 # logs. Once Vault is deployed, initialized and unseal, Vault must
58 # be configured to use this for audit logs. This will be mounted to
59 # /vault/audit
60 # See https://www.vaultproject.io/docs/audit/index.html to know more
61 auditStorage
62 enabledfalse
63
64 # Run Vault in "HA" mode. There are no storage requirements unless audit log
65 # persistence is required. In HA mode Vault will configure itself to use Consul
66 # for its storage backend. The default configuration provided will work the Consul
67 # Helm project by default. It is possible to manually configure Vault to use a
68 # different HA backend.
69 ha
70 enabledtrue
71 replicas3
72
73 # Set the api_addr configuration for Vault HA
74 # See https://www.vaultproject.io/docs/configuration#api_addr
75 # If set to null, this will be set to the Pod IP Address
76 apiAddr null
77
78 # config is a raw string of default configuration when using a Stateful
79 # deployment. Default is to use a Consul for its HA storage backend.
80 # This should be HCL.
81
82 # Note: Configuration files are stored in ConfigMaps so sensitive data
83 # such as passwords should be either mounted through extraSecretEnvironmentVars
84 # or through a Kube secret. For more information see:
85 # https://www.vaultproject.io/docs/platform/k8s/helm/run#protecting-sensitive-vault-configurations
86 config
87 ui = true
88 listener "tcp" {
89 address = "[::]:8200"
90 cluster_address = "[::]:8201"
91 tls_disable = true
92 #tls_cert_file = "/etc/certs/vault.crt"
93 #tls_key_file = "/etc/certs/vault.key"
94 }
95 storage "mysql" {
96 address = "192.165.10.102:3306"
97 username = "root"
98 password = "sa123"
99 database = "vault"
100 ha_enabled = "true"
101 }
102 service_registration "kubernetes" {}
103 # Example configuration for using auto-unseal, using Google Cloud KMS. The
104 # GKMS keys must already exist, and the cluster must have a service account
105 # that is authorized to access GCP KMS.
106 #seal "gcpckms" {
107 # project = "vault-helm-dev-246514"
108 # region = "global"
109 # key_ring = "vault-helm-unseal-kr"
110 # crypto_key = "vault-helm-unseal-key"
111 #}
112# Vault UI
113ui
114 # True if you want to create a Service entry for the Vault UI.
115 #
116 # serviceType can be used to control the type of service created. For
117 # example, setting this to "LoadBalancer" will create an external load
118 # balancer (for supported K8S installations) to access the UI.
119 enabledtrue
120 publishNotReadyAddressestrue
121 # The service should only contain selectors for active Vault pod
122 activeVaultPodOnlyfalse
123 serviceType"NodePort"
124 serviceNodePort null
125 externalPort8200
xxxxxxxxxx
651
2#安装
3helm install vault hashicorp/vault --namespace vault -f custom-values.yaml
4
5#查看状态,会部署三个服务
6
7kubectl get pods -n vault -l app.kubernetes.io/instance=vault
8...
9NAME READY STATUS RESTARTS AGE
10vault-agent-injector-77fbb4d4f8-mwngm 1/1 Running 0 30m
11vault-2 0/1 Running 0 2m24s
12vault-0 0/1 Running 0 2m24s
13vault-1 0/1 Running 0 2m24s
14
15## 当启动后,其中一台或两台服务器padding,需要执行去除污点
16...
17NAME READY STATUS RESTARTS AGE
18vault-agent-injector-77fbb4d4f8-mwngm 1/1 Running 0 30m
19vault-2 0/1 Running 0 2m24s
20vault-0 0/1 Running 0 2m24s
21vault-1 0/1 padding 0 2m24s
22
23## 去除污点
24kubectl taint nodes --all node-role.kubernetes.io/master-
25
26# 初始化
27kubectl exec --stdin=true --tty=true -n vault vault-0 -- vault operator init
28
29# 会显示记录的解密秘钥和token 需要保存下来,登录和解密需要
30...
31Unseal Key 1: mK1PeGrP+A+QidoKzsYIpaAhszwaMCGd0dUMGZ1JWWoQ
32Unseal Key 2: q2bazJZReOhY2yfJmJ8puS2FLF4mpWqlE6umws4M2lwl
33Unseal Key 3: fnpqx2xpAtI4iTU8iTA3uFM5xP/yDqnsPMsDzVTEyqPa
34Unseal Key 4: I2D1KeIA3lIqdlodRL1AeFBmvBoy92mg8kno3QD0mKN0
35Unseal Key 5: cNpXnigDnm/djUED5UE0nhAc3wXrfvIDKWQoVgzn5X5b
36
37Initial Root Token: s.XP91VwITtMaMhiL1JMHzFpSR
38
39#k8s启动三个台服务器,部署了三份,需要解密三次
40## 解密vault-0
41$ kubectl exec --stdin=true --tty=true vault-0 -- vault operator unseal # ... Unseal Key 1
42$ kubectl exec --stdin=true --tty=true vault-0 -- vault operator unseal # ... Unseal Key 2
43$ kubectl exec --stdin=true --tty=true vault-0 -- vault operator unseal # ... Unseal Key 3
44
45## 解密vault-1
46$ kubectl exec --stdin=true --tty=true vault-1 -- vault operator unseal # ... Unseal Key 1
47$ kubectl exec --stdin=true --tty=true vault-1 -- vault operator unseal # ... Unseal Key 2
48$ kubectl exec --stdin=true --tty=true vault-1 -- vault operator unseal # ... Unseal Key 3
49
50## 解密vault-2
51$ kubectl exec --stdin=true --tty=true vault-2 -- vault operator unseal # ... Unseal Key 1
52$ kubectl exec --stdin=true --tty=true vault-2 -- vault operator unseal # ... Unseal Key 2
53$ kubectl exec --stdin=true --tty=true vault-2 -- vault operator unseal # ... Unseal Key 3
54
55
56#查看启动的pod和svc
57kubectl --namespace='vault' get all
58
59...
60service/vault-ui NodePort 10.1.42.143 <none> 8200:30124/TCP 86m
61
62# vault-ui 映射端口 30124
63# 浏览器中输入地址
64# http://192.168.59.128:30124
65# 登录 输入token登录 Initial Root Token
创建的数据,需要根据需要的配置更改
x
201// Path for this secret 秘钥路径 :
2 CacheRedisConfig
3//内容:
4{
5 "RedisConnString": "127.0.0.1:6379",
6 "RedisDefaultDatabase": "2",
7 "RedisPassword": ""
8}
9
10
11
12// Path for this secret 秘钥路径 :
13 commonserver
14//内容:
15{
16 "AllowedHosts": "*",
17 "ConnectionStrings": "Server=localhost;Port=3306;Database=commondb;Uid=root;Pwd=sa123;"
18}
19
20
增加两个文件
unsealSH.sh
解封脚本
vault-UnsealKeys.txt
解封秘钥存储文件
xxxxxxxxxx
141# 创建sh文件
2vim unsealSH.sh
3
4#内容
5
6
7
8for i in `cat vault-UnsealKeys.txt`
9do
10kubectl exec --stdin=true --tty=true vault-0 -- vault operator unseal $i
11kubectl exec --stdin=true --tty=true vault-1 -- vault operator unseal $i
12kubectl exec --stdin=true --tty=true vault-2 -- vault operator unseal $i
13done
14
xxxxxxxxxx
101#创建秘钥存储文件
2vim vault-UnsealKeys.txt
3
4#内容 为Vault生成的token
5yRPXJ7pxw4sP8fkJKyJQvZtyAXKQSzgZUa3bDoM4CQgQ
6sL49v9sUWthlx9YRiSKfOsHu1ItntYOeZYcH4zzwmN2N
7ovqjpsSVy7baLXnSfCdc4hDryBc3kVu1cEPks0tZsHiH
8KXPtacUFe1O3uTJ/9cbE1c4a9bir8KtwY9wN5ZgyjIFH
92iwk+5X08J4vnFKrQt+v7J3e4jxB6sQxSF7ReYy7ool0
10
执行文件命令
xxxxxxxxxx
11sh unsealSH.sh
创建秘钥管理文件
秘钥管理配置官方文档:
https://docs.dapr.io/reference/components-reference/supported-secret-stores/hashicorp-vault/
修改自定义秘钥管理地址和token
- name: vaultAddr value: http://127.0.0.1:8200 #修改为vault地址
- name: vaultToken value : "hvs.n9lOGM7LQXo8JtBogY64RXjA" #vault生成的token
xxxxxxxxxx
361#创建秘钥管理yaml文件
2# vim secretstores.hashicorp.vault.yaml
3
4apiVersion dapr.io/v1alpha1
5kind Component
6metadata
7 name vault-secret-store
8 namespace netapp-demo
9spec
10 type secretstores.hashicorp.vault
11 version v1
12 metadata
13name vaultAddr
14 value http //127.0.0.1 8200 #修改为vault地址
15 #- name: caCert # Optional. This or caPath or caPem
16 # value: "[ca_cert]"
17 #- name: caPath # Optional. This or CaCert or caPem
18 # value: "[path_to_ca_cert_file]"
19 #- name: caPem # Optional. This or CaCert or CaPath
20 # value : "[encoded_ca_cert_pem]"
21name skipVerify # Optional. Default: false
22 value true
23 #- name: tlsServerName # Optional.
24 # value : "[tls_config_server_name]"
25 #- name: vaultTokenMountPath # Required if vaultToken not provided. Path to token file. ~/.vault-token
26 # value : ""
27name vaultToken # Required if vaultTokenMountPath not provided. Token value.
28 value "hvs.n9lOGM7LQXo8JtBogY64RXjA"
29 #- name: vaultKVPrefix # Optional. Default: "dapr"
30 # value : "dapr"
31name vaultKVUsePrefix # Optional. default: "true"
32 valuefalse
33name enginePath # Optional. default: "secret"
34 value"secret"
35name vaultValueType # Optional. default: "map"
36 value"map"
修改redis-storage-class.yaml 配置 从vault读取
xxxxxxxxxx
211apiVersion dapr.io/v1alpha1
2kind Component
3metadata
4 name statestore
5 namespace netapp-demo
6spec
7 type state.redis
8 version v1
9 metadata
10name redisHost
11 secretKeyRef# redis地址
12 name CacheRedisConfig
13 key RedisConnString
14name redisPassword
15 secretKeyRef# redis密码
16 name CacheRedisConfig
17 key RedisPassword
18name actorStateStore
19 value"true"
20auth
21 secretStore vault-secret-store #引用秘钥管理配置源
修改redis-pubsub.yaml配置 从vault读取
xxxxxxxxxx
191apiVersion dapr.io/v1alpha1
2kind Component
3metadata
4 name pubsub
5 namespace netapp-demo
6spec
7 type pubsub.redis
8 version v1
9 metadata
10name redisHost
11 secretKeyRef# redis地址,可修改为其他组件
12 name CacheRedisConfig
13 key RedisConnString
14name redisPassword
15 secretKeyRef# redis地址,可修改为其他组件
16 name CacheRedisConfig
17 key RedisPassword
18auth
19 secretStore vault-secret-store # 引用秘钥管理配置源