为了账号安全,请及时绑定邮箱和手机立即绑定

私密信息管理工具 Vault 快速入门

标签:
安全

什么是 Vault

Vault 是一个基于身份的秘密和加密管理系统。秘密是您想要严格控制访问的任何内容,例如 API 加密密钥、密码和证书。 Vault 提供由身份验证和授权方法控制的加密服务。使用 Vault 的 UI、CLI 或 HTTP API,可以安全地存储和管理、严格控制(限制)和审核对机密和其他敏感数据的访问。

为什么需要 Vault

  • 执行密码轮换策略很痛苦

  • 掌握机密的员工离职后可能泄密或是恶意报复

  • 开发者不小心把机密信息随着代码上传到公网的源码仓库造成泄密

  • 管理多个系统的机密非常麻烦

  • 需要将机密信息安全地加密后存储,但又不想将密钥暴露给应用程序,以防止应用程序被入侵后连带密钥一起泄漏

Vault 架构图

Vault 只暴漏了存储后端(Storage Backend) 和 API,其他部分都被保护起来了。Vault 并不信任后端存储,存放的都是密文。

安装

此处以 Mac 为例,其他平台参考官方文档Vault 安装向导


❯  brew  tap  hashicorp/tap

❯  brew  install  hashicorp/tap/vault

启动 Vault(Dev 模式)


❯  vault  server  -dev

WARNING!  dev  mode  is  enabled!  In  this  mode,  Vault  runs  entirely  in-memory

and  starts  unsealed  with  a  single  unseal  key.  The  root  token  is  already

authenticated  to  the  CLI,  so  you  can  immediately  begin  using  Vault.

  

You  may  need  to  set  the  following  environment  variables:

  

$  export  VAULT_ADDR='http://127.0.0.1:8200'

  

The  unseal  key  and  root  token  are  displayed  below  in  case  you  want  to

seal/unseal  the  Vault  or  re-authenticate.

  

Unseal  Key:  QNqS6xZOnJKsbcz60PThJE2O070F2+9b7LLrGGgI7os=

Root  Token:  hvs.IKbh5pTGI0Qn08G5QNJb4jPY

  

Development  mode  should  NOT  be  used  in  production  installations!

查看服务状态


❯  vault  status

Key  Value

---  -----

Seal  Type  shamir

Initialized  true

Sealed  false

Total  Shares  1

Threshold  1

Version  1.12.1

Build  Date  2022-10-27T12:32:05Z

Storage  Type  inmem

Cluster  Name  vault-cluster-c5c1f8a4

Cluster  ID  60514532-959b-9540-ea21-5d9c968a21ba

HA  Enabled  false

写入第一个密码


❯  vault  write  kv/infini  value=infinilabs

Success!  Data  written  to:  kv/infini

如果报这个错误:

vault write kv/infini value=infinilabs

Error writing data to kv/cheng: Error making API request.

Code: 404. Errors:

  • no handler for route ‘kv/cheng’

是因为 kv 存储没有启动(不同版本默认初始设置不同),执行:


❯  vault  secrets  enable  kv

读取一条数据


❯  vault  read  kv/infini

Key  Value

---  -----

refresh_interval  768h

value  labs

使用 Consul 作为数据存储的 Backend

Vault 自身不存储数据,需要提供存储后台。 支持多种后台。


❯  brew  tap  hashicorp/tap

❯  brew  install  hashicorp/tap/consul

启动 Consul


❯  consul  agent  -dev

==> Starting  Consul  agent...

Version:  '1.14.1'

Build  Date:  '2022-11-21 16:56:07 +0000 UTC'

Node  ID:  '6d9bcfc4-60cf-5d9b-c4fa-764127a94af6'

Node  name:  'ChengKai-MacBook.local'

Datacenter:  'dc1' (Segment: '<all>')

Server:  true (Bootstrap: false)

Client  Addr: [127.0.0.1] (HTTP:  8500,  HTTPS:  -1,  gRPC:  8502,  gRPC-TLS:  8503,  DNS:  8600)

Cluster  Addr:  127.0.0.1 (LAN: 8301,  WAN:  8302)

Gossip  Encryption:  false

Auto-Encrypt-TLS:  false

HTTPS  TLS:  Verify  Incoming:  false,  Verify  Outgoing:  false,  Min  Version:  TLSv1_2

gRPC  TLS:  Verify  Incoming:  false,  Min  Version:  TLSv1_2

Internal  RPC  TLS:  Verify  Incoming:  false,  Verify  Outgoing:  false (Verify Hostname:  false), Min Version: TLSv1_2

  

==> Log  data  will  now  stream  in  as  it  occurs:

  

2022-11-30T16:34:52.604+0800 [WARN] agent: Node name "ChengKai-MacBook.local" will not be discoverable via DNS due to invalid characters. Valid characters include all alpha-numerics and dashes.

2022-11-30T16:34:52.609+0800 [WARN] agent.auto_config: Node name "ChengKai-MacBook.local" will not be discoverable via DNS due to invalid characters. Valid characters include all alpha-numerics and dashes.

2022-11-30T16:34:52.613+0800 [INFO] agent.server.raft: initial configuration: index=1 servers="[{Suffrage:Voter ID:6d9bcfc4-60cf-5d9b-c4fa-764127a94af6 Address:127.0.0.1:8300}]"

2022-11-30T16:34:52.614+0800 [INFO] agent.server.raft: entering follower state: follower="Node at 127.0.0.1:8300 [Follower]" leader-address= leader-id=

启动 Vault(生产模式)

创建配置文件,使用刚刚启动的 Consul 作为存储后台。

注意: 这种方式启动,为生产模式,需要手动配置和管理秘钥。


storage "consul"{

address = "127.0.0.1:8500"

path = "vault/"

}

  

listener "tcp"{

address = "127.0.0.1:8200"

tls_disable = 1

}

执行命令,启动


❯  vault  server  -config=config.hcl

WARNING!  mlock  is  not  supported  on  this  system!  An  mlockall(2)-like  syscall  to

prevent  memory  from  being  swapped  to  disk  is  not  supported  on  this  system.  For

better  security,  only  run  Vault  on  systems  where  this  call  is  supported.  If

you  are  running  Vault  in  a  Docker  container,  provide  the  IPC_LOCK  cap  to  the

container.

==> Vault  server  configuration:

  

Api  Address:  http://127.0.0.1:8200

Cgo:  disabled

Cluster  Address:  https://127.0.0.1:8201

Go  Version:  go1.19.2

Listener  1:  tcp (addr: "127.0.0.1:8200",  cluster  address:  "127.0.0.1:8201",  max_request_duration:  "1m30s",  max_request_size:  "33554432",  tls:  "disabled")

Log  Level:  info

Mlock:  supported:  false,  enabled:  false

Recovery  Mode:  false

Storage:  consul (HA available)

Version:  Vault  v1.12.1,  built  2022-10-27T12:32:05Z

Version  Sha:  e34f8a14fb7a88af4640b09f3ddbb5646b946d9c

  

==> Vault  server  started!  Log  data  will  stream  in  below:

  

2022-11-30T16:42:59.995+0800 [INFO] proxy environment: http_proxy="" https_proxy="" no_proxy=""

2022-11-30T16:43:00.006+0800 [WARN] no `api_addr`  value  specified  in  config  or  in  VAULT_API_ADDR; falling  back  to  detection  if  possible,  but  this  value  should  be  manually  set

注意: 此时虽然服务启动了,但是 Vault 处于封印状态(sealed), 不可用。

此时我们执行操作,会看到如下提示:


❯  vault  read  kv/cheng

Error  reading  kv/cheng:  Error  making  API  request.

  

URL:  GET  http://127.0.0.1:8200/v1/kv/cheng

Code:  503.  Errors:

  

* Vault is sealed

上面 Dev 模式启动的 Vault 实际上帮助我们自动地把创建主密钥、解封的步骤都完成了。生产模式,则需要手动配置后续步骤。

补充点小知识

  • Vault 保存在 Backend 中的数据都是加密的

  • Vault 密钥称为 Master Key 主密钥,Vault 默认使用 Shamir 算法,把主密钥切分成 M 份,管理员必须至少提供其中的 N 份才能还原出主密钥(这里的 M 和 N 都是可配置的,M>=N)理想状态下,我们必须把这 M 份密钥分配给公司内 M 个不同的人,只有在获取其中 N 个人的授权后,Vault 才可以成功解密主密钥。

Vault 初始化(生产模式)

注意看,接下来的步骤,会生成 5 个秘钥,一个 Root 用户的 Token。真实场景下,这 5 个秘钥会分配给 5 个不同的人员管理。 至少正确输入 3 个秘钥,才能解封 Vault。

热知识: Vault 每次启动/重启,都会进入封印状态,未解封时,几乎无法执行任何操作。


> vault operator init

Unseal Key 1: IDcHr5kT7hhgYKiDxF6Qlp2g11UVXNu+f5VX51+3jpeD

Unseal Key 2: dfjqn++KcqLDIDnBcE8B0fIvicI7T9TQCxBSI7b1oE12

Unseal Key 3: DaFtgnYsm0rTQcPpLTPaDTNW338BHhyhezct+ySTT45L

Unseal Key 4: Z1vmlLm/KBydeLrmVf9ELqlJoaUgwzNvzx6ddXttc4Nk

Unseal Key 5: x2lIwJiCz3lNqzBPzkryrnatfZT9mahj3yfW4qxT3eMZ

  

Initial Root Token: s.o7NjzR6qXEvJEwPYpmVFOt4P

  

Vault initialized with 5 key shares and a key threshold of 3. Please securely

distribute the key shares printed above. When the Vault is re-sealed,

restarted, or stopped, you must supply at least 3 of these keys to unseal it

before it can start servicing requests.

  

Vault does not store the generated master key. Without at least 3 keys to

reconstruct the master key, Vault will remain permanently sealed!

  

It is possible to generate new unseal keys, provided you have a quorum of

existing unseal keys shares. See "vault operator rekey" for more information.

Vault 默认访问 https 的地址,所以如果执行初始化报如下错误:

Error authenticating: error looking up token: Get "https://127.0.0.1:8200/v1/auth/token/lookup-self": http: server gave HTTP response to HTTPS client

设置一下 Vault 地址即可,执行:

export VAULT_ADDR=‘http://127.0.0.1:8200

查看 Vault 状态

此时 Vault 处于封印状态(Sealed 为 true)


❯  vault  status

Key  Value

---  -----

Seal  Type  shamir

Initialized  true

Sealed  true

Total  Shares  5

Threshold  3

Unseal  Progress  0/3

Unseal  Nonce  n/a

Version  1.9.2

Storage  Type  consul

HA  Enabled  true

解封 Vault

使用需要 vault operator unseal 命令来执行解封。至少需要 3 个秘钥来解封。


❯  vault  operator  unseal  IDcHr5kT7hhgYKiDxF6Qlp2g11UVXNu+f5VX51+3jpeD

Key  Value

---  -----

Seal  Type  shamir

Initialized  true

Sealed  true

Total  Shares  5

Threshold  3

Unseal  Progress  1/3

Unseal  Nonce  9eeaaa92-d673-51d3-b993-d3affe68b5a3

Version  1.9.2

Storage  Type  consul

HA  Enabled  true

注意: 每次输入一个秘钥,会看到如上提示"Unseal Progress 1/3"。 但是,这里仅仅表示已经输入多少个秘钥,并不代表输入的秘钥都是正确的!!

如何使用 Vault 保存秘密

进入下一步之前,先来看看 Vault 提供了哪些措施,用来保护我们的秘密?

  • 秘钥的保护机制: 秘钥被拆分成 5 份,至少正确输入 3 个才能解封。

  • 策略控制(权限控制): 可以针对每个 Path 设置策略。

  • 有效期: Vault 生成的每个令牌(Token)都有有效期。

开始前,我们先写入 2 条测试数据:


❯  vault  write  kv/infini  value=infinilabs

Success!  Data  written  to:  kv/infini

  

❯  vault  write  kv/ck  value=chengkai

Success!  Data  written  to:  kv/ck

  

热知识:

“kv/infini” 是一个 Path(路径), 可以简单理解为数据库中的一个表。并不是 kv 数据库 当中的 key。你可以试试这样存数据并读取:


❯  vault  write  kv/infini  ck=chengkai  c=cheng  k=kai

Success!  Data  written  to:  kv/infini

  

❯  vault  read  kv/infini

Key  Value

---  -----

refresh_interval  768h

c  cheng

ck  chengkai

k  kai

制定策略

新建策略文件

输入以下内容


path  "kv/infini"  {

capabilities  = ["read"]

}

解释: 以上策略,是指在 infini 这个路径(path)下,具有只读权限。

创建策略

先登录已经解封的 Vault(使用初始化生成的 root token 登录)


❯  vault  login  s.o7NjzR6qXEvJEwPYpmVFOt4P

Success!  You  are  now  authenticated.  The  token  information  displayed  below

is  already  stored  in  the  token  helper.  You  do  NOT  need  to  run  "vault login"

again.  Future  Vault  requests  will  automatically  use  this  token.

  

Key  Value

---  -----

token  s.o7NjzR6qXEvJEwPYpmVFOt4P

token_accessor  tKZyxkkFvrmhQeTsoDOogcoV

token_duration  ∞

token_renewable  false

token_policies ["root"]

identity_policies []

policies ["root"]


❯  vault  policy  write  infini-readonly  policy.hcl

Success!  Uploaded  policy:  infini-readonly

“infini-readonly” 是策略的名称,这个可以自定义

生成 Token 并指定策略

生成对"kv/infini"具有只读权限的 Token, 执行:


❯  vault  token  create  -policy="infini-readonly"

Key  Value

---  -----

token  s.bHzsfREs9MGirYO8yZ2TbAzq

token_accessor  nPuAQzNTn28vMMUKcDu0mN8g

token_duration  768h

token_renewable  true

token_policies ["infini-readonly"  "default"]

identity_policies []

policies ["infini-readonly"  "default"]

此处生成了新的 Token: s.bHzsfREs9MGirYO8yZ2TbAzq, 有效期 768 小时(别拿计算器了,我算过了,32 天)

使用新生成的 Token 登录(别找退出操作了,直接再执行 login 即可):


❯  vault  login  s.bHzsfREs9MGirYO8yZ2TbAzq

Success!  You  are  now  authenticated.  The  token  information  displayed  below

is  already  stored  in  the  token  helper.  You  do  NOT  need  to  run  "vault login"

again.  Future  Vault  requests  will  automatically  use  this  token.

  

Key  Value

---  -----

token  s.bHzsfREs9MGirYO8yZ2TbAzq

token_accessor  nPuAQzNTn28vMMUKcDu0mN8g

token_duration  767h56m19s

token_renewable  true

token_policies ["infini-readonly"  "default"]

identity_policies []

policies ["infini-readonly"  "default"]

验证新生成的 Token

尝试读 kv/infini 的秘密:


❯  vault  read  kv/infini

Key  Value

---  -----

refresh_interval  768h

value  infinilabs

Wow!成功读取!

试试写入操作


❯  vault  write  kv/infini  value=c1

Error  writing  data  to  kv/cheng:  Error  making  API  request.

  

URL:  PUT  http://127.0.0.1:8200/v1/kv/infini

Code:  403.  Errors:

  

* 1 error occurred:

*  permission  denied

有个疑问,你说当前这个 Token,可以读取 kv/ck 的秘密吗?


❯  vault  read  kv/ck

Error  reading  kv/ck:  Error  making  API  request.

  

URL:  GET  http://127.0.0.1:8200/v1/kv/ck

Code:  403.  Errors:

  

* 1 error occurred:

*  permission  denied

啊欧! 不行~

OK, 到这里了,简单的对 Vault 做了个入门。 Vault 的功能点还有很多,去看看下面的文档吧~~

参考文档

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消