密码即服务-初探vault

欢迎关注微信公众号 singless

1 介绍

https://www.vaultproject.io/
https://lonegunmanb.github.io/essential-vault/

简单来说,在我们日常的工作中,免不了要和许多的机密信息打交道,可以是云服务的 Access Key 和 Secret Key,也可以是生产服务器的证书、SSH 口令、证书,或者数据库的用户名密码。以往在工作中我们经常面临着这样的问题:

  • 执行密码轮换策略很痛苦
  • 掌握机密的员工离职后可能泄密或是恶意报复
  • 开发者不小心把机密信息随着代码上传到公网的源码仓库造成泄密
  • 管理多个系统的机密非常麻烦
  • 需要将机密信息安全地加密后存储,但又不想将密钥暴露给应用程序,以防止应用程序被入侵后连带密钥一起泄漏

Vault 就是用来解决这些问题的利器。

生产环境推荐的Vault架构如下

HashiCorp 推荐使用 Consul 作为 Vault 的数据存储 Backend(推荐但并不强制,Vault 支持丰富的数据存储 Backend)。本文使用consul作为vault的后端存储。

2 安装vault

笔者服务器为Ubuntu,其他系统请参考以下链接进行安装

https://developer.hashicorp.com/vault/downloads?product_intent=vault

root@ceph-4:~# wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
root@ceph-4:~# echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
root@ceph-4:~# sudo apt update && sudo apt install vault
root@ceph-4:~# vault version
Vault v1.15.0 (b4d07277a6c5318bb50d3b94bbd6135dccb4c601), built 2023-09-22T16:53:10Z

3 启动consul

以dev方式启动一个consul

root@ceph-4:~# sudo apt update && sudo apt install consul
root@ceph-4:~# consul agent -dev

4 vault操作

4.1 启动vault

创建vault的配置文件,指定后端存储为consul,数据存储路径为vault/,同时指定vault的端口为8200,并禁用tls

root@ceph-4:~# cat /root/config.hcl  
storage "consul"{
address = "127.0.0.1:8500"
path    = "vault/"
}

listener "tcp"{
address     = "127.0.0.1:8200"
tls_disable = 1
}
root@ceph-4:~# vault server -config=/root/config.hcl ##启动vault服务

vault保存在Backend中的数据都是加密的。需要用密钥进行解密,这个密钥在vault中称为master key,master key需要手动创建。vault会使用shamir算法将master key切分成M份shared key,管理员需要至少提供其中N份shared key才能还原出master key(M和N都可配置,M≥N)。

Vault 刚启动时由于无法解密主密钥,所以处于 Seal 封印状态,这时 Vault 是无法进行任何操作的。解密主密钥的过程称为 Unseal 解封。在未解封(unseal)时,Vault 几乎无法执行任何操作。比方身份认证、管理挂载表等等,都无法执行。唯一可以执行的操作就是解封并检查封印状态。

4.2 生成key

root@ceph-4:~# vault operator init -address='http://127.0.0.1:8200'

执行上面的命令可以生成master key,默认master key会被分成5份,其中的任意3份可以组合成master key。root token是用来登录vault的账户,拥有最高的权限。这些key都需要自己保存好,vault并不会保存这些信息。

4.3 查看vault的状态

root@ceph-4:~# vault status -address='http://127.0.0.1:8200'

从图中我们可以看到,vault处于seal状态,且seal使用的是shamir算法,总共的shared key(unseal key)数量是5,threshold表示当有3把shared key时,可以解封vault,"unseal progress"代表我们当前提供了多少把shared key。

4.4 解封和封印vault

我们提供之前生成的三个shared key用于解封

root@ceph-4:~# vault operator unseal -address='http://127.0.0.1:8200' /glIbUIEG7/5IBc+OVVczoBiKocYBCb44F0cmz9mH8/E
root@ceph-4:~# vault operator unseal -address='http://127.0.0.1:8200' VIWROv3z+yLn/jbURZ/EhKMLYoEI7hvR9Rvvv2lP+udy
root@ceph-4:~# vault operator unseal -address='http://127.0.0.1:8200' 71DTfw9gZUAVSTlY6i3V9k1SYtyJQ6dNfZwox0NHc8SF

可以看到,在提供key时,unseal progress的数量一直在增加,当我们提供3个key 后,vault的sealed变为false状态,解封成功。

如果觉得系统存在风险,可以使用root token登录vault,执行以下命令将vault重新封印

root@ceph-4:~# vault operator seal -address='http://127.0.0.1:8200'

4.5 登录vault

root@ceph-4:~# vault login -address='http://127.0.0.1:8200' hvs.EjKzWarVoX2yQOQkNTrO3RCd

4.6 重建root token

如果root token泄露或root token不甚丢失,可以使用本节的方法重建root token。重建 Root 令牌有两种办法,分别是一次性密码(one time password)简称OPT,以及 pgp。本次使用OPT方式重建。

root@ceph-4:~# export VAULT_ADDR=http://127.0.0.1:8200  ##为了不用每次都输入一个-address参数,我们定义一个VAULT_ADDR的变量
root@ceph-4:~# vault operator generate-root -init  ##生成OPT密码,这个密码我们需要记住,后面需要用到

下面来重新生成root token,会提示我们输入shared key,因为我们默认是需要三个shared key来生成master key,所以命令需要执行三次。最后一次命令执行时,会生成一个encoded token,我们使用otp可以将它解码为root token

root@ceph-4:~# vault operator generate-root

解码root token

root@ceph-4:~# vault operator generate-root -decode=MDtATTsEGC4ZDzQPORIYVzIHIz8wCGYLGjkODA -otp=XM3cMjJcIjSzxWo6CFuMGk0CjhbY  ##使用这个就可以重新生成root token了
hvs.vnRMPeguAEwaqAVrwcVHpQlU

5 配置使用一次性密码登录SSH

5.1 原理介绍

实现原理图如下

我们需要在被登录的服务器上配置 vault-ssh-helper 程序,它可以取代 Linux 默认的登录验证程序,在用户传递了登录用户名密码后,转而向 Vault 服务器请求验证用户名密码的正确性。用户首先登录 Vault,通过 Vault 创建一个属于目标服务器的 otp,随后远程连接目标服务器,给出这组 otp,在 vault-ssh-helper 验证通过后成功登录,同时 Vault 服务器会在成功验证后删除这个 otp,确保密码的确是一次性的。

5.2 安装vault-ssh-helper

https://github.com/hashicorp/vault-ssh-helper

root@ceph-4:~# wget https://releases.hashicorp.com/vault-ssh-helper/0.2.1/vault-ssh-helper_0.2.1_linux_amd64.zip
root@ceph-4:~# unzip vault-ssh-helper_0.2.1_linux_amd64.zip
root@ceph-4:~# mv vault-ssh-helper /usr/bin/
root@ceph-4:~# vault-ssh-helper -version
vault-ssh-helper v0.2.1

创建配置文件

root@ceph-4:~# mkdir /etc/vault-ssh-helper.d/
root@ceph-4:~# cat /etc/vault-ssh-helper.d/config.hcl
vault_addr = "<VAULT_ADDRESS>"
ssh_mount_point = "ssh"
tls_skip_verify = true
allowed_roles = "*"

5.3 sshd配置

编辑/etc/pam.d/sshd文件

root@ceph-4:~# vim /etc/pam.d/sshd

注释@include common-account一行并加上两行auth

auth requisite pam_exec.so quiet expose_authtok log=/tmp/vaultssh.log /usr/local/bin/vault-ssh-helper -dev -config=/etc/vault-ssh-helper.d/config.hcl
auth optional pam_unix.so not_set_pass use_first_pass nodelay

检查ssh配置中以下三个值的配置是否正确

root@ceph-4:~# grep -E "ChallengeResponseAuthentication|PasswordAuthentication|UsePAM" /etc/ssh/sshd_config |grep -v "^#"
PasswordAuthentication no
ChallengeResponseAuthentication yes
UsePAM yes

重启ssh服务

root@ceph-4:~# systemctl restart sshd

5.4 vault服务配置

启动vault服务

root@ceph-4:~# cat /root/config.hcl
storage "consul" {
  address = "127.0.0.1:8500"
  path    = "vault/"
}

listener "tcp" {
 address     = "192.168.85.151:8200"  ##填写本机ip地址
 tls_disable = 1
}

listener "tcp" {
 address     = "127.0.0.1:8200"
 tls_disable = 1
}
root@ceph-4:~#
root@ceph-4:~# vault server -config=/root/config.hcl

参考第四节解封vault并用root token登录vault,shared key和root token可以使用之前的

登录后启用ssh模块

root@ceph-4:~# vault secrets enable ssh
Success! Enabled the ssh secrets engine at: ssh/

然后我们写入一条角色,允许使用 otp 登录 ssh

root@ceph-4:~# vault write ssh/roles/otp_key_role key_type=otp default_user=singless cidr_list=0.0.0.0/0
Success! Data written to: ssh/roles/otp_key_role

这里我们指定了生成的 otp 的默认用户名是 singless,生成 otp 时要确保对应的用户名在要登录的服务器上已经存在,否则即使 Vault 验证通过,也是无法正常登录的。这里的 cidr_list 可以限制试图登录的来访 ip 范围。

生成一个otp

root@ceph-4:~# vault write ssh/creds/otp_key_role ip=192.168.85.151

ip为运行vault-ssh-helper的服务器ip,key为生成的otp密码,通过username一行可以知道,otp是为singless用户生成的。

我们在使用singless用户通过ssh连接到服务器上,通过otp密码可以正常连接到服务器。且OTP密码只可使用一次。

相关推荐
神秘的土鸡2 天前
丹摩征文活动 | SD3+ComfyUI的图像部署实践
人工智能·云计算·aigc·ai绘画·gpu算力·安全架构
溯Sec8 天前
shodan(五)连接Mongodb数据库&Jenkins&org、net、查看waf命令
网络·安全·web安全·网络安全·系统安全·网络攻击模型·安全架构
溯Sec9 天前
搜索引擎之shodan(一):初始化及安装
网络·安全·web安全·搜索引擎·网络安全·系统安全·安全架构
wusong99914 天前
数据安全-接口数据混合加密笔记
前端·笔记·后端·软件工程·安全架构
kinlon.liu15 天前
安全日志记录的重要性
服务器·网络·安全·安全架构·1024程序员节
予安灵17 天前
Metasploit(MSF)使用
安全·web安全·网络安全·网络攻击模型·安全威胁分析·安全架构
程序员小予18 天前
2024年网络安全(黑客)自学总结
网络·计算机网络·安全·web安全·网络安全·系统安全·安全架构