GO-使用环境变量和AWS SSM的安全配置

227 阅读2分钟

在这里我将介绍通过环境变量配置从安全的远程存储中获取远程值。


以安全的方式存储和检索秘密是任何现代软件的一个基本步骤,已经有知名的供应商提供这种服务,例如Hashicorp VaultAWS Systems Manager

这种模式与选择一个具体的供应商无关,而是与我们如何与上述供应商互动,以安全和简单的方式动态地获得我们应该获得的值有关。

我们定义配置值的方式是通过环境变量,最简单的例子是为某种数据存储定义凭证,基本上是数据库凭证,类似于以下内容。

  • DB_HOST="host.somewhere"
  • DB_USERNAME="user.name"
  • DB_PASSWORD="pass.word"

这种类型的配置的主要问题是,这些值对于恰好在运行将使用这些值的程序的环境来说是公开和清楚的。这是一个安全问题。

这种模式包括,不这样做,而是用相同的名字定义新的环境变量,但后缀为_SSM ,这将包含一个参数值,用于从安全存储中检索远程值。

  • DB_HOST_SSM="/service1/db/host"
  • DB_USERNAME_SSM="/service1/db/username/"
  • DB_PASSWORD_SSM="/service1/db/password

因此,当运行我们的程序时,环境变量将被定义为上述变量,但实际上这些变量的实际值不会是公开的和清晰的,而是在程序请求这些值时从远程存储中安全地提取。

所有这些都被包裹在一个叫做aws-ssm-env的包中,然而重要的不是包的实现,而是范式本身,以及在从远程存储中检索值时如何定义交互。

更多信息请参见示例

// Run it as:
// AWS_REGION=us-east1 go run examples/main.go
package main

import (
	"context"
	"fmt"
	"os"

	"github.com/aws/aws-sdk-go/aws"
	awssession "github.com/aws/aws-sdk-go/aws/session"
	awsssm "github.com/aws/aws-sdk-go/service/ssm"

	awsssmenv "github.com/MarioCarrion/aws-ssm-env"
)

func main() {
	// XXX Error validation omitted
	session, _ := awssession.NewSession(&aws.Config{
		Region: aws.String(os.Getenv("AWS_REGION")),
	})

	ssm := awsssm.New(session)

	v := struct {
		Username string `ssm:"USER"`
	}{}

	// If USER_SSM is defined on the system we will contact AWS SSM to get
	// the remote value defined in this variable.
	// For example if USER_SSM is "/remote/user" then AWS SSM will be queried
	// using "/remote/user" and the result will be stored in "v.Username"

	if err := awsssmenv.Get(context.Background(), &v, ssm); err != nil {
		fmt.Println("Error", err)
	}

	fmt.Printf("%+v\n", v)
}