KMS Agent是一个HTTP代理服务,负责向KMS服务获取凭据值并缓存在内存中,应用通过HTTP请求向KMS Agent获取凭据值。通过部署KMS Agent,可以简化应用访问KMS的身份认证与缓存管理流程,适用于大规模应用访问KMS的场景。同时,KMS Agent能够降低应用改造成本,确保统一的集成标准。本文介绍如何部署KMS Agent。
KMS Agent获取凭据流程
KMS Agent使用内存缓存凭据值,根据您设置的TTL时间定期刷新缓存的凭据值。当业务应用通过HTTP请求向KMS Agent请求凭据值时,KMS Agent通过SSRF Token文件验证请求的合法性,若缓存中存在有效凭据值则直接返回,否则向KMS服务转发请求,KMS服务验证KMS Agent身份通过后,从KMS解密凭据并返回,KMS Agent更新缓存后通过HTTP消息将凭据值返回给业务应用。流程如下图所示:
命中缓存的流程。
未命中缓存的流程。
KMS Agent需要和业务应用部署在一起,支持多环境部署,包括本地物理机、虚拟机(如ECS)、容器(如K8s Pod)。您可以访问alibabacloud-kms-agent,了解更多KMS Agent代码信息。
功能模块
KMS Agent代理由HTTP Server模块、Cache模块、KMS配置模块、Log模块这四个模块组成。
您可以通过在配置文件中设置相应参数来配置各功能模块。配置文件如下:
# 全部配置项
[Server]
# 可选, 默认值为 2025, Agent默认监听地址127.0.0.1:2025
HttpPort = 2025
# 可选, 默认值为 ["X-KMS-Token", "X-Vault-Token"]。
# 访问Agent必须携带SSRF Header, 否则禁止访问。
SSRFHeaders = ["X-KMS-Token"]
# 可选,默认值为 ["KMS_TOKEN", "KMS_SESSION_TOKEN", "KMS_CONTAINER_AUTHORIZATION_TOKEN"],变量值可以是具体值,或者文件路径如 file:///var/run/awssmatoken.
# Agent从Env获取SSRF Token,与应用访问Header携带的 Token比较,一致才允许访问。
SSRFEnvVariables = ["KMS_TOKEN"]
# 可选, 默认值为 "/v1/".
# 基于路径访问时请求的URI前缀
PathPrefix = "/v1/"
# 可选, 默认值为 800
# 同时能够并发请求的最大值
MaxConn = 800
# 可选, 默认值为 0
# 0: 凭据内容按照KMS GetSecretvalue API Response 格式返回; 1: 凭据内容按照 AWS SeceretManager GetSecretvalue API Response 格式返回; 2: 以 HashiCorp KV 结构返回。
ResponseType = 0
# 可选, 默认值 true
# IgnoreTransientErrors为 true,当缓存失效后, 而访问远端KMS遇到失败,Response会返回已经在内存里失效的缓存凭证。
IgnoreTransientErrors = true
[Kms]
# 可选,默认值为 cn-hangzhou
# KMS所在的地域
Region = "cn-hangzhou"
# 可选, 默认值为 kms.cn-hangzhou.aliyuncs.com
# Endpoint可以是共享网关Endpoint,也可以是专属网关Endpoint
Endpoint = "kms.cn-hangzhou.aliyuncs.com"
[Cache]
# 可选,默认为 InMemory,当前仅支持内存缓存
CacheType = "InMemory"
# 可选, 默认缓存大小 1000 个凭据,当 CacheSize=0 时,不使用缓存,每次请求都访问远端KMS。
CacheSize = 1000
# 可选, 缓存时效性,默认值是 300s.
TtlSeconds = 300
# 可选, 缓存淘汰策略,不填默认为 false.
# 当缓存凭据到了CacheSize上限,取值false表示按照缓存时间删除最早存入缓存凭据,取值true表示按照使用频率淘汰最近一次使用时间最长的凭据。
EnableLRU = false
[Log]
# 可选, 默认日志级别 Debug
LogLevel = "Debug"
# 可选, 默认日志存储应用启动目录的 ./logs/
LogPath = "./logs/"
# 可选, 默认单个日志大小 100M
MaxSize = 100
# 可选, 默认保留2个日志文件数量
MaxBackups = 2
HTTP Server模块。
用于响应应用程序检索凭据的请求。KMS Agent返回的凭据值默认与GetSecretValue的响应格式相同,也可以通过在配置文件中设置ResponseType参数返回其他格式。
Cache模块。
KMS Agent内置内存缓存机制,将凭据缓存在内存中,凭据值在缓存中未加密,业务应用直接读取本地缓存,减少对KMS服务的频繁请求。用户可以设置缓存时间、缓存大小、淘汰策略,避免凭据过期导致业务中断。
重要建议您通过设置内存保护机制、设置合理的KMS Agent进程访问权限以及部署内存泄漏检测工具等措施,增强缓存中的凭据值的存储安全性。
KMS配置模块。
支持设置地域、网关地址(Endpoint),网关地址支持共享网关Endpoint和专属网关Endpoint。
说明使用专属网关Endpoint时,KMS Agent已经内置了全地域专属网关的CA证书,用户无需配置CA证书。
Log模块。
基于流行的Zap日志框架, 提供JSON格式的日志,支持用户配置单个日志文件的大小限制和最多保留的日志文件数量。
安全性
身份认证与授权
KMS Agent访问KMS。
KMS Agent访问KMS使用默认凭证链,自动按优先级检测环境变量、ECS实例RAM角色、配置文件等认证方式,不允许用户在配置里直接使用明文AccessKey。详细介绍,请参见默认凭据链。Linux环境部署推荐使用ECS实例RAM角色,K8s Sidecar容器部署推荐使用RRSA, 其他环境推荐使用环境变量。
访问KMS服务时通过RAM权限策略限制对凭据的访问时,KMS Agent需要具有获取凭据值的权限,由于凭据值是加密存储的,还需要具有解密密钥的权限,请在设置Agent的权限时遵循权限最小原则。
业务应用访问KMS Agent。
KMS Agent启动时生成SSRF Token文件(如
/var/run/kmstoken
),应用程序在向KMS Agent发起HTTP请求时,必须在请求头中携带该SSRF Token,Agent会对其进行校验,只有校验通过请求才会被处理,否则返回失败响应。Linux环境部署场景。
SSRF Token文件默认只允许KMS Agent与应用程序所属的系统用户读取,其他进程禁止访问SSRF Token文件。
Sidecar容器部署。
采用Sidecar模式与业务应用容器同Pod部署,SSRF Token文件默认仅在Pod内部可见,其他Pod或外部服务无法直接访问。
通信安全
KMS Agent与KMS服务之间的通信使用TLS协议来确保数据传输过程,以防止被攻击或窃听。相比使用共享网关Endpoint,建议您使用专属网关Endpoint访问KMS服务,该方式业务请求仅在VPC网络内传输,可以避免请求暴露到公网,从而提供更高的安全性。
KMS Agent只监听127.0.0.1,即只有在同一台机器上运行的应用程序或进程能够与KMS Agent进行通信,外部网络中的任何设备都无法连接到KMS Agent。
支持日志
所有通过KMS Agent获取凭据的操作,均以日志形式保存在您设置的日志路径中,便于您审计操作记录。
稳定性
KMS Agent通过自检、重试机制等,确保在复杂网络环境和突发故障场景下的服务连续性。
启动自检机制。
KMS Agent启动时会验证KMS的连通性,验证失败则终止启动。
错误重试机制。
KMS Agent依赖阿里云SDK(V2)与KMS服务进行通信,遇到网络异常时,会利用阿里云SDK(V2)内置的错误重试逻辑自动尝试重新发起请求。当遇到服务端限流(HTTP 429)或服务器内部错误(HTTP 500)时,会采用间隔时间指数退避方法重试3次。
故障时使用过期缓存。
在KMS Agent配置文件中设置IgnoreTransientErrors参数, 当遇到网络或服务端故障时,KMS Agent会检查并返回旧的缓存数据,确保应用程序不会由于短时间故障而无法获取凭据。IgnoreTransientErrors参数默认开启。
基于systemd或Sidecar容器的高可用性保障。
Linux环境部署:KMS Agent被systemd托管,进程中断后会自动重启。
Sidecar容器部署:把Sidecar配置为Init容器,确保KMS Agent在业务容器启动之前完成初始化。
KMS Agent优势
性能和可靠性。
KMS Agent在内存中缓存凭据值,高频访问场景可以减少对KMS服务的频繁请求,避免高频访问可能引起的限流,从而提高性能和业务可用性。
兼容性。
KMS Agent基于标准化HTTP接口提供服务,支持任意编程语言的业务应用直接调用。当业务的多个应用属于不同语言时,使用KMS Agent可以降低集成难度。
简化集成。
通过KMS Agent,可以解耦应用与KMS,KMS Agent可以减少应用程序与KMS服务交互所需的复杂性,应用程序只需与KMS Agent进行通信,无需直接处理访问KMS服务时的身份验证、API调用等。
集中化管理及可扩展性。
对于企业级多应用场景,使用KMS Agent可以统一管理和控制访问权限,减少在每个客户端上配置权限,从而保证各应用集成过程中的统一性。当业务需要扩展时,使用KMS Agent便于新应用集成,减少使用SDK可能导致的权限配置及代码改造。
KMS Agent与凭据客户端对比
KMS Agent作为中间层,应用通过Agent间接访问KMS服务,使用凭据客户端需要应用通过SDK直接调用KMS服务的API。两者之间的差异请参见下表。
对比维度 | KMS Agent | 凭据客户端 |
部署位置 | 作为独立进程部署(如Sidecar容器),与应用解耦。 | 与应用代码集成,作为依赖库。 |
访问控制 | KMS Agent作为唯一访问入口,可集中实施权限策略管控。 | 需在每个应用中配置访问身份及权限策略,策略分散。 |
语言支持 | Agent提供通用HTTP接口,支持任意语言的应用。 | 提供Java(Java 8及以上版本)、Python、Go语言。 |
业务性能 | KMS Agent在内存缓存凭据值,针对高频获取凭据值的场景,可以减少访问延迟且降低限流风险。 | 每次请求均需访问远端KMS服务,高频访问时可能会限流。 |
凭据轮转场景处理 | 通过在KMS Agent中设置TTL时间,当超过TTL时长时会向KMS服务获取凭据值,减少凭据轮转可能导致的凭据失效问题。 | 通过配置凭据缓存机制及错误重试机制,当凭据失效时会自动从KMS服务重新获取凭据。 |
集成复杂度 | 应用无需集成SDK,仅需调用KMS Agent提供的HTTP接口,应用程序无需处理KMS的交互逻辑,集成方式更简单。 当业务涉及多语言应用时,使用KMS Agent还可保证集成质量的统一性。 | 需在代码中调用API,处理重试、错误、缓存机制,当业务涉及多个应用时集成复杂度较高。 |
维护成本 | 多个应用的场景下,当权限策略等出现变更时,可以统一维护KMS Agent配置,应用无感知。 | 多个应用的场景下,当权限策略等出现变更时,每个应用需单独修改配置。 |
针对多应用、多语言的企业级用户,如果您需要保证权限策略的集中控制,降低应用集成的复杂度,保证集成质量的统一性时可优先使用KMS Agent。针对小型或单一应用,无需复杂访问控制策略时,可优先使用凭据客户端。