最近花了些时间将服务的 AKSK 切换为 Role 认证方式,本篇博文对 AWS Role 及 AssumeRole 的一些知识点整理如下。
什么是 AWS Role?
先从 AWS AKSK 说起,以往程序使用 S3、SQS 等 AWS 服务,一般是通过 KeyID、Secret Access Key 进行鉴权,好处是使用方便,但无法避免安全问题,一旦泄露就会对服务安全构成威胁。
使用 Role 可以解决这一问题,AWS 的 EC2 和 ECS Task 等资源都可以绑定 Role,从近期改造 Jenkisn、Golang、Vector 的配置从 AKSK 到 Role 来看,使用 Role 很方便。
备忘记录。
什么是 AssumeRole?
AssumeRole是AWS Identity and Access Management(IAM) 中的一个 API 操作,他允许一个 AWS 角色(Role) 临时地假设另一个角色,从而获得该角色的权限。当你需要一个 AWS 角色临时获得另一个角色的权限时,可以调用 AssumeRole API,让该角色假设目标角色身份,实现跨账号访问。
一个说不定有用的小 Tips:一个 Role 授权允许的情况下可以 AssumeRole 到自身,当多个服务公用配置的时候很灵活。
以下是几个使用 Role 的场景
场景1:ECS Task 内拉取 Code Commit 配置
在这个场景下,Git CodeCommit 插件自动使用本机 Role 信息,即 Task Role,所以需要 ECS Task Role 具备访问 CodeCommit 的权限,Git 配合 CodeCommit 插件无需任何配置,即可使用本机的的权限。
补充:通过设置 AWS_ROLE_ARN
和 AWS_ROLE_SESSION_NAME
两个环境变量,可以让 git-remote-codecommit 插件 AssumeRole 到其他角色。
场景2:ECS Task 内使用 Vector 上报 S3
在 ECS Task 的 Vector 容器中,将收集到的日志发送到 S3,需要注意的是 S3 和 Vector 服务不在一个账号内。
Vector 服务跟 CodeCommit 插件的不同是,CodeCommit 自动使用本机的 Task Role,而 Vector 可以指定 assume_role,这样,我们可以在 S3 所在区域创建一个 IAM Role,为其赋予读写 S3 的权限。
再赋予 ECS Task Role 权限,使其能够具备 AssumeRole 的能力。这样,Vector 使用 Task Role 自动切换到 S3 Role,具备读写 S3 的能力。
场景3:EC2 下 Jenkins 使用 Role
Jenkins 在使用 Jenkinsfile 调用 ansible 部署服务到正式环境时,使用 Role 进行认证。
使用 AWS 插件提供的 withAWS
step,可以指定 Role 信息,跟 Vector 中指定 Assume Role 是类似的,需要 EC2 的基础 Role 具备切换为指定 Role 的权限,使得 ansible 具备访问 ECR / ECS 的能力。
EC2 和 ECS Task 配置 Role 在使用上有无区别?
通过在不同场景的实践,可以得出以下结论
- ECS Task Role 可以理解为 EC2 Role,在使用 Role 上没有区别。
- 如果 Task 未绑定 ECS Task Role,那么在 Task 的容器内部获取到的 Role 即部署 Task 的 EC2 的 Role。
- 如果 Task 绑定了 ECS Task Role,那么在 Task 的容器内部获取到的 Role 是 ECS Task Role。
通过 AWS CLI 获取本机绑定的 Role
首先,安装 aws-cli 后需要先配置地区,AKSK 不用填写,回车即可。
[root@jumpserver ~]# aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]: json
而后获取当前身份
$ aws sts get-caller-identity
输出
{
"UserId": "AROA772VM***N4XQO3LPZ:i-0d8426c3***12cb43",
"Account": "AIOAM62***2S712R83HN",
"Arn": "arn:aws-cn:sts::AIOAM62***2S712R83HN:assumed-role/Role-allprompts-server-dev/i-0d843273d0b24cc2z"
}
测试其是否有 AssumeRole 到指定 Role 的权限
AssumeRole 即程序可以借助当前机器的 Role,切换到另一个 Role,是否有权限切换,由绑定在机器上的 Role 权限决定。
$ aws sts assume-role --role-arn "arn:aws-cn:iam::AIOAM62***2S712R83HN:role/1122_server_ec2_dev_role" --role-session-name AWSCLI-Session
输出
{
"Credentials": {
"AccessKeyId": "AIOAM62V***S712R83HN",
"SecretAccessKey": "5CxQrfX/uS/1hWdibOe***IXaDd3PcWiEuK6CJ",
"SessionToken": "IQoJb3JpZ2luX2VjEH0aDmNuLW5vcnRod2VzdC0xIkYwRAIgJvRuKxDuJP25EzpuYudzpz+qmpbG3uotBHi2m2jy5MoCIGa1nvUJIWsRsP8JAO9Ta+5/FSRMjgjW9/GTF20qL1eDKqQCCKr//////////wEQCRoMNDc4NTMxMDkyMTMzIgzEorI2dnFAqUshHMcq+AF1Y9+mouNZqhF94m/9d+vDfiy7abKXGsGflSjq72CdPl/UpsBUWIQ2GHONhrJQGY8yRmijNUwM/6Zertnut7wHWitMS8arLLfpdKFXyLA7GHGJSFhD/wOa4jP0FvxmHmosN8J3hbXEsq9RMHo6RvMGECcxp4cAT9eBduYaHDT+DzXtrGNZcQpyNW4BSVSCQwIWCmR2M3h/UtSD9QXdjU0X1IYMNMl3De0N6******5GVxI9Cs1nA35PohFpmpkTmpzS0nBHccke/xq/oaMiNEz30JuNKm64YvGmCpAt364bSsfUl6RHbY/AMVP2zvCIzQhsi8ajD0mvmlBjqeAftg+mEKFlUhQurdjSEn9V7D9xpRwJjHf/3K0gZx******U7fAs9rn2lr1XAXwMDC0RdwkPQCpZifj9swhR1EoKGHO37jyWY9irZvMrI0TCz/GH7kPFbiUuyDbCtN/bqWA7iROsewfFEWtZw6PdysM0jwzo5R7rGtytfV0hHaa81IGkRnb5bh0ElSV4/M6Hj1GyAWAEetEIGa3irz7",
"Expiration": "2023-07-24T11:07:48+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "NOZAW62V88***ZLOG8SDK:AWSCLI-Session",
"Arn": "arn:aws-cn:sts::AIOAM62***2S712R83HN:assumed-role/1122_server_ec2_dev_role/AWSCLI-Session"
}
}
正确输出如上,即机器绑定的 Role 允许用户或程序切换使用 1122_server_ec2_dev_role 角色。反之会提示权限错误
测试角色是否有 S3 权限
$ aws s3 ls s3://my-bucket
如果当前机器 Role 拥有权限,则会输出目录,一般在使用时,也倾向于机器上配置比较基础的 Role,访问资源时 AssumeRole 到资源 Role,这样权限解耦,同时也能应对跨账号问题。
假设我们的机器绑定的是很基础的 Role,没有访问 S3 的权限,需要 AssumeRole 到指定 Role,如何通过 AWS CLI 模拟呢?
需要使用小节命令 aws sts assume-role ...
获取到的 Token,设置环境变量
$ export AWS_ACCESS_KEY_ID=AIOAM62VN72S712R83HN
$ export AWS_SECRET_ACCESS_KEY=5CxQrfX/uS/1hWd******Y0aIXaDd3PcWiEuK6CJ
$ export AWS_SESSION_TOKEN=IQoJb3JpZ2luX2VjEH0aDmNuLW5vcnRod2VzdC0xIkYwRAIgJvRuKxDuJP25EzpuYudzpz+qmpbG3uotBHi2m2jy5MoCIGa1nvU******P8JAO9Ta+5/FSRMjgjW9/GTF20qL1eDKqQCCKr//////////wEQCRoMNDc4NTMxMDkyMTMzIgzEorI2dnFAqUshHMcq+AF1Y9+mouNZqhF94m/9d+vDfiy7abKXGsGflSjq72CdPl/UpsBUWIQ2GHONhrJQGY8yRmijNUwM/6Zertnut7wHWitMS8arLLfpdKFXyLA7GHGJSFhD/wOa4jP0FvxmHm******Esq9RMHo6RvMGECcxp4cAT9eBduYaHDT+DzXtrGNZcQpyNW4BSVSCQwIWCmR2M3h/UtSD9QXdjU0X1IYMNMl3De0N6WMG1OrxYIA05GVxI9Cs1nA35PohFpmpkTmpzS0nBHccke/xq/oaMiNEz30JuNKm64YvGmCpAt364bSsfUl6RHbY/AMVP2zvCIzQhsi8ajD0mvmlBjqeAftg+mEKFlUhQurdjSEn9V7D9xpRwJjHf/3K0gZxchS2bpQHU7fAs9rn2lr1XAXwMDC0******CpZifj9swhR1EoKGHO37jyWY9irZvMrI0TCz/GH7kPFbiUuyDbCtN/bqWA7iROsewfFEWtZw6PdysM0jwzo5R7rGtytfV0hHaa81IGkRnb5bh0ElSV4/M6Hj1GyAWAEetEIGa3irz7
而后再次执行命令,即可查询 S3 桶下目录。
备注:如需要进一步确认可写权限,可以使用如下命令
$ echo "test file" > test_file.txt
$ aws s3 cp test_file.txt s3://my-bucket/test_file.txt
测试角色是否有 SQS 权限
$ aws sqs get-queue-url --queue-name user_identity_event
结果
{
"QueueUrl": "https://sqs.cn-northwest-1.amazonaws.com.cn/AIOAM62***2S712R83HN/user_identity_event"
}
AssumeRole 使用方式跟 S3 使用临时 Token 的方式同理。
总结
最后,Role 和 AssumeRole 的使用容易,但要避免混乱的权限分配,角色的命名和使用也需要设计一套方案来约束,保障安全的同时也便于维护。