#aws-sdk #amazon-iam #aws #aws-credentials #role #certificate #container

bin+lib needroleshere

又一个 AWS IAM Roles Anywhere 辅助工具

5 个版本 (3 个重大更新)

0.4.0 2023年11月4日
0.3.0 2022年9月30日
0.2.0 2022年9月29日
0.1.1 2022年9月29日
0.1.0 2022年9月29日

#194 in 身份验证

Apache-2.0

135KB
2.5K SLoC

Needroleshere - 又一个 AWS IAM Roles Anywhere 辅助工具

crates.io build status dependency status

这是一个用于通过 X.509 证书及其对应私钥获取凭证的 AWS IAM Roles Anywhere 辅助程序。它可以很好地替换官方的 rolesanywhere-credential-helper,具有以下优点:

  • 支持加载包含终端实体证书及其中间 CA 证书的完整链证书 PEM 文件。
  • 支持 SDK 和库的 ECS 容器凭证提供程序,这些 SDK 和库没有进程凭证提供程序支持。

安装

用法

Needroleshere 提供以下模式:

  • process-credentials:处理凭证提供程序模式
  • server + ecs-full:使用 AWS_CONTAINER_CREDENTIALS_FULL_URI + AWS_CONTAINER_AUTHORIZATION_TOKEN 的容器凭证提供程序模式
  • server + ecs-full-query:使用 AWS_CONTAINER_CREDENTIALS_FULL_URI 的容器凭证提供程序模式
  • server + ecs-relative:使用 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI + AWS_CONTAINER_AUTHORIZATION_TOKEN 的容器凭证提供程序模式
  • server + ecs-relative-query:使用 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 的容器凭证提供程序模式

比较将在稍后解释。

处理凭证提供程序模式(process-credentials

Needroleshere 充当 AWS SDK 中定义的 处理凭证提供程序 的凭证辅助程序。

这可以作为官方和原始 rolesanywhere-credential-helper 的直接替换,因为该工具支持 相同的参数和使用方式

https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html

[profile myrole]
    credential_process = needroleshere credential-process --certificate /path/to/certificate.pem --private-key /path/to/private-key.pem --trust-anchor-arn arn:aws:rolesanywhere:region:account:trust-anchor/TA_ID --profile-arn arn:aws:rolesanywhere:region:account:profile/PROFILE_ID --role-arn arn:aws:iam::account:role/role-name-with-path

与原始版本相比,Needroleshere 的优势在于传递给 --certificate 的证书 PEM 文件可以包含多个证书,因此如果您有中间 CA 并将这些证书放入一个文件中(例如 fullchain.pem),则不需要使用 --intermediates

服务器模式(《serve》)

服务器模式运行一个 HTTP 服务器,充当其他 AWS SDK 凭据提供者,以便使用不支持凭据提供者的 SDK 和库。目前实现了 ECS 容器凭据提供者。

运行服务器

Needroleshere 支持通过 systemd 套接字激活(仅限)启动。配置 systemd 单元如下

# /etc/systemd/system/needroleshere.service
[Unit]
Wants=needroleshere.socket

[Service]
Type=simple
ExecStart=/usr/bin/needroleshere serve --region AWS_REGION
RuntimeDirectory=needroleshere
# /etc/systemd/system/needroleshere.socket
[Socket]
ListenStream=127.0.0.1:7224
FreeBind=yes
IPAddressAllow=localhost
IPAddressDeny=any

[Install]
WantedBy=sockets.target

根据需要指定 User=Group=。完整的示例单元文件(监听 196.254.170.2:80)可在 ./contrib/systemd 下找到。

用作 ECS 容器凭据提供者

服务器模式支持 ECS 容器凭据提供者。要使用此提供者,您首先需要使用辅助命令生成绑定配置和环境变量文件。

此提供者支持在单个服务器进程中使用多个角色。

生成绑定
needroleshere bind myrole \
  --mode ecs-full \
  --url http://127.0.0.1:7224 \
  --certificate /path/to/certificate.pem \
  --private-key /path/to/private-key.pem \
  --trust-anchor-arn arn:aws:rolesanywhere:region:account:trust-anchor/TA_ID \
  --profile-arn arn:aws:rolesanywhere:region:account:profile/PROFILE_ID \
  --role-arn arn:aws:iam::account:role/myrole \
  --configuration-directory /path/to/etc/needroleshere

这将在 /path/to/etc/needroleshere/bindings/myrole 生成配置文件,并在 /path/to/etc/needroleshere/env/myrole 生成环境文件。将环境文件视为机密信息,因为它包含 Needroleshere 和凭据消费者之间的共享密钥。

  • --configuration-directory 默认为 $RUNTIME_DIRECTORY,如果没有指定。
  • 可以使用 --mode 指定模式变体。例如,指定 --mode ecs-relative-query 以激活仅使用 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 的模式。

通过 systemd 单元运行是推荐的方式

# /etc/systemd/system/needroleshere-bind-somethingawesome.service
[Unit]
Before=somethingawesome.service
After=needroleshere.socket
PartOf=somethingawesome.service
Wants=needroleshere.socket needroleshere.service

[Service]
Type=oneshot
RemainAfterExit=yes
# use of --no-validate is recommended if you run `bind` in a systemd unit
ExecStart=/usr/bin/needroleshere bind somethingawesome --no-validate ...
ExecStop=/usr/bin/needroleshere unbind somethingawesome

# Can't use RuntimeDirectory here
# https://github.com/systemd/systemd/issues/5394
Environment=RUNTIME_DIRECTORY=/run/needsrolehere

[Install]
WantedBy=somethingawesome.service

# and run systemctl enable needroleshere-bind-somethingawesome.service, or specify Wants= in somethingawesome.service
加载环境文件并使用
# /etc/systemd/system/somethingawesome.service

[Unit]
# You can specify Wants= here instead of systemctl enable:
# Wants=needroleshere-bind-somethingawesome.service

[Service]
Type=simple
EnvironmentFile=/run/needroleshere/env/somethingawesome
ExecStart=...

needroleshere-bind-somethingawesome.serviceneedroleshere.socket 将在 somethingawesome.service 启动之前自动启动。如果您重新启动 somethingawesome.service,则 needroleshere bind 将自动重新运行以旋转共享密钥(归功于 PartOf=)。

模式之间的比较

兼容性矩阵

  进程凭据 ecs-full ecs-full-query ecs-relative ecs-relative-query
AWS CLI v2
AWS SDK for C++
AWS SDK for Go V2 (1.x)
AWS SDK for Go 1.x (V1)
AWS SDK for Java 2.x
AWS SDK for Java 1.x
AWS SDK for JavaScript 3.x
AWS SDK for JavaScript 2.x
AWS SDK for .NET 3.x
AWS SDK for PHP 3.x
AWS SDK for Python (Boto3)
AWS SDK for Ruby 3.x ✅ *1 ✅ *1 ✅ *1 
AWS SDK for Rust (preview)
Rusoto
minio-go  
雾-aws        

*1 Ruby v3:aws-sdk-core 3.171.0(发布于2023-03)增加了对ecs-full、ecs-full-query和ecs-relative模式的支持 https://github.com/aws/aws-sdk-ruby/pull/2837

process-credentials是最受欢迎且简单的方法,最后的选择是使用ecs-relative-query

  • ecs-*类型有-query变体,用于防止使用AWS_CONTAINER_AUTHORIZATION_TOKEN,因为某些SDK不支持。注意,-query变体不提供SSRF保护。
  • ecs-relative*模式需要特殊的服务器进程配置来监听169.254.170.2:80

安全模型

  • 在服务器模式下,服务器进程必须能够代表凭证消费者读取私钥。此外,needroleshere bind命令也需要能够读取密钥,除非使用--no-validate
    • 为了允许带有密钥轮换的证书续订,服务器进程在每次请求中读取和解析证书和密钥文件。
  • 在ECS容器凭证提供程序模式下,端点使用访问令牌来区分角色绑定并验证其消费者。访问令牌基于在needroleshere bind期间生成的共享密钥。
    • 将秘密的SHA-384摘要存储到角色绑定数据文件中,并从服务器进程读取,明文秘密存储到环境文件中。
    • 因此,请将环境文件视为秘密并相应地保护它。needroleshere bind在后续运行中保留环境文件的文件模式和所有者,以用于现有角色绑定。
    • -query模式变体使用HTTP URL查询字符串传递访问令牌,而不是使用AWS_CONTAINER_AUTHORIZATION_TOKEN,它将成为HTTP Authorization头。由于AWS_CONTAINER_CREDENTIALS_*_URI不被视为秘密,因此它可能在请求失败时泄露到日志中。并且由于端点使用HTTP GET方法,它可能通过SSRF攻击进行利用。
    • 作为一种保护措施,对于使用AWS_CONTAINER_AUTHORIZATION_TOKEN的角色绑定,端点拒绝带有HTTP查询字符串中访问令牌的请求。

注意事项

  • 仅支持RSA、P-256、P-384密钥。
  • AWS4-X509-*-SHA256算法的签名者实现使用来自RustCrypto的crate。如果您使用此工具与EC密钥一起使用,请参阅他们的安全警告
    • 对于P-256曲线以外的曲线的EC密钥,将使用hazmat特性背后的原始实现;因为AWS4-X509-ECDSA-SHA256要求在ECDSA中使用SHA-256哈希函数,而不管曲线的字段大小如何,但ecdsacrate将哈希函数的使用限制为与曲线长度匹配,因此我们必须使用原始实现来强制使用SHA-256...
  • 服务器模式旨在主要用于服务器和与systemd一起使用。支持非服务器使用此模式超出了本项目的范围。
    • 特别是,ECS相关URI模式需要监听:80的权限。我们目前没有计划实现易于使用的隐式助手来支持从非root用户启动,就像在aws-vault中那样。
  • 服务器模式可以使用每个进程的单个AWS区域。`needroleshere bind`确实接受`--region`参数,但它仅用于在它上进行的配置验证。
  • 服务器模式每次请求读取一个证书和密钥。这允许在不需要重新加载/重启服务器进程的情况下进行证书更新。
  • 请注意,systemd.exec指出,不建议使用EnvironmentFile=来存储凭证。

systemd单元的示例配置

有关systemd单元的完整示例配置,请参阅./contrib/systemd/

开发

服务器

使用systemfd和cargo-watch运行。以下是在127.0.0.1:3000上启动的简写

./dev/serve.sh

要测试凭证提供程序是否正常工作,请使用以下脚本;它使用给定参数运行`needroleshere bind`并将其传递给`aws sts get-caller-identity`。

./dev/roundtrip-gci.sh --region ap-northeast-1 \
  --trust-anchor-arn TA_ARN \
  --profile-arn PROFILE_ARN \
  --role-arn ROLE_ARN \
  --private-key path/to/key.pem \
  --certificate path/to/fullchain.pem \
  --no-validate \
  --mode ecs-full

许可协议

本项目采用Apache-2.0许可协议。

版权所有2022 Sorah Fukumori

  • src/sign.rs包含来自aws-sigv4 crate的原始源代码,该源代码也采用Apache License 2.0。
    • 版权所有Amazon.com, Inc.或其附属公司。保留所有权利。
  • src/ecdsa_sha256.rs包含来自ecdsa crate的原始源代码,该源代码也采用Apache License 2.0。
    • 版权所有2018-2022 RustCrypto开发者

依赖项

~20–37MB
~622K SLoC