使用代 Amazon Secrets Manager 理 - Amazon Secrets Manager
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功能的情况下构建代理需要以下解决方法:

  • 创建一个名为的环境变量SDKROOT,该变量设置为运行结果 xcrun --show-sdk-path

RPM-based systems
在基于 RPM 的系统上构建
  1. 使用存储库中提供的 install 脚本。

    该脚本在启动时生成一个随机的 SSRF 令牌并将其存储在文件 /var/run/awssmatoken 中。安装脚本创建的 awssmatokenreader 组可以读取该令牌。

  2. 要允许您的应用程序读取令牌文件,您需要将应用程序在其下运行的用户账户添加到 awssmatokenreader 组。例如,您可以使用以下 usermod 命令授予应用程序读取令牌文件的权限,其中<APP_USER>是应用程序在其下运行的用户 ID。

    sudo usermod -aG awssmatokenreader <APP_USER>
    安装开发工具

    在基于 RPM 的系统(如 AL2 023)上,安装 “开发工具” 组:

    sudo yum -y groupinstall "Development Tools"
  3. 安装 Rust

    按照 Rust 文档中安装 Rus t 中的说明进行操作:

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Follow the on-screen instructions . "$HOME/.cargo/env"
  4. 构建代理

    使用 cargo build 命令构建 Secrets Manager 代理:

    cargo build --release

    您将在 target/release/aws_secretsmanager_agent 下找到可执行文件。

Debian-based systems
在基于 Debian 的系统上构建
  1. 安装开发工具

    在基于 Debian 的系统(例如 Ubuntu)上,安装构建必需包:

    sudo apt install build-essential
  2. 安装 Rust

    按照 Rust 文档中安装 Rus t 中的说明进行操作:

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Follow the on-screen instructions . "$HOME/.cargo/env"
  3. 构建代理

    使用 cargo build 命令构建 Secrets Manager 代理:

    cargo build --release

    您将在 target/release/aws_secretsmanager_agent 下找到可执行文件。

Windows
在 Windows 上构建
  1. 设置开发环境

    请按照 Microsoft Windows 文档中的 Set up your dev environment on Windows fo r Rus t

  2. 构建代理

    使用 cargo build 命令构建 Secrets Manager 代理:

    cargo build --release

    您将在 target/release/aws_secretsmanager_agent.exe 下找到可执行文件。

Cross-compile natively
本机交叉编译
  1. 安装交叉编译工具

    在 mingw-w64 包可用的发行版(例如 Ubuntu)上,请安装交叉编译工具链:

    # Install the cross compile tool chain sudo add-apt-repository universe sudo apt install -y mingw-w64
  2. 添加 Rust 构建目标

    安装 Windows GNU 编译目标:

    rustup target add x86_64-pc-windows-gnu
  3. 为 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

重要

我们建议为构建环境提供 32GB 的磁盘空间。

  1. 设置 Docker

    安装和配置 Docker:

    # Install and start docker sudo yum -y install docker sudo systemctl start docker sudo systemctl enable docker # Make docker start after reboot
  2. 配置 Docker 权限

    将您的用户添加到 docker 群组:

    # Give ourselves permission to run the docker images without sudo sudo usermod -aG docker $USER newgrp docker
  3. 为 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
  1. 导航到配置目录

    切换到配置目录:

    cd aws_secretsmanager_agent/configuration
  2. 运行安装脚本

    运行存储库中提供的 install install 脚本。

    该脚本在启动时生成一个随机的 SSRF 令牌并将其存储在文件 /var/run/awssmatoken 中。安装脚本创建的 awssmatokenreader 组可以读取该令牌。

  3. 配置应用程序权限

    将运行应用程序的用户帐户添加到awssmatokenreader群组中:

    sudo usermod -aG awssmatokenreader APP_USER

    APP_USER替换为运行应用程序时使用的用户 ID。

Container Sidecar

您可以使用 Docker 将 Secrets Manager 代理作为附加容器与应用程序一起运行。然后,您的应用程序可以从 Secrets Manager 代理提供的本地 HTTP 服务器检索密钥。有关 Docker 的信息,请参阅 Docker 文档

为 Secrets Manager 代理创建附加容器
  1. 创建代理 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"]
  2. 创建应用程序 Dockerfile

    为您的客户端应用程序创建一个 Dockerfile。

  3. 创建 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
  4. 复制座席班次

    secrets-manager-agent 二进制文件复制到包含您的 Dockerfile 和 Docker Compose 文件的同一个目录中。

  5. 构建并运行容器

    使用 Docker Compose 构建并运行容器:

    docker-compose up --build
  6. 后续步骤

    您现在可使用 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 扩展
  1. 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')
  2. 配置 SSRF 令牌

    代理的默认配置会自动将 SSRF 令牌设置为在预设变量AWS_SESSION_TOKENAWS_CONTAINER_AUTHORIZATION_TOKEN环境变量中设置的值(后一个变量适用于启用的 Lambda 函数)。 SnapStart 或者,您可以改用您的 Lambda 函数的任意值定义AWS_TOKEN环境变量,因为该变量优先于其他两个变量。如果您选择使用AWS_TOKEN环境变量,则必须通过lambda:UpdateFunctionConfiguration调用来设置该环境变量。

  3. 将图层附加到函数

    将层版本附加到您的 Lambda 函数:

    # Attach the layer version to the Lambda function aws lambda update-function-configuration \ --function-name $LAMBDA_ARN \ --layers "$LAYER_VERSION_ARN"
  4. 更新函数代码

    更新您的 Lambda 函数以http://localhost:2773/secretsmanager/get?secretId=MyTest使用X-Aws-codes-Secrets-Token标头值设置为来自上述环境变量之一的 SSRF 令牌的值进行查询,以检索密钥。务必在应用程序代码中实现重试逻辑,以适应 Lambda 扩展初始化和注册中的延迟。

  5. 测试此函数

    调用 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 代理检索密钥的权限。

  • secretsmanager:DescribeSecret

  • secretsmanager:GetSecretValue

有关权限的更多信息,请参阅 的权限参考 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
  • 在 TTL 到期之前使用缓存值

  • 仅在 TTL 之后才刷新密钥(默认为 300 秒)

  • 如果密钥在缓存过期之前轮换,则可能会返回陈旧值

行为与 refreshNow=true
  • 完全绕过缓存

  • 直接从 Secrets Manager 中检索最新的密钥值

  • 使用新值更新缓存并重置 TTL

  • 确保您始终获得最新的秘密值

强制刷新密钥值

重要

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 或缓存的解决方案。有关更多信息,请参阅获取密钥