1. 什么是Vault?
Vault是一款由HashiCorp开发的开源工具,可以用于安全地存储和访问敏感信息,如数据库密码、API密钥和证书。Vault提供了诸如密钥轮换、动态凭证生成和访问控制等功能,可用于构建高度安全的应用程序。
Vault的工作原理是将敏感信息加密后存储在Vault服务器中,只有具有足够权限的用户才能解密并访问这些信息。Vault还提供了API和CLI工具,可用于与其他应用程序进行集成。
2. 为什么需要使用Vault?
2.1 管理和存储密码的问题
在应用程序中存储密码是一项非常敏感的工作。如果不正确地处理密码,就有可能遭受攻击,并导致数据泄露和安全漏洞。在许多情况下,开发人员会将密码明文存储在配置文件或数据库中,这会使应用程序易受到攻击。
但是,Vault使用加密技术将密码等敏感信息安全地存储在服务器中,可以为应用程序提供更安全的存储和管理方案。
2.2 动态凭证生成的优点
动态凭证是一种仅在必要时才生成的凭证,以避免长期使用的特权访问,从而增强了应用程序的安全性。在许多情况下,开发人员会将凭证硬编码到应用程序中或存储在配置文件中。这会使凭证受到攻击并且难以轮换。
但是,Vault提供了动态凭证生成功能,可以使应用程序在需要时生成凭证,以避免访问权限被滥用,提高安全性。
2.3 应用程序的访问控制
在许多情况下,不同的应用程序需要使用不同的凭证来访问数据库或其他服务。Vault可以通过为每个应用程序分配不同的凭证来增强应用程序的访问控制,并在需要时轮换凭证。
3. 在Golang中使用Vault
3.1 安装Vault
在使用Vault之前,需要安装和配置Vault服务器。您可以在这里找到有关安装和配置Vault的详细信息。
// 安装Vault
brew install vault
// 启动Vault服务
vault server -dev
3.2 初始化Vault,并进行身份验证
初始化Vault是创建Vault实例的第一步。这将为Vault生成一个根令牌,并设置一些必要的配置。根令牌是具有最高权限的令牌,可以执行任何操作。
// 初始化Vault
vault operator init
// 输出示例
Unseal Key 1: nFnR6BKNlUPo7D4zx7ye+kiMqPSWSmU/+3+QQq3E3Fl5
Unseal Key 2: BK+2Hqws28upRUNG1VJxUsJTT/LZpr+01mmpbxrHMzqy
Unseal Key 3: zfl0Rt6lhWjQOrPyVBGnj2LpNbNPrHPznyzI8xgV2j3z
Unseal Key 4: odGTYHHuw9g03C8UQ95ECQpyaVuqkKLt+zUX/4pOScW3
Unseal Key 5: ulmriI4MnElmY+TcOE0vRQ1l6Iq7zVqhiQ3yheAnxCb/
Initial Root Token: s.Vp8TbWqnwnjbTOapO3VT69ya
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 key to
reconstruct the master key, Vault will remain permanently sealed!
请将生成的根令牌保存到安全且易于访问的地方,例如密码管理工具。在配置Vault服务器时,可以使用根令牌进行身份验证。
3.3 配置数据库凭证
接下来,我们将使用Vault为数据库配置凭证。在这个例子中,我们将使用MySQL数据库。
首先,运行以下命令创建一个名为“my-mysql-database”的Vault数据库配置文件:
cat <
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \
username="my-mysql-user" \
password="my-mysql-password"
接下来,在Vault中为该配置文件创建角色。在这个例子中,我们将为一个名为“my-mysql-app”的应用程序创建一个连接MySQL数据库的角色:
vault write database/roles/my-mysql-app \
db_name=my-mysql-database \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT ALL ON *.* TO '{{name}}'@'%';GRANT ALL ON *.* TO '{{name}}'@'localhost';" \
default_ttl="1h" \
max_ttl="24h"
在这个角色中,我们指定了数据库、创建所有者的SQL语句以及默认存活时间和最长存活时间。
3.4 通过Vault获取数据库密码
使用Vault获取数据库密码的过程如下:
打开Vault客户端
通过Vault客户端进行身份验证
为应用程序生成动态凭证
使用凭证连接数据库
以下是使用Vault和Golang连接MySQL数据库的示例代码:
package main
import (
"database/sql"
"fmt"
"os"
_ "github.com/go-sql-driver/mysql"
"github.com/hashicorp/vault/api"
)
func main() {
// Configure Vault client
vaultAddr := os.Getenv("VAULT_ADDR")
vaultToken := os.Getenv("VAULT_TOKEN")
config := api.DefaultConfig()
config.Address = vaultAddr
client, err := api.NewClient(config)
if err != nil {
fmt.Println(err)
return
}
client.SetToken(vaultToken)
// Generate database credentials
database := client.Logical()
result, err := database.Write("database/creds/my-mysql-app", nil)
if err != nil {
fmt.Println(err)
return
}
username := result.Data["username"]
password := result.Data["password"]
// Open database connection
dataSourceName := fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/", username, password)
db, err := sql.Open("mysql", dataSourceName)
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
// Execute SQL query
rows, err := db.Query("SHOW DATABASES")
if err != nil {
fmt.Println(err)
return
}
defer rows.Close()
// Print results
for rows.Next() {
var database string
if err := rows.Scan(&database); err != nil {
fmt.Println(err)
return
}
fmt.Println(database)
}
if err := rows.Err(); err != nil {
fmt.Println(err)
return
}
}
该示例代码首先使用Vault客户端进行身份验证。然后,它使用Vault客户端创建一个名为“my-mysql-app”的动态凭证。接下来,它使用该凭证连接MySQL数据库,并执行SQL查询。最后,它打印数据库的列表。
4. 总结
Vault是一个功能强大的工具,可用于存储和管理敏感信息。使用Vault进行密码管理和动态凭证生成可以为您的应用程序提供更安全、更灵活的访问机制。在Golang中使用Vault可以轻松地创建动态凭证,并实现对数据库等服务的安全访问。要充分利用Vault,需要仔细了解Vault的各种功能和组件,并学会如何将这些功能集成到您的应用程序中。