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 身份验证
135KB
2.5K SLoC
Needroleshere - 又一个 AWS IAM Roles Anywhere 辅助工具
这是一个用于通过 X.509 证书及其对应私钥获取凭证的 AWS IAM Roles Anywhere 辅助程序。它可以很好地替换官方的 rolesanywhere-credential-helper,具有以下优点:
- 支持加载包含终端实体证书及其中间 CA 证书的完整链证书 PEM 文件。
- 支持 SDK 和库的 ECS 容器凭证提供程序,这些 SDK 和库没有进程凭证提供程序支持。
安装
- Cargo:
cargo install needroleshere
- 架构:
yay -Sy needroleshere
[AUR] - Debian/Ubuntu: https://github.com/nkmideb/needroleshere/releases (nekomit-originals 仓库)
用法
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.service
和 needroleshere.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
,它将成为HTTPAuthorization
头。由于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哈希函数,而不管曲线的字段大小如何,但ecdsa
crate将哈希函数的使用限制为与曲线长度匹配,因此我们必须使用原始实现来强制使用SHA-256...
- 对于P-256曲线以外的曲线的EC密钥,将使用
- 服务器模式旨在主要用于服务器和与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