最近爆出不少公司代码泄露的新闻,像前不久的Bilibili后端代码被上传到Github,大疆因为前员工泄露公司源代码,致黑客入侵造成百万损失。生产环境代码泄露的危害,一方面是业务逻辑被不怀好意的人分析,容易被找出可利用的漏洞,当然更危险的是如果代码里面有一些明文存储secrets、Token、Api Key等,这些内容被别人拿到,服务就很容易遭到致命的攻击,给我们带来不可估量的损失 。所以合理存储程序中的secrets是十分有必要的。本文接下来简单给大家介绍解决以上问题方法密钥管理服务(Key Management Service,KMS)以及一款开源的密钥管理工具Vault。

一. 密钥管理服务介绍

1.1 什么是密钥管理服务?

密钥管理服务是一款安全管理类服务,使用经过第三方认证的硬件安全模块 HSM(Hardware Security Module) 来生成和保护密钥。帮助用户轻松创建和管理密钥,满足用户多应用多业务的密钥管理需求,符合监管和合规要求。

1.2 具体应用在哪些场景?

1.2.1 账号及密码

网站用户的账号、密码等关键数据,明文存放非常危险,万一泄露或被窃取会产生巨大损失,因此想要使用密钥来对其进行加密存储,使用的时候再对其进行解密。密钥的管理必须是安全的,访问必须经过授权。

1.2.2 SSL证书

目前大部分网站使用HTTPS协议来保障数据传输时的安全,在网站提供HTTPS服务时就需要使用到SSL证书和密钥。若以明文保存在本地 ,攻击者获取SSL证书和密钥后,HTTPS的安全机制就完全失效了。

1.2.3 合规性要求

政策法规要求密钥管理必须符合相关规定,必须确保密钥调用都拥有合理的授权,密钥相关的操作都能够被审计、追溯。

二. Vault密钥管理

Vault是用来安全的存储秘密信息的工具,提供了对Token,密码,证书,API key等的安全存储(key/value)和控制功能。它能处理key的续租、撤销、审计等功能。通过API访问可以获取到加密保存的密码、SSH key、证书等。

2.1 Vault的特性

(1)安全的存储后端

任意的键值对密码都能存储在Vault。Vault在把数据写入存储后端之前会先将数据加密,所以即使你直接读取存储后端数据也无法拿到数据的明文。

(2)动态密码生成

Vault能够按需生成某些后端的密码,例如:AWS、SQL数据库等等。当一个应用需要访问AWS的S3 bucket,应用向Vault请求访问S3 bucket的证书,Vault能按需生成一个指定权限的AWS密钥,并且能够根据租期自动销毁这个密钥。

(3)数据加密

Vault可以在不对数据存储的情况下,对数据进行加密和解密。安全团队只需定义好加密方法,开发将加密后的数据存储在例如SQL之类的后端即可,而无需设计自己的加密方式。

(4)租期和续租

在Vault里面,全部的密码都可以跟租期联系起来。在租期结束时,Vault会自动销毁对应的密码。客户端能够通过Renew-API进行续租。

(5)销毁

Vault本身支持对密码进行销毁,不仅支持销毁单个密码,还支持销毁与之关联的密码。比如指定某个用户读取的全部密码,或者特定类型的密码。销毁功能能够在密码被泄露的时候辅助锁定系统。

2.2 Vault的使用场景

(1)作为集中存储各个服务器账号密码的服务器。

比如数据库密码泄露,正常流程可能是需要先修改密码,首先数据库修改密码,然后通知到应用,应用再做代码上的变更。如果使用Vault的话,数据库只要在Vault上面修改好密码之后通知应用重新从Vault拉取最新密码就行了,类似于实现了加密的配置文件的效果。

(2)为每一个操作单位动态分配账号

当我们想要对某些敏感操作进行审计,但是由于生成账号比较麻烦,所以存在公用账号的情况。Vault支持为某些后端动态生成账号的功能,比如SQL,当某个应用向Vault请求账号密码的时候,Vault能够为每次请求生成一个独一无二的SQL账号密码。

(3) 作为证书服务器

Vault能够作为CA服务器,根据请求信息自动颁发证书。并且提供在线CA和CRL的功能。

(4)作为OAUTH服务器

Vault支持多种认证后端,比如GitHub、Kubernetes、账号密码等。Vault能够将这些账号关联成一个用户,在用户认证之后返回一个Token供其使用。一个系统可能需要访问多个带密码的后端:例如数据库、通过API keys对外部系统进行调用,面向服务的架构通信等等。要将众多系统中的用户和权限对应起来已经非常困难,加上提供密钥滚动功能、安全的存储后端还要有详细的审计日志,自定义解决方案几乎不太可能,所以Vault就出现了。

三. Vault部署与应用

3.1 安装

  • 源码编译安装(需要本机安装Golang和Git环境,具体步可骤参见网上)

    1.源码下载到GOPATH

    $ git clone https://github.com/hashicorp/vault

    2. 进入代码目录,编译(因为编译需要安装相关库,所以需要使用代理)

    $ cd $GOPATH/src/github.com/hashicorp/vault/

    $ make dev
  • 预编译的Vault二进制安装

    1.下载预编译二进制包

    $ wget https://releases.hashicorp.com/Vault/1.1.3/Vault_1.1.3_linux_amd64.zip

    2.解压到环境变量路径

    $ unzip Vault_1.1.3_linux_amd64.zip -d /usr/local/bin 

    这里建议直接使用预编译的二进制包安装,简单快捷。

3.2 服务配置与启动

3.2.1 启动配置文件

编辑配置文件vault.hcl,配置中需要配置存储密钥的数据库相关信息,这里用的MySQL,官网上还支持其他数据库,具体信息参见官方文档:(https://www.vaultproject.io/docs/configuration/storage/index.html)

1 disable_mlock = true

2 ui = true

3 backend "mysql" {

4 address = "192.168.23.225:3306"

5 username = "root"

6 password = "123456"

7 database = "vault-test"

8 table = "vault"

9 }

10 listener "tcp" {

11 address = "0.0.0.0:8200"

12 tls_disable = 1

13 }

14

15 api_addr = "http://192.168.23.225:8200"

3.2.2 启动Vault

1 #启动Vault服务

2

3 vault server -config=vault.hcl

4

5 #设置访问地址设置成http

6

7 export VAULT_ADDR=http://127.0.0.1:8200

3.2.3 初始化Vault

1 vault init -key-shares=5 -key-threshold=3

2

3 # -key-shares:指定密钥的总股数,

4

5 # -key-threshold:指定需要几股可解锁

6

7 # 以上参数为默认,可不设置。

Vault借助Shamir门限秘密共享方案创建主密钥

初始化的Vault会返回5个密钥,根据我们设置的启动参数,正确输入其中的3个密钥就可以解封数据库。Root Token是用作首次访问Vault使用。

 1 Unseal Key 1: O2h1reLoykkEDPVptQ7xr4M6zpSLwexYvRxSbIsRqIRX

2

3 Unseal Key 2: xo5sQSE2MoiUbT4s/9WvmEF18K9HWy2ARwS1wW4VnX2c

4

5 Unseal Key 3: jm6BkWMnZlYGf2R5van32UJdB8nzE6uemyYz4JrsMH/2

6

7 Unseal Key 4: B6qEyjN26sookmCbmh0ZJr/B/4Ik7FdALaFmF4pylDGh

8

9 Unseal Key 5: Zw+JnaM7biiLlA094o2pAIXWrEM37sV7BF9flg8DFe8K

10

11

12

13 Initial Root Token: s.MWnxEObtfY6Knkk8tkDZs5yz

14

15

16

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

18

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

20

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

22

23 before it can start servicing requests.

24

25

26

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

28

29 reconstruct the master key, Vault will remain permanently sealed!

30

31

32

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

34

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

3.2.4 解封Vault

数据初始化的时候获取的5个密钥中的3个对Vault进行解封操作:

1 vault operator unseal

2

3 #分别输入5个中的3个密钥

4

5 Unseal Key (will be hidden):

6

7 Key Value

8

9 --- -----

10

11 Seal Type shamir

12

13 Initialized true

14

15 Sealed true

16

17 Total Shares 5

18

19 Threshold 3

20

21 Unseal Progress 1/3

22

23 Unseal Nonce 4bd56e46-40c1-baf9-ce13-b47386f35d78

24

25 Version 1.1.2

26

27 HA Enabled false

成功解封后,一个可用的Vault服务就启动了。

3.3 创建CA签发引擎

Vault可以使用简单的API调用,实现撤销或颁发新的CA证书,完美解决了手动生成自签名证书的困扰。创建一个CA证书签发引擎步骤如下:

3.3.1 登录Vault

使用Root Token登录Vault

 1 vault login s.MWnxEObtfY6Knkk8tkDZs5yz

2

3

4

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

6

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

8

9 again. Future Vault requests will automatically use this token.

10

11

12

13 Key Value

14

15 --- -----

16

17 token s.MWnxEObtfY6Knkk8tkDZs5yz

18

19 token_accessor kVlLumxoJUyBH7ORZ0oNJgH7

20

21 token_duration ∞

22

23 token_renewable false

24

25 token_policies ["Root"]

26

27 identity_policies []

28

29 policies ["Root"]

3.3.2 创建Root CA

在创建根CA之前,我们需要先在Vault创建一个路径来存放Root CA

1 #创建存放证书路径

2

3 vault secrets enable -path=test -description="MQTT CA" -max-lease-ttl=87600h pki

4

5

6

7 Success! Enabled the pki secrets engine at: test /

8

9 #查看已经创建的引擎

10

11 vault secrets list

Vault中的每个secret引擎都需要定义路径和属性。对于用户来说,secret引擎的行为类似于虚拟文件系统,支持读、写和删除等操作,当然具体取决于使用角色分配给它们的权限。

1 #创建Root CA 填写相关证书信息

2

3 vault write test/Root/generate/internal \

4

5 common_name="test.com" \

6

7 ttl=87600h \

8

9 key_bits=4096

执行成功后会返回certificate就是我们的Root CA。更多的证书申请参数参见官网文档: Vault PKI证书介绍

3.3.3 创建角色

1 #创建role

2

3 vault write test/roles/test_server \

4

5 key_bits=2048 \

6

7 max_ttl=8750h \

8

9 allow_any_name=true

参数的test就是我们刚刚存放Root CA的路径,test_server就是我们创建角色的名称。

3.3.4 签发证书

那么就下来就用刚刚申请的角色签发一个证书。

1 #签发证书

2

3 vault write test/issue/test_server \

4

5 common_name="test.com" \

6

7 ttl=8660h \

8

9 format=pem

因为返回结果比较长,就不在文中贴了。执行成功后,会返回一个我们新签的CA证书,还有我们的Root CA,还有就是新颁发CA的私钥。

当然颁发证书的接口我们也可以通过HTTP接口获得:

定义请求参数 payload.json:

1 {

2

3 "common_name": "iot-sdk.intra.***.com",

4

5 "ttl":"8000h",

6

7 "format":"pem"

8

9 }

使用curl向Vault服务器发起POST请求,X-Vault-Token就是Vault的Root Token:

1 curl --header "X-Vault-Token: s.MWnxEObtfY6Knkk8tkDZs5yz" --request POST --data @payload.json http://192.168.23.225:8200/v1/test/issue/test_server

2

3 {

4 "auth": null,

5 "data": {

6 "certificate": "-----BEGIN CERTIFICATE-----\nMIIEXjdCzwN6h2...\n-----END CERTIFICATE-----",

7 "expiration": 1589711650,

8 "issuing_ca": "-----BEGIN CERTIFICATE-----\nMIIFLDCCAxSgAwI...\n-----END CERTIFICATE-----",

9 "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAA...\n-----END RSA PRIVATE KEY-----",

10 "private_key_type": "rsa",

11 "serial_number": "76:e8:f1:49:91:58:8e:e3:6a:bc:b3:2d:ae:1c:bb:de:0c:27:a0:a6"

12 },

13 "lease_duration": 0,

14 "lease_id": "",

15 "renewable": false,

16 "request_id": "08d5fd69-bc93-5b10-9bc7-94ff47440b3b",

17 "warnings": null,

18 "wrap_info": null

19 }

3.3.5 证书校验

接下来,用Root CA验证一下我们新签发的CA证书:

  1. 将我们的Root CA存储到ca.crt中

  2. 签发CA存储到server.crt中

  3. 使用openssl命令进行校验,返回OK就证明申请的证书校验通过

1 #使用openssl校验证书

2

3 openssl verify -CAfile ca.crt client.crt

4

5 server.crt: OK

综上,一个完整的使用Vault签发CA证书的流程就完成了。

四. 总结

个人觉得Vault是一个非常有用的应用,所以写了这篇介绍的文章分享给大家。当然本文也只是简单介绍了Vault中CA证书引擎的使用方法,它还支持SSH密钥管理、KV加密存储等功能。要发掘Vault的更多信息,请访问其官方网(https://www.vaultproject.io/)。对程序的密钥、Token、用户及密码等合理的加密管理,让我们的服务更安全。

参考链接:

[1]. https://help.aliyun.com/document_detail/28935.html?spm=a2c4g.11186623.6.542.67c4623aXx5oM4

[2]. https://cloud.baidu.com/doc/KMS/ProductDescription/24.5C.E5.BA.94.E7.94.A8.E5.9C.BA.E6.99.AF.html

[3]. Vault-服务器密码/证书管理工具:https://segmentfault.com/a/1190000012959727?utm_source=tag-newest

[4]. https://medium.com/@sufiyanghori/guide-using-hashicorp-vault-to-manage-pki-and-issue-certificates-e1981e7574e

[5]. https://www.vaultproject.io/

声明:本文来自绿盟科技研究通讯,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。