Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅
中国的 Amazon Web Services 服务入门
(PDF)。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
使用代 Amazon Secrets Manager 理
Secrets Manager 代理是如何运作的
Amazon Secrets Manager 代理是一项客户端 HTTP 服务,可帮助您标准化在计算环境中使用 Secrets Manager 中的密钥的方式。您可以将它用于以下服务:
-
Amazon Lambda
-
Amazon Elastic Container Service
-
Amazon Elastic Kubernetes Service
-
Amazon Elastic Compute Cloud
Secrets Manager Agent 检索密钥并将其缓存在内存中,允许您的应用程序从本地主机获取密钥,而不必直接调用 Secrets Manager。Secrets Manager Agent 只能读取密钥,而无法修改密钥。
Secrets Manager 代理使用您环境中的 Amazon 凭证来调用 Secrets Manager。它包括针对服务器端请求伪造(SSRF)的保护,以帮助提高密钥安全性。默认情况下,Secrets Manager Agent 使用后量子 ML-KEM 密钥交换作为优先级最高的密钥交换。
了解 Secrets Manager 代理缓存
Secrets Manager 代理使用内存缓存,该缓存会在 Secrets Manager 代理重启时重置。它会根据以下内容定期刷新缓存的密钥值:
-
默认刷新频率 (TTL) 为 300 秒
-
您可以使用配置文件修改 TTL
-
当你在 TTL 到期后请求密钥时,就会发生刷新
Secrets Manager 代理不包括缓存失效。如果密钥在缓存条目过期之前轮换,则 Secrets Manager 代理可能会返回过时的密钥值。
Secrets Manager 代理返回的密钥值与 GetSecretValue
的响应格式相同。密钥值在缓存中未进行加密。
构建 Secrets Manager 代理
在开始之前,请确保您已为您的平台安装标准开发工具和 Rust 工具。
目前,在 macOS 上启用该fips
功能的情况下构建代理需要以下解决方法:
- RPM-based systems
-
在基于 RPM 的系统上构建
-
使用存储库中提供的 install
脚本。
该脚本在启动时生成一个随机的 SSRF 令牌并将其存储在文件 /var/run/awssmatoken
中。安装脚本创建的 awssmatokenreader
组可以读取该令牌。
-
要允许您的应用程序读取令牌文件,您需要将应用程序在其下运行的用户账户添加到 awssmatokenreader
组。例如,您可以使用以下 usermod 命令授予应用程序读取令牌文件的权限,其中<APP_USER>
是应用程序在其下运行的用户 ID。
sudo usermod -aG awssmatokenreader <APP_USER>
安装开发工具
在基于 RPM 的系统(如 AL2 023)上,安装 “开发工具” 组:
sudo yum -y groupinstall "Development Tools"
-
安装 Rust
按照 Rust 文档中安装 Rus t 中的说明进行操作:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Follow the on-screen instructions
. "$HOME/.cargo/env"
-
构建代理
使用 cargo build 命令构建 Secrets Manager 代理:
cargo build --release
您将在 target/release/aws_secretsmanager_agent
下找到可执行文件。
- Debian-based systems
-
在基于 Debian 的系统上构建
-
安装开发工具
在基于 Debian 的系统(例如 Ubuntu)上,安装构建必需包:
sudo apt install build-essential
-
安装 Rust
按照 Rust 文档中安装 Rus t 中的说明进行操作:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Follow the on-screen instructions
. "$HOME/.cargo/env"
-
构建代理
使用 cargo build 命令构建 Secrets Manager 代理:
cargo build --release
您将在 target/release/aws_secretsmanager_agent
下找到可执行文件。
- Windows
-
在 Windows 上构建
-
设置开发环境
请按照 Microsoft Windows 文档中的 Set up your dev environment on Windows fo r Rus t
-
构建代理
使用 cargo build 命令构建 Secrets Manager 代理:
cargo build --release
您将在 target/release/aws_secretsmanager_agent.exe
下找到可执行文件。
- Cross-compile natively
-
本机交叉编译
-
安装交叉编译工具
在 mingw-w64 包可用的发行版(例如 Ubuntu)上,请安装交叉编译工具链:
# Install the cross compile tool chain
sudo add-apt-repository universe
sudo apt install -y mingw-w64
-
添加 Rust 构建目标
安装 Windows GNU 编译目标:
rustup target add x86_64-pc-windows-gnu
-
为 Windows 构建
交叉编译适用于 Windows 的代理:
cargo build --release --target x86_64-pc-windows-gnu
您将在 target/x86_64-pc-windows-gnu/release/aws_secretsmanager_agent.exe
处找到可执行文件。
- Cross compile with Rust cross
-
使用 Rust 交叉进行交叉编译
如果系统本身没有交叉编译工具,则可以使用 Rust 交叉项目。有关更多信息,请参阅 c https://github.com/cross-rs/ross。
-
设置 Docker
安装和配置 Docker:
# Install and start docker
sudo yum -y install docker
sudo systemctl start docker
sudo systemctl enable docker # Make docker start after reboot
-
配置 Docker 权限
将您的用户添加到 docker 群组:
# Give ourselves permission to run the docker images without sudo
sudo usermod -aG docker $USER
newgrp docker
-
为 Windows 构建
安装 cross 并生成可执行文件:
# Install cross and cross compile the executable
cargo install cross
cross build --release --target x86_64-pc-windows-gnu
安装 Secrets Manager 代理
从以下安装选项中选择您的计算环境。
- Amazon EC2
-
在亚马逊上安装 Secrets Manager 代理 EC2
-
导航到配置目录
切换到配置目录:
cd aws_secretsmanager_agent/configuration
-
运行安装脚本
运行存储库中提供的 install install
脚本。
该脚本在启动时生成一个随机的 SSRF 令牌并将其存储在文件 /var/run/awssmatoken
中。安装脚本创建的 awssmatokenreader
组可以读取该令牌。
-
配置应用程序权限
将运行应用程序的用户帐户添加到awssmatokenreader
群组中:
sudo usermod -aG awssmatokenreader APP_USER
APP_USER
替换为运行应用程序时使用的用户 ID。
- Container Sidecar
-
您可以使用 Docker 将 Secrets Manager 代理作为附加容器与应用程序一起运行。然后,您的应用程序可以从 Secrets Manager 代理提供的本地 HTTP 服务器检索密钥。有关 Docker 的信息,请参阅 Docker 文档。
为 Secrets Manager 代理创建附加容器
-
创建代理 Dockerfile
为 Secrets Manager 代理附加容器创建 Dockerfile:
# Use the latest Debian image as the base
FROM debian:latest
# Set the working directory inside the container
WORKDIR /app
# Copy the Secrets Manager Agent binary to the container
COPY secrets-manager-agent .
# Install any necessary dependencies
RUN apt-get update && apt-get install -y ca-certificates
# Set the entry point to run the Secrets Manager Agent binary
ENTRYPOINT ["./secrets-manager-agent"]
-
创建应用程序 Dockerfile
为您的客户端应用程序创建一个 Dockerfile。
-
创建 Docker Compose 文件
创建 Docker Compose 文件,使用共享网络接口运行两个容器:
您必须加载 Amazon 凭证和 SSRF 令牌,应用程序才能使用 Secrets Manager 代理。对于 Amazon EKS 和 Amazon ECS,请参阅以下内容:
version: '3'
services:
client-application:
container_name: client-application
build:
context: .
dockerfile: Dockerfile.client
command: tail -f /dev/null # Keep the container running
secrets-manager-agent:
container_name: secrets-manager-agent
build:
context: .
dockerfile: Dockerfile.agent
network_mode: "container:client-application" # Attach to the client-application container's network
depends_on:
- client-application
-
复制座席班次
将 secrets-manager-agent
二进制文件复制到包含您的 Dockerfile 和 Docker Compose 文件的同一个目录中。
-
构建并运行容器
使用 Docker Compose 构建并运行容器:
docker-compose up --build
-
后续步骤
您现在可使用 Secrets Manager 代理从您的客户端容器中检索密钥。有关更多信息,请参阅 使用 Secrets Manager 代理检索密钥。
- Lambda
-
您可以将 S ecrets Manager 代理打包为 Lambda 扩展。然后,您可以将其作为层添加到 Lambda 函数中,并从 Lambda 函数调用 Secrets Manager 代理来获取密钥。
以下说明说明如何使用secrets-manager-agent-extension.sh
中的示例脚本将 Secret MyTests Manager 代理作为 Lambda 扩展进行安装,https://github.com/aws/aws-secretsmanager-agent从而获取名为的密钥。
为 Secrets Manager 代理创建 Lambda 扩展
-
Package 代理层
从 Secrets Manager 代理代码包的根目录运行以下命令:
AWS_ACCOUNT_ID=AWS_ACCOUNT_ID
LAMBDA_ARN=LAMBDA_ARN
# Build the release binary
cargo build --release --target=x86_64-unknown-linux-gnu
# Copy the release binary into the `bin` folder
mkdir -p ./bin
cp ./target/x86_64-unknown-linux-gnu/release/aws_secretsmanager_agent ./bin/secrets-manager-agent
# Copy the `secrets-manager-agent-extension.sh` example script into the `extensions` folder.
mkdir -p ./extensions
cp aws_secretsmanager_agent/examples/example-lambda-extension/secrets-manager-agent-extension.sh ./extensions
# Zip the extension shell script and the binary
zip secrets-manager-agent-extension.zip bin/* extensions/*
# Publish the layer version
LAYER_VERSION_ARN=$(aws lambda publish-layer-version \
--layer-name secrets-manager-agent-extension \
--zip-file "fileb://secrets-manager-agent-extension.zip" | jq -r '.LayerVersionArn')
-
配置 SSRF 令牌
代理的默认配置会自动将 SSRF 令牌设置为在预设变量AWS_SESSION_TOKEN
或AWS_CONTAINER_AUTHORIZATION_TOKEN
环境变量中设置的值(后一个变量适用于启用的 Lambda 函数)。 SnapStart 或者,您可以改用您的 Lambda 函数的任意值定义AWS_TOKEN
环境变量,因为该变量优先于其他两个变量。如果您选择使用AWS_TOKEN
环境变量,则必须通过lambda:UpdateFunctionConfiguration
调用来设置该环境变量。
-
将图层附加到函数
将层版本附加到您的 Lambda 函数:
# Attach the layer version to the Lambda function
aws lambda update-function-configuration \
--function-name $LAMBDA_ARN \
--layers "$LAYER_VERSION_ARN"
-
更新函数代码
更新您的 Lambda 函数以http://localhost:2773/secretsmanager/get?secretId=MyTest
使用X-Aws-codes-Secrets-Token
标头值设置为来自上述环境变量之一的 SSRF 令牌的值进行查询,以检索密钥。务必在应用程序代码中实现重试逻辑,以适应 Lambda 扩展初始化和注册中的延迟。
-
测试此函数
调用 Lambda 函数以验证是否已正确获取密钥。
使用 Secrets Manager 代理检索密钥
要检索密钥,请使用密钥名称或 ARN 作为查询参数调用本地 Secrets Manager 代理端点。默认情况下,Secrets Manager 代理会检索密钥的 AWSCURRENT
版本。要检索其他版本,请使用 versionStage 或 versionId 参数。
为了帮助保护 Secrets Manager 代理,您必须在每个请求中包含 SSRF 令牌标头:X-Aws-Parameters-Secrets-Token
。Secrets Manager 代理会拒绝没有此标头或具有无效 SSRF 令牌的请求。您可以在 配置 Secrets Manager 代理 中自定义 SSRF 标头名称。
所需的权限
Secrets Manager 代理使用 Amazon 适用于 Rust 的 SDK,该 SDK 使用Amazon
凭证提供程序链。这些 IAM 凭证的身份决定了 Secrets Manager 代理检索密钥的权限。
有关权限的更多信息,请参阅 的权限参考 Amazon Secrets Manager。
将密钥值拉入 Secrets Manager 代理后,任何有权访问计算环境和 SSRF 令牌的用户都可以从 Secrets Manager 代理缓存中访问密钥。有关更多信息,请参阅 安全性注意事项。
示例请求
- curl
-
例 示例-使用 curl 获取秘密
以下 curl 示例展示了如何从 Secrets Manager 代理获取密钥。该示例依赖于文件中存在的 SSRF,该文件是安装脚本存储示例的位置。
curl -v -H \\
"X-Aws-Parameters-Secrets-Token: $(/var/run/awssmatoken)" \\
'http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID
' \\
echo
- Python
-
例 示例 — 使用 Python 获取秘密
以下 Python 示例展示了如何从 Secrets Manager 代理获取密钥。该示例依赖于文件中存在的 SSRF,该文件是安装脚本存储示例的位置。
import requests
import json
# Function that fetches the secret from Secrets Manager Agent for the provided secret id.
def get_secret():
# Construct the URL for the GET request
url = f"http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID
"
# Get the SSRF token from the token file
with open('/var/run/awssmatoken') as fp:
token = fp.read()
headers = {
"X-Aws-Parameters-Secrets-Token": token.strip()
}
try:
# Send the GET request with headers
response = requests.get(url, headers=headers)
# Check if the request was successful
if response.status_code == 200:
# Return the secret value
return response.text
else:
# Handle error cases
raise Exception(f"Status code {response.status_code} - {response.text}")
except Exception as e:
# Handle network errors
raise Exception(f"Error: {e}")
了解refreshNow
参数
Secrets Manager 代理使用内存缓存来存储密钥值,并且会定期刷新密钥值。默认情况下,当您在生存时间 (TTL) 到期后请求密钥时,通常每 300 秒刷新一次。但是,这种方法有时会导致密钥值过时,特别是如果密钥在缓存条目过期之前轮换。
为了解决此限制,Secrets Manager Agent 支持在 URL refreshNow
中调用的参数。您可以使用此参数强制立即刷新密钥的值,绕过缓存并确保您拥有最多的 up-to-date信息。
- 默认行为(没有
refreshNow
)
-
- 行为与
refreshNow=true
-
强制刷新密钥值
refreshNow
的默认值为 false
。设置为时true
,它将覆盖 Secrets Manager 代理配置文件中指定的 TTL,并对 Secrets Manager 进行 API 调用。
- curl
-
例 示例 — 使用 curl 强制刷新密钥
以下 curl 示例展示了如何强制 Secrets Manager 代理刷新密钥。该示例依赖于文件中存在的 SSRF,该文件是安装脚本存储示例的位置。
curl -v -H \\
"X-Aws-Parameters-Secrets-Token: $(/var/run/awssmatoken)" \\
'http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID
&refreshNow=true' \\
echo
- Python
-
例 示例-使用 Python 强制刷新密钥
以下 Python 示例展示了如何从 Secrets Manager 代理获取密钥。该示例依赖于文件中存在的 SSRF,该文件是安装脚本存储示例的位置。
import requests
import json
# Function that fetches the secret from Secrets Manager Agent for the provided secret id.
def get_secret():
# Construct the URL for the GET request
url = f"http://localhost:2773/secretsmanager/get?secretId=YOUR_SECRET_ID
&refreshNow=true"
# Get the SSRF token from the token file
with open('/var/run/awssmatoken') as fp:
token = fp.read()
headers = {
"X-Aws-Parameters-Secrets-Token": token.strip()
}
try:
# Send the GET request with headers
response = requests.get(url, headers=headers)
# Check if the request was successful
if response.status_code == 200:
# Return the secret value
return response.text
else:
# Handle error cases
raise Exception(f"Status code {response.status_code} - {response.text}")
except Exception as e:
# Handle network errors
raise Exception(f"Error: {e}")
配置 Secrets Manager 代理
要更改 Secrets Manager 代理的配置,请创建一个 TOML 配置文件,然后调用 ./aws_secretsmanager_agent --config
config.toml
。
配置选项
log_level
-
Secrets Manager 代理日志中报告的详细程度:DEBUG、INFO、WARN、ERROR 或 NONE。默认值为 INFO。
log_to_file
-
是登录文件还是 stdout/stderr:或。true
false
默认值为 true
。
http_port
-
本地 HTTP 服务器的端口,范围在 1024 到 65535 之间。默认值为 2773。
region
-
用于请求的 Amazon 区域。如果未指定区域,则 Secrets Manager 代理会根据 SDK 确定区域。有关更多信息,请参阅《Amazon
SDK for Rust 开发人员指南》中的 Specify your credentials and default Region。
ttl_seconds
-
缓存项目的 TTL(以秒为单位),范围在 0 到 3600 之间。默认值为 300。0 表示没有缓存。
cache_size
-
缓存中可以存储的最大密钥数量,范围在 1 到 1000 之间。默认值为 1000。
ssrf_headers
-
Secrets Manager 代理检查 SSRF 令牌的标头名称列表。默认值为 “X-Aws-Parameters-Token”。 X-Vault-Token
ssrf_env_variables
-
Secrets Manager 代理按顺序检查 SSRF 令牌的环境变量名称列表。环境变量可以包含令牌或对令牌文件的引用,如下所示:AWS_TOKEN=file:///var/run/awssmatoken
。默认为 “AWS_TOKEN、 AWS_SESSION _TOKEN、_AUTHORIZATION AWS_CONTAINER _TOKEN”。
path_prefix
-
用于确定请求是否为基于路径的请求的 URI 前缀。默认值为“/v1/”。
max_conn
-
Secrets Manager 代理允许的来自 HTTP 客户端的最大连接数,范围在 1 到 1000 之间。默认值为 800。
可选功能
通过将--features
标志传递给,可以构建 Secrets Manager Agent,使用可选功能cargo build
。可用功能有:
生成功能
prefer-post-quantum
-
生成优先级最高X25519MLKEM768
的密钥交换算法。否则,它可用,但不是最高优先级。 X25519MLKEM768
是一种混合 post-quantum-secure密钥交换算法。
fips
-
将代理使用的密码套件限制为 FIPS 批准的密码。
日志记录
- 本地日志
-
Secrets Manager 代理会在本地将错误记录到 stdout/stderr 中logs/secrets_manager_agent.log
,具体取决于配置变量。log_to_file
当应用程序调用 Secrets Manager 代理来获取密钥时,这些调用会显示在本地日志中。它们不会显示在 CloudTrail 日志中。
- 日志轮换
-
当文件达到 10 MB 时,Secrets Manager 代理会创建一个新的日志文件,并且总共最多存储五个日志文件。
- Amazon 服务日志
-
日志不会转到 Secrets Manager CloudWatch。 CloudTrail从 Secrets Manager 代理获取密钥的请求不会出现在这些日志中。当 Secrets Manager 代理调用 Secrets Manager 来获取密钥时,该调用会记录在 CloudTrail Secrets Manager 代理字符串中aws-secrets-manager-agent
。
您可以在中配置日志记录选项配置 Secrets Manager 代理。
安全性注意事项
- 信任域
-
对于代理架构,信任域是代理终端节点和 SSRF 令牌可访问的位置,通常是整个主机。为了保持相同的安全状况,Secrets Manager 代理的信任域应与 Secrets Manager 凭证可用的域相匹配。例如,在亚马逊 EC2 上,使用 Amazon 角色时,Secrets Manager 代理的信任域将与凭证的域相同 EC2。
如果应用程序具有安全意识并且尚未使用将 Secrets Manager 凭证锁定到应用程序的代理解决方案,则应考虑使用特定于语言 Amazon SDKs 或缓存的解决方案。有关更多信息,请参阅获取密钥。