Skip to content

本文为 SPIRE 官方文档 plugin_server_keymanager_hashicorp_vault 的中文译本,以英文原文为准。

🔗 穿越源码分析:Server 详解 · KeyManager

服务端插件:KeyManager "hashicorp_vault"

hashicorp_vault 密钥管理器(key manager)插件借助 HashiCorp Vault 来创建、维护并轮换密钥对,并按需签发 SVID。

配置

该插件接受以下配置项:

键名类型是否必填说明默认值
key_identifier_filestring若未设置 key_identifier_value 则必填一个文件路径,用于持久化所生成密钥的相关信息。更多信息见"密钥的管理"。""
key_identifier_valuestring若未设置 key_identifier_file 则必填SPIRE server 实例的静态标识符(用于替代 key_identifier_file)。""
vault_addrstringVault 服务器的 URL。(例如 https://vault.example.com:8443/)${VAULT_ADDR}
namespacestringVault 命名空间(namespace)的名称。仅在 Vault Enterprise 中可用。${VAULT_NAMESPACE}
transit_engine_pathstring存储密钥的 transit 引擎(transit engine)的路径。transit
ca_cert_pathstring用于校验 Vault 服务器证书的 CA 证书文件路径。仅支持 PEM 格式。${VAULT_CACERT}
insecure_skip_verifybool若为 true,vault 客户端将接受任意服务器证书。只应在测试环境中使用。false
cert_authstruct客户端证书(Client Certificate)认证方式的配置
token_authstruct令牌(Token)认证方式的配置
approle_authstructAppRole 认证方式的配置
k8s_authstructKubernetes 认证方式的配置

环境变量

插件会读取以下环境变量。标注为"标准"的变量会被 Vault CLI 与客户端库原生识别——完整参考见 Vault 文档

变量标准说明
VAULT_ADDRVault 服务器的地址
VAULT_CACERTCA 证书文件的路径
VAULT_CLIENT_CERT客户端证书文件的路径(cert 认证)
VAULT_CLIENT_KEY客户端私钥文件的路径(cert 认证)
VAULT_NAMESPACEVault 命名空间(仅 Enterprise)
VAULT_TOKENVault 令牌(token 认证)
VAULT_APPROLE_IDAppRole 的 role ID —— SPIRE 专用,并非 Vault SDK 变量
VAULT_APPROLE_SECRET_IDAppRole 的 secret ID —— SPIRE 专用,并非 Vault SDK 变量
VAULT_TRANSIT_ENGINE_PATHtransit 引擎路径 —— SPIRE 专用,回退默认值为 transit

插件支持 客户端证书(Client Certificate)令牌(Token)AppRoleKubernetes 四种认证方式。

  • 客户端证书(Client Certificate) 方式使用 TLS 客户端证书向 Vault 认证。
  • 令牌(Token) 方式使用 HTTP 请求头中的令牌向 Vault 认证。
  • AppRole 方式使用由 Vault 签发的 RoleID 与 SecretID 向 Vault 认证。
  • Kubernetes 方式使用 Kubernetes 服务账号令牌(Service Account Token)向 Vault 认证。

所配置的令牌需要绑定到一个至少具备以下能力(capabilities)的策略(policy)上:

hcl
path "transit/keys/*" {
  capabilities = ["create", "read", "update", "delete", "list"]
}

path "transit/sign/*" {
  capabilities = ["update"]
}

客户端证书认证(Client Certificate Authentication)

键名类型是否必填说明默认值
cert_auth_mount_pointstringTLS 证书认证方式挂载点(mount point)的名称cert
cert_auth_role_namestringVault 角色(role)的名称。若给定,插件仅针对该命名角色进行认证。默认尝试所有角色。
client_cert_pathstring客户端证书文件的路径。仅支持 PEM 格式。${VAULT_CLIENT_CERT}
client_key_pathstring客户端私钥文件的路径。仅支持 PEM 格式。${VAULT_CLIENT_KEY}
hcl
    KeyManager "hashicorp_vault" {
        plugin_data {
            vault_addr = "https://vault.example.org/"
            ca_cert_path = "/path/to/ca-cert.pem"
            cert_auth {
                cert_auth_mount_point = "test-tls-cert-auth"
                client_cert_path = "/path/to/client-cert.pem"
                client_key_path  = "/path/to/client-key.pem"
            }
            // 若要指定用于认证的角色
            // cert_auth {
            //     cert_auth_mount_point = "test-tls-cert-auth"
            //     cert_auth_role_name = "test"
            //     client_cert_path = "/path/to/client-cert.pem"
            //     client_key_path  = "/path/to/client-key.pem"
            // }
       
            // 若通过环境变量指定密钥对,并使用修改后的挂载点
            // cert_auth {
            //    cert_auth_mount_point = "test-tls-cert-auth"
            // }

            // 若通过环境变量指定密钥对,并使用默认挂载点,则设为空结构体。
            // cert_auth {}
        }
    }

令牌认证(Token Authentication)

键名类型是否必填说明默认值
tokenstring要设置到 "X-Vault-Token" 请求头中的令牌字符串${VAULT_TOKEN}
hcl
    KeyManager "hashicorp_vault" {
        plugin_data {
            vault_addr = "https://vault.example.org/"
            ca_cert_path = "/path/to/ca-cert.pem"
            token_auth {
               token = "<token>"
            }
            // 若通过环境变量指定令牌,则设为空结构体。
            // token_auth {}
        }
    }

AppRole 认证(AppRole Authentication)

键名类型是否必填说明默认值
approle_auth_mount_pointstringAppRole 认证方式挂载点(mount point)的名称approle
approle_idstringAppRole 的标识符${VAULT_APPROLE_ID}
approle_secret_idstringAppRole 的凭据${VAULT_APPROLE_SECRET_ID}
hcl
    KeyManager "hashicorp_vault" {
        plugin_data {
            vault_addr = "https://vault.example.org/"
            ca_cert_path = "/path/to/ca-cert.pem"
            approle_auth {
               approle_auth_mount_point = "my-approle-auth"
               approle_id = "<Role ID>" // 或通过环境变量指定
               approle_secret_id = "<Secret ID>" // 或通过环境变量指定
            }
            // 若通过环境变量指定 approle_id 和 approle_secret,并使用修改后的挂载点
            // approle_auth {
            //    approle_auth_mount_point = "my-approle-auth"
            // }

            // 若通过环境变量指定 approle_id 和 approle_secret,并使用默认挂载点,则设为空结构体。
            // approle_auth {}
        }
    }

Kubernetes 认证(Kubernetes Authentication)

键名类型是否必填说明默认值
k8s_auth_mount_pointstringKubernetes 认证方式挂载点(mount point)的名称kubernetes
k8s_auth_role_namestringVault 角色(role)的名称。插件针对该命名角色进行认证
token_pathstring用于向 Vault 认证的 Kubernetes 服务账号令牌(Service Account Token)的路径
hcl
    KeyManager "hashicorp_vault" {
        plugin_data {
            vault_addr = "https://vault.example.org/"
            ca_cert_path = "/path/to/ca-cert.pem"
            k8s_auth {
               k8s_auth_mount_point = "my-k8s-auth"
               k8s_auth_role_name = "my-role"
               token_path = "/path/to/sa-token"
            }
            
            // 若指定角色名,并使用默认挂载点与 token_path
            // k8s_auth {
            //   k8s_auth_role_name = "my-role"
            // }            
        }
    }

密钥的管理

插件需要一种方式来识别它正在其上运行的具体 server 实例。为此,必须使用 key_identifier_filekey_identifier_value 两者之一。设置**密钥标识文件(Key Identifier File)**会指示插件自动管理 server 的标识符,将 server ID 存储在指定 文件中。这种方式适用于大多数情况。如果配置了_密钥标识文件_而在 server 启动时未 找到该文件,则会以新的、自动生成的 server ID 重新创建该文件。因此,如果该文件丢 失,插件将无法识别它此前管理过的密钥,并会按需重新创建新密钥。

如果你需要对 server 所用的标识符有更多控制,可以使用 key_identifier_value 设置 来为 server 实例指定一个静态标识符。这种设置适用于无法持久化密钥标识文件的场景。