故障排除:AWS CLI 中的“访问被拒绝”和身份验证问题
在使用 AWS 命令行界面 (CLI) 时遇到 Access Denied 错误或意外的身份验证失败,是开发人员和系统管理员面临的最常见障碍之一。这些问题几乎总是源于身份和访问管理 (IAM) 策略配置错误、临时凭证过期或 CLI 环境设置不正确。
成功解决这些错误需要采取系统化的方法,首先确认您的身份和凭证,然后深入评估 IAM 策略。本综合指南提供了可操作的步骤和诊断命令,以快速识别和纠正 AWS CLI 中常见的授权问题,确保您可以有效地管理您的资源。
1. 初步诊断:识别调用方和凭证
在深入研究复杂的策略分析之前,第一步是明确确认 AWS CLI 正在使用哪个 IAM 身份以及这些凭证是否仍然有效。
检查当前身份:sts get-caller-identity
这是最关键的诊断命令。它确切地告诉您哪个用户 ARN、角色 ARN 或假设的角色会话正在执行后续的 AWS 命令。
aws sts get-caller-identity
预期输出:
{
"UserId": "AIDAIAMUSERID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/DevUser"
}
如果返回的 ARN 与您预期的用户或角色不符,则说明您正在使用错误的 AWS 配置文件或环境变量进行操作。
验证配置文件和区域设置
确保使用了正确的 AWS 配置文件,无论是通过 --profile 标志指定还是通过 AWS_PROFILE 环境变量设置。
# 检查默认配置文件的设置
aws configure list
# 或检查特定配置文件
aws configure list --profile prod-admin
如果输出显示没有区域或区域不正确,则对全局资源或特定区域服务(如 S3 存储桶或 EC2 实例)的操作可能会失败,如果 CLI 查找的资源不存在,有时会导致 Access Denied。
提示: 如果
sts get-caller-identity命令本身因身份验证错误而失败,则表明访问密钥存在根本性问题(它们可能已被删除、撤销或不正确)。
处理临时凭证
如果您正在使用 IAM 角色(通过 STS AssumeRole),CLI 使用的临时凭证包含一个 SessionToken。这些凭证会过期(通常为 1 小时)。虽然 AWS CLI 在从标准凭证提供程序链获取时通常会自动刷新它们,但手动配置可能会失败。
症状: 命令最初有效,但在设定时间后(例如 60 分钟)因身份验证错误而失败。
解决方案: 如果使用自定义脚本或手动加载的环境,请确保您的假设角色方法包含在凭证过期时刷新凭证的机制。
2. 深入研究 IAM 策略和授权
确认所使用的身份后,下一步是确定该身份为何缺乏必要的权限。AWS 授权失败很复杂,因为多个策略会同时进行评估。
IAM 策略评估层级结构
授权错误通常是由于以下任一策略组件导致的:
- 显式拒绝: 任何适用策略(身份、资源或边界)中的显式
Deny语句始终会覆盖Allow语句。 - 缺少允许: 没有适用于身份或资源的策略授予特定操作权限。
A. 基于身份的策略(用户和角色)
检查直接附加到用户或所假设角色的 IAM 策略。查找以下内容:
- 缺少操作: 策略是否明确列出了必要的 API 操作(例如
s3:ListBucket、ec2:DescribeInstances)? - 资源限制: 策略是否使用
Resource元素将操作限制在特定资源上?一个常见的错误是设置Resource: "*",而操作需要特定的 ARN,反之亦然。 - 条件: 是否存在未满足的条件(例如源 IP 地址、一天中的时间、需要 MFA)?
B. 基于资源的策略(S3、SQS、KMS)
对于 S3 或 KMS 等服务,资源本身具有策略,规定了谁可以访问它。即使您的 IAM 用户策略明确允许访问,资源策略也必须允许用户执行该操作。
示例: 尝试访问一个 S3 存储桶(资源策略),该存储桶对特定 VPC 端点之外的所有用户有显式 Deny,将导致 Access Denied,无论用户的 IAM 策略如何。
C. 权限边界和 SCP
如果您的组织使用 AWS Organizations,服务控制策略 (SCPs) 定义了账户内允许的最大权限。同样,权限边界限制了 IAM 实体可能拥有的最大权限。
如果 SCP 或边界拒绝了所需的操作,即使身份策略授予了权限,CLI 操作也会失败。
实用工具:IAM 策略模拟器
在对复杂故障进行故障排除时,AWS 管理控制台中的 IAM 策略模拟器非常宝贵。您可以针对特定资源(例如 arn:aws:s3:::my-bucket/key)测试特定操作(例如 s3:GetObject),并指定 IAM 实体,从而帮助您准确定位导致拒绝的具体策略语句。
3. 常见的“访问被拒绝”场景和解决方案
场景 1:S3 访问被拒绝(资源与身份)
S3 Access Denied 非常有名,因为它可能源于用户策略或存储桶策略。
| 原因 | 诊断 | 解决方案 |
|---|---|---|
| 缺少存储桶策略允许 | sts get-caller-identity 工作正常,但 aws s3 ls 失败。 |
修改存储桶策略,明确允许调用方 ARN 执行必要的操作(s3:ListBucket、s3:GetObject)。 |
| 缺少 KMS 解密权限 | 访问加密对象失败(即使 S3 策略允许)。 | 确保 IAM 实体具有使用加密对象的底层 KMS 密钥(kms:Decrypt)的权限。 |
| 请求者付费 | 尝试下载大文件失败。 | 如果存储桶要求 Requester Pays,CLI 命令必须包含 --request-payer requester 标志。 |
场景 2:条件失败导致的隐式拒绝
许多策略使用条件来执行安全最佳实践,例如要求多重身份验证 (MFA)。
如果您的策略包含如下条件:
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
并且您尝试在未经 MFA 身份验证的情况下运行命令,该操作将被隐式拒绝。
解决方案: 对于需要 MFA 的命令,您必须首先使用您的 MFA 设备进行身份验证并创建 STS 会话:
# 1. 使用您的 MFA 令牌获取临时凭证
aws sts get-session-token --serial-number arn:aws:iam::123456:mfa/user --token-code 123456
# 2. 将产生的 AccessKeyId、SecretAccessKey 和 SessionToken 作为环境变量导出,供您的 CLI 会话使用。
场景 3:缺少或不正确的区域
尽管不总是 Access Denied 错误,但在不指定正确区域的情况下尝试对资源执行操作,通常会导致授权或资源未找到失败,尤其是在处理 EC2、DynamoDB 或 EKS 等区域性服务时。
解决方案: 在命令中明确定义区域,或确保您的配置文件设置正确。
aws ec2 describe-instances --region us-west-2
4. 诊断命令摘要
使用此命令清单来快速诊断授权失败链:
| 目标 | 命令 | 用途 |
|---|---|---|
| 验证身份 | aws sts get-caller-identity |
确认执行命令的 ARN。 |
| 验证配置 | aws configure list |
检查配置文件设置、区域和输出格式。 |
| 测试策略有效性 | (使用 IAM 策略模拟器) | 检查 IAM 身份是否可以对资源执行特定的 API 操作。 |
| 识别策略拒绝 | aws cloudtrail lookup-events ... |
使用 CloudTrail 查看策略评估失败的确切事件记录。 |
结论:预防最佳实践
为最大限度地减少 AWS CLI 中的 Access Denied 错误,请遵循以下安全和操作最佳实践:
- 使用最小权限原则: 除非绝对必要,否则不要授予
*(通配符)访问权限。严格限制策略到所需的操作和资源。 - 使用 IAM 角色: 优先使用 IAM 角色而不是长期存在的 IAM 用户密钥,尤其是在脚本或 CI/CD 管道中。这可以限制凭证泄露时的暴露时间。
- 审计 CloudTrail: 如果问题仍然存在,权威来源是 AWS CloudTrail。失败 API 调用的日志记录事件通常会包含失败原因(例如
Deny by Policy X、MFA required)。 - 管理配置文件: 为不同的 AWS 账户或角色(
--profile)明确命名和管理不同的配置文件。避免将环境变量与配置文件配置混用。