无AWS控制台权限时如何检查EC2是否关联正确的IAM策略
EC2实例IAM权限零额外权限校验方案
你不需要申请任何额外IAM权限就能完成权限校验,核心是利用AWS API本身的权限校验逻辑,不需要调用任何需要特殊权限的IAM模拟接口。
前置准备
SSH登录到目标EC2实例后,先确认aws cli可用,执行aws sts get-caller-identity,能正常返回当前实例绑定的角色ARN就说明凭证正常,实例角色的临时凭证会自动从EC2元数据服务获取,不需要手动配置AK/SK。
两种无额外权限的校验逻辑
1. 支持DryRun参数的写类API
所有支持--dry-run参数的API,调用时加上该参数后,AWS不会实际执行操作,只会先校验调用者权限:
- 返回*
DryRunOperation*错误:代表权限校验通过,你有对应操作的权限 - 返回*
UnauthorizedOperation*错误:代表缺少对应权限
这种方式不会产生任何资源变更,也不会产生费用。
2. 不支持DryRun的读类API
对于Describe、Get类的读接口,构造不会返回实际业务数据、参数格式合法的请求即可:
- 返回*
AccessDenied*类的权限错误:代表缺少对应权限 - 返回空结果集、或者
ResourceNotFound/InvalidParameterValue类的业务错误(非权限类):代表权限校验通过,只是你传入的资源不存在或者参数不匹配实际数据
这种方式同样不会拉取敏感数据,也不会产生费用。
针对你列出的待校验权限的具体校验方法
cloudwatch:GetMetricData - Resource: *
传入不存在的指标查询条件,时间范围设为未来时间,执行命令:
不报权限错误即代表有权限。aws cloudwatch get-metric-data --metric-data-queries '[{"Id":"dryrun-test","MetricStat":{"Metric":{"Namespace":"AWS/EC2","MetricName":"CPUUtilization"},"Period":300,"Stat":"Average"}}]' --start-time 2099-01-01T00:00:00Z --end-time 2099-01-02T00:00:00Zrds:DescribeExportTasks - Resource: *
传入随机生成的不存在的导出任务ID,执行命令:
不报权限错误即代表有权限。aws rds describe-export-tasks --export-task-identifier dryrun-nonexist-$RANDOMrds:StartExportTask - Resource: *
该接口支持DryRun,传入虚构的参数加--dry-run即可:
返回aws rds start-export-task --export-task-identifier dryrun-$RANDOM --source-arn arn:aws:rds:us-east-1:123456789012:snapshot:nonexist --s3-bucket-name dryrun-bkt-nonexist --iam-role-arn arn:aws:iam::123456789012:role/nonexist --dry-runDryRunOperation即代表有权限。rds:DescribeDBSnapshots - Resource: arn:aws:rds::region:account:snapshot:*
传入你账号对应区域下不存在的快照ID,执行命令:
不报权限错误即代表对该资源范围有权限。aws rds describe-db-snapshots --db-snapshot-identifier dryrun-snapshot-nonexist-$RANDOM
自动化校验脚本
你可以把上述逻辑整理成shell脚本,登录实例后直接执行就能批量输出校验结果:
#!/bin/bash set +e echo "=== EC2实例IAM权限批量校验 ===" echo "当前身份: $(aws sts get-caller-identity --query Arn --output text)" echo "----------------------------------------" # 校验cloudwatch:GetMetricData echo -n "[1/4] cloudwatch:GetMetricData (*): " err_msg=$(aws cloudwatch get-metric-data --metric-data-queries '[{"Id":"dryrun","MetricStat":{"Metric":{"Namespace":"AWS/EC2","MetricName":"CPUUtilization"},"Period":300,"Stat":"Average"}}]' --start-time 2099-01-01T00:00:00Z --end-time 2099-01-02T00:00:00Z 2>&1 >/dev/null) if [[ $err_msg == *"AccessDenied"* ]] || [[ $err_msg == *"UnauthorizedOperation"* ]]; then echo "❌ 缺失权限" else echo "✅ 权限正常" fi # 校验rds:DescribeExportTasks echo -n "[2/4] rds:DescribeExportTasks (*): " err_msg=$(aws rds describe-export-tasks --export-task-identifier dryrun-$RANDOM 2>&1 >/dev/null) if [[ $err_msg == *"AccessDenied"* ]] || [[ $err_msg == *"UnauthorizedOperation"* ]]; then echo "❌ 缺失权限" else echo "✅ 权限正常" fi # 校验rds:StartExportTask echo -n "[3/4] rds:StartExportTask (*): " err_msg=$(aws rds start-export-task --export-task-identifier dryrun-$RANDOM --source-arn arn:aws:rds:us-east-1:123456789012:snapshot:nonexist --s3-bucket-name dryrun-nonexist --iam-role-arn arn:aws:iam::123456789012:role/nonexist --dry-run 2>&1 >/dev/null) if [[ $err_msg == *"DryRunOperation"* ]]; then echo "✅ 权限正常" else echo "❌ 缺失权限" fi # 校验rds:DescribeDBSnapshots echo -n "[4/4] rds:DescribeDBSnapshots (arn:aws:rds::region:account:snapshot:*): " err_msg=$(aws rds describe-db-snapshots --db-snapshot-identifier dryrun-$RANDOM 2>&1 >/dev/null) if [[ $err_msg == *"AccessDenied"* ]] || [[ $err_msg == *"UnauthorizedOperation"* ]]; then echo "❌ 缺失权限" else echo "✅ 权限正常" fi echo "----------------------------------------"
注意事项
- 所有校验操作都不会产生实际资源变更,也不会产生云资源费用
- 校验指定资源范围的权限时,要确保请求参数落在你申请的资源范围内,避免出现资源范围不匹配导致的校验结果误差
- 不要使用
aws iam simulate-principal-policy、aws iam simulate-custom-policy这类接口做校验,这类接口本身需要你拥有IAM相关的操作权限,属于需要额外申请的权限,不符合你的需求
内容的提问来源于stack exchange,提问作者Lebanner
相关产品推荐
相关产品推荐

