aws-IAM身份
IAM
身份认证
核心要素
- 资源: 需要操作的对象
- 动作: 可以对这个对象 进行某些操作
- 身份: 谁
其它要素
- 策略: 也就是 权限, 即 资源+动作 的绑定;
- 角色: 身份集合, 可以把策略绑定给角色
- 用户
- 组
策略
- user-policy: 直接附加到单个 IAM 用户上的权限策略, 尽量少用
- group-policy: 附加到 IAM 用户组上的权限策略,组内所有用户继承该权限
- role-policy: 附加到 IAM 角色上的权限策略
一般模式
人员: group + group-policy 程序: role + role-policy CICD: Role Policy + OIDC
管理 cli
https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/cli_iam_code_examples.html
aws iam list-users
aws iam list-groups
aws iam list-roles
aws iam list-user-policies --user-name Bob
aws iam list-role-policies --role-name Test-Role
aws iam list-policies --max-items 3 # 可用的托管策略用户+组
aws iam create-user --user-name Bob
aws iam delete-user --user-name Bob
aws iam create-group --group-name MyTestGroup
aws iam delete-group --group-name MyTestGroup
aws iam add-user-to-group --user-name Bob --group-name Admins角色
# 创建角色 + 附加策略
aws iam create-role --role-name Test-Role \
--assume-role-policy-document file://Test-Role-Trust-Policy.json
aws iam delete-role --role-name Test-Role策略
aws iam delete-user-policy --user-name Bob --policy-name ExamplePolicy
aws iam delete-group-policy --group-name Admins --policy-name ExamplePolicy
aws iam delete-role-policy --role-name Test-Role --policy-name ExamplePolicy
aws iam delete-policy --policy-arn arn:aws:iam::123456789012:policy/MySamplePolicy
# 将策略附加到组
aws iam attach-group-policy --group-name Finance \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
# 将策略附加到角色
aws iam attach-role-policy --role-name ReadOnlyRole \
--policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
# 将策略附加到用户
aws iam attach-user-policy --user-name Alice \
--policy-arn arn:aws:iam::aws:policy/AdministratorAccess \
# 新建权限策略, 并附加到 IAM 角色
aws iam put-role-policy --role-name Test-Role \
--policy-name ExamplePolicy --policy-document file://AdminPolicy.json用户密码
# 更新当前用户密码, 注意不能是 root iam 用户;
# 先生成一个标准格式文件, 然后在文件内填入旧密码和新密码
aws iam change-password --generate-cli-skeleton > change-password.json
# 变更密码
aws iam change-password --cli-input-json file://change-password.json
# 修改其他用户的密码 - 需要管理员权限
aws iam update-login-profile --user-name user_name --password new_pw
# 修改其他用户的密码 - 需要管理员权限 - 下次登录必须修改
aws iam update-login-profile --user-name Bob \
--password "TemporaryP@ss123" --password-reset-requiredsts
# 获取当前身份
aws sts get-caller-identity --region ap-southeast-1
# # 获取当前账号ID
ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
# 验证当前使用的身份, 输出 ARN 地址
aws sts get-caller-identity
aws sts get-caller-identity --query Arn --output text审计
# 查看谁在 AssumeRole
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRoleWithWebIdentity \
--start-time "2024-01-01T00:00:00Z"特殊权限说明
iam:PassRole
授权, 授权这个系统可以使用自己 角色的权限
一般可以通过 --role-arn xxxx 参数进行显式指定授于的角色
{
"Version": "2012-10-17",
"Statement": [
// 传递角色权限, 如果要创建资源, 必须要能传递自身的权限
{
"Effect": "Allow",
"Action": "iam:PassRole", // 允许传递 IAM 角色
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PassedToService": "eks.amazonaws.com" // 角色只能传递给 EKS 服务
}
}
}
]
}凭证使用
操作场景
- 人工 ui 操作: 账号 + 密码 + 二次验证
- 本地 cli: aws_access_key_id + aws_secret_access_key
- 生产环境程序: 不注入任何密码和 key 信息, 程序从环境中获取身份
本地环境
-
方式 1: aws_access_key_id + aws_secret_access_key 有特权的长期凭证
-
方式 2: aws_access_key_id + aws_secret_access_key 无特权的长期凭证 + 通过 sts api AssumeRole 获取短期临时凭证 aws_session_token;
~/.aws/credentials
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws_session_token = xxxxxxxxxxenv 注入
AWS_ACCESS_KEY_ID=x
AWS_SECRET_ACCESS_KEY=x
AWS_SESSION_TOKEN=x# 临时切换到一个角色(AssumeRole), 返回结果中包含 SessionToken
aws sts assume-role \
--role-arn "arn:aws:iam::123456789012:role/MyRole" \
--role-session-name "MySession"从环境中获取身份
将一个 IAM 角色 附加到这些计算资源上 运行在该资源上的 AWS SDK 会自动通过实例元数据服务 (IMDS) 或容器凭证端点来获取临时的, 动态刷新的凭证
对于 aws 原生资源(ec2 等) 默认有一个 IAM 角色; 所以实际是将权限 附加策略 给默认 IAM 角色
# EC2 实例元数据服务, 也会获取到 AWS_SESSION_TOKEN
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/MyRolesdk_auth
不要在代码或配置文件里存储任何 Access Key 程序里面只需要使用默认方法创建客户端即可;
import boto3
s3 = boto3.client('s3') # 直接创建客户端import software.amazon.awssdk.services.s3.S3Client;
S3Client s3 = S3Client.create(); // 直接创建客户端, 无需任何凭证相关配置import "github.com/aws/aws-sdk-go-v2/service/s3"
client := s3.NewFromConfig(aws.Config{Region: "us-west-2"}) // 直接创建客户端原理
SDK 会按照预定义的顺序检查一系列位置来寻找凭证, 一旦找到有效的凭证就停止搜索
EKS Pod Identity
在 Pod 内启动了一个本地代理(Agent)来负责凭证的获取和刷新
- 注入环境变量 当 Pod 启动时, EKS 集群会自动向 Pod 注入特定的环境变量和挂载卷 AWS_CONTAINER_CREDENTIALS_FULL_URI 指向节点上 Agent 的本地地址 (http://169.254.170.23/v1/credentials
AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE 指向一个服务账户令牌文件
-
SDK 在默认凭证链中, 会发现 AWS_CONTAINER_CREDENTIALS_FULL_URI 这个环境变量, 从而知道应该向本地的 Agent 请求凭证
-
Agent 代理请求: Agent 收到 SDK 的请求后, 会使用挂载的令牌文件, 通过调用 EKS Auth API 的 AssumeRoleForPodIdentity 接口, 来获取与 Pod 服务账户关联的 IAM 角色的临时凭证
-
返回临时凭证: Agent 将获取到的临时凭证返回给 SDK
IRSA (IAM Roles for Service Accounts)
让 SDK 直接与 AWS STS 服务交互来换取凭证, 没有本地代理, 需要集群拥有 OIDC 终端节点
-
注入环境变量: 集群的 Webhook 会自动为 Pod 注入以下环境变量; AWS_ROLE_ARN: 需要扮演的 IAM 角色 ARN; AWS_WEB_IDENTITY_TOKEN_FILE: 指向一个 OIDC 令牌文件的路径;
-
SDK 交换令牌: 应用程序的 SDK 在默认凭证链中, 会发现 AWS_WEB_IDENTITY_TOKEN_FILE 和 AWS_ROLE_ARN 环境变量, 于是知道需要通过 OIDC 方式获取凭证;
-
调用 STS 服务: SDK 会读取令牌文件内容, 然后直接调用 AWS STS 服务的 AssumeRoleWithWebIdentity API, 将令牌发送给 STS 服务以交换临时凭证;
-
使用临时凭证: STS 服务验证令牌后, 返回临时凭证给 SDK, SDK 随后使用这些凭证调用 AWS 服务
EKS Pod Identity
较新的, 更简单的方案, 无需配置 OIDC
- 安装 EKS Pod Identity 代理: 确保集群已安装 eks-pod-identity-agent 插件
- 创建 IAM 角色, 附加业务策略, 角色的信任策略 (Trust Policy) 需要允许 Pod Identity 服务代为获取凭证
- 创建 Pod Identity 关联: 将 IAM 角色与特定的 Kubernetes 服务账户 (Service Account) 关联起来
- 在 Pod 中指定服务账户: 在 Pod 的 YAML 文件中, 通过 serviceAccountName 字段指定上述服务账户
定义 IAM 角色的信任策略 (Trust Policy) 是明确谁(AWS 服务)可以扮演(Assume)这个角色
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowEksAuthToAssumeRoleForPodIdentity",
"Effect": "Allow",
"Principal": {
// 授权 EKS 的 Pod Identity 服务本身来扮演此角色
"Service": "pods.eks.amazonaws.com"
},
"Action": [
"sts:AssumeRole", // 允许执行角色扮演操作
// 允许在扮演角色时添加会话标签(Session Tags)
// 这些标签可以用于在 IAM 策略中实施更细粒度的权限控制(ABAC)
"sts:TagSession"
],
// 可选条件限制
"Condition": {
"StringEquals": {
"aws:RequestTag/kubernetes-namespace": ["your-namespace"],
"aws:RequestTag/kubernetes-service-account": ["your-service-account"]
}
}
}
]
}创建 Pod Identity 关联:
将创建好的 IAM 角色, 与你 Kubernetes 集群中的服务账户(ServiceAccount)绑定起来
aws eks create-pod-identity-association \
--cluster-name your-cluster-name \
--namespace your-namespace \
--service-account your-service-account \
--role-arn arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>