关于安全:私密信息管理工具-Vault-快速入门

3次阅读

共计 8958 个字符,预计需要花费 23 分钟才能阅读完成。

什么是 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.

URL: PUT http://127.0.0.1:8200/v1/kv/cheng
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 的性能点还有很多,去看看上面的文档吧~~

参考文档

  • [1]: Vault 官网文档
  • [2]: Vault 教程(中文)
  • [3]: How To Securely Manage Secrets with HashiCorp Vault on Ubuntu 20.04
正文完
 0