AWS CLI에서 'Access Denied' 및 인증 문제 해결
AWS CLI 사용 시 발생하는 'Access Denied' 및 인증 오류를 체계적으로 해결합니다. 이 가이드는 `aws sts get-caller-identity`를 사용한 자격 증명 확인, 복잡한 IAM 정책 평가 계층 분석, 임시 자격 증명 또는 리소스 기반 정책(예: S3 버킷 정책)으로 인한 문제 해결 등 필수 진단 단계를 다룹니다. 주요 명령어와 IAM Policy Simulator를 사용하여 AWS 환경에서 권한 부여 실패를 신속하게 식별하고 수정하는 방법을 알아보세요.
AWS CLI에서 'Access Denied' 및 인증 문제 해결
AWS CLI에서 Access Denied 오류가 발생하면 실패한 API 호출은 표시되지만 이를 유발한 정책 라인은 표시되지 않아 답답합니다. 이러한 문제는 거의 항상 잘못 구성된 IAM(Identity and Access Management) 정책, 만료된 임시 자격 증명, 또는 CLI 환경의 잘못된 설정에서 비롯됩니다.
유용한 습관은 문제를 두 가지 질문으로 나누는 것입니다: CLI가 누구로 호출되고 있는지, 그리고 해당 작업을 수행하지 못하도록 막는 정책 경계는 무엇인지.
1. 초기 진단: 호출자 및 자격 증명 식별
복잡한 정책 분석에 들어가기 전에, 첫 번째 단계는 AWS CLI가 어떤 IAM 자격 증명을 사용하고 있는지, 그리고 해당 자격 증명이 여전히 유효한지 확실히 확인하는 것입니다.
현재 자격 증명 확인: sts get-caller-identity
이것은 가장 중요한 진단 명령어입니다. 이 명령어는 후속 AWS 명령어를 실행하는 사용자 ARN, 역할 ARN 또는 수임된 역할 세션이 정확히 무엇인지 알려줍니다.
aws sts get-caller-identity
예상 출력:
{
"UserId": "AIDAIAMUSERID",
"Account": "123456789012",
"Arn": "arn:aws:iam::123456789012:user/DevUser"
}
반환된 ARN이 예상한 사용자 또는 역할과 일치하지 않으면 잘못된 AWS 프로필 또는 환경 변수로 작업하고 있는 것입니다.
프로필 구성 및 리전 확인
--profile 플래그를 통해 지정하거나 AWS_PROFILE 환경 변수를 통해 설정된 올바른 AWS 프로필이 사용되고 있는지 확인합니다.
# 기본 프로필의 구성된 설정 확인
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요소를 사용하여 특정 리소스로 작업을 제한합니까? 일반적인 오류는 작업에 특정 ARN이 필요할 때Resource: "*"로 설정하거나 그 반대의 경우입니다. - 조건: 충족되지 않는 조건(예: 소스 IP 주소, 시간, MFA 필요)이 있습니까?
B. 리소스 기반 정책(S3, SQS, KMS)
S3 또는 KMS와 같은 서비스의 경우 리소스 자체에 누가 액세스할 수 있는지 지시하는 정책이 있습니다. 교차 계정 액세스 및 많은 리소스별 설계의 경우 리소스 정책도 보안 주체를 허용해야 합니다. 동일한 계정에서 정확한 상호 작용은 보안 주체 유형 및 서비스에 따라 다르므로 자격 증명 정책만으로 모든 결과를 설명한다고 가정하지 마십시오.
예: 특정 VPC 엔드포인트 외부의 모든 사용자에 대해 명시적 Deny가 있는 S3 버킷(리소스 정책)에 액세스하려고 하면 사용자의 IAM 정책에 관계없이 Access Denied가 발생합니다.
C. 권한 경계 및 SCP
조직에서 AWS Organizations를 사용하는 경우 **SCP(Service Control Policies)**는 계정 내에서 허용되는 최대 권한을 정의합니다. 마찬가지로 권한 경계는 IAM 엔터티가 가질 수 있는 최대 권한을 제한합니다.
SCP 또는 경계가 필요한 작업을 거부하면 자격 증명 정책이 권한을 부여하더라도 CLI 작업이 실패합니다.
실용적인 도구: IAM Policy Simulator
복잡한 실패를 해결할 때 AWS Management Console의 IAM Policy Simulator는 매우 유용합니다. 특정 리소스(예: arn:aws:s3:::my-bucket/key)에 대해 특정 작업(예: s3:GetObject)을 테스트하고 IAM 엔터티를 지정하여 거부를 유발하는 정책 문을 정확히 찾아낼 수 있습니다.
3. 일반적인 'Access Denied' 시나리오 및 해결 방법
시나리오 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(Multi-Factor Authentication) 요구와 같은 보안 모범 사례를 적용하는 조건을 활용합니다.
정책에 다음과 같은 조건이 포함된 경우:
"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
시간을 절약해주는 서비스별 확인 사항
IAM 오류는 AWS를 하나의 권한 시스템으로 취급하지 않을 때 디버그하기 쉽습니다. 각 서비스는 고유한 리소스 모델과 조건 키를 추가합니다.
S3의 경우 버킷 수준 작업과 객체 수준 작업을 분리하십시오. s3:ListBucket은 버킷 ARN을 사용하는 반면, s3:GetObject 및 s3:PutObject는 버킷 아래의 객체 ARN을 사용합니다. arn:aws:s3:::my-bucket에 대해 s3:GetObject를 부여하는 정책은 잘못된 형태입니다. 객체 액세스에는 arn:aws:s3:::my-bucket/*이 필요합니다. 반대 실수도 목록 작성에서 흔히 발생합니다.
KMS의 경우 IAM 정책뿐만 아니라 키 정책도 확인하십시오. 역할에 kms:Decrypt가 있는 것처럼 보일 수 있지만 키 정책이 해당 역할 경로를 허용하지 않으면 복호화는 여전히 실패합니다. 이는 암호화된 S3 객체 다운로드, 암호화된 EBS 스냅샷 가져오기 또는 고객 관리형 키를 사용하는 비밀 읽기 시 나타납니다.
ECR의 경우 Docker 로그인 및 이미지 풀은 여러 서비스가 일치해야 합니다. CLI 자격 증명에는 ecr:GetAuthorizationToken이 필요할 수 있으며, 리포지토리가 계정 간에 공유되는 경우 리포지토리 정책이 풀 작업을 허용해야 할 수 있습니다. 클러스터 노드 역할이 이미지를 풀고 있는 경우 개인 관리자 프로필로 디버깅하는 것은 거의 도움이 되지 않습니다. 노드 역할 또는 태스크 실행 역할로 테스트하십시오.
STS assume-role 워크플로의 경우 신뢰 관계의 양쪽을 살펴보십시오. 호출자에게 sts:AssumeRole을 호출할 권한이 필요하고 대상 역할 신뢰 정책은 호출자를 신뢰해야 합니다. 신뢰 정책에 외부 ID 또는 MFA 조건이 있는 경우 assume-role 명령어가 이를 충족해야 합니다.
환경 우선 순위는 숙련된 사용자도 속일 수 있습니다.
AWS CLI는 ~/.aws/credentials만 읽지 않습니다. 명령줄 플래그, 환경 변수, 명명된 프로필, SSO 캐시 항목, 웹 ID 토큰, EC2 또는 ECS 메타데이터, 프로필에 구성된 역할 수임을 포함할 수 있는 자격 증명 공급자 체인을 탐색합니다. 이것이 aws configure list가 하나의 파일을 여는 것보다 더 유용한 이유입니다.
일반적인 로컬 실패는 다음과 같습니다: export AWS_PROFILE=dev를 실행한 다음 나중에 임시 프로덕션 자격 증명을 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY 및 AWS_SESSION_TOKEN에 붙여넣습니다. 환경 키가 우선할 수 있으므로 dev를 사용하는 것처럼 보이는 명령어가 실제로는 내보낸 세션을 사용하고 있습니다. 하루 종일 열려 있는 터미널에서 다음을 실행하십시오:
env | sort | grep '^AWS_'
계정을 자주 전환하는 경우 별도의 터미널 탭, 자격 증명 도우미 또는 파괴적인 명령어 전에 호출자 ID를 출력하는 래퍼 스크립트를 사용하십시오. 출력의 추가 줄은 잘못된 계정에서 삭제하는 것보다 저렴합니다.
4. 진단 명령어 요약
이 명령어 체크리스트를 사용하여 권한 부여 실패 체인을 신속하게 진단하십시오:
| 목표 | 명령어 | 목적 |
|---|---|---|
| 자격 증명 확인 | aws sts get-caller-identity |
명령어를 실행하는 ARN을 확인합니다. |
| 구성 확인 | aws configure list |
프로필 설정, 리전 및 출력 형식을 확인합니다. |
| 정책 유효성 테스트 | (IAM Policy Simulator 사용) | IAM 자격 증명이 리소스에 대해 특정 API 작업을 수행할 수 있는지 확인합니다. |
| 정책 거부 식별 | aws cloudtrail lookup-events ... |
CloudTrail을 사용하여 정책 평가가 실패한 정확한 이벤트 레코드를 확인합니다. |
실제 디버깅 경로
좋은 첫 번째 패스는 다음과 같습니다. 셸이 이미 설정되었다고 생각하더라도 프로필과 리전을 명시적으로 작성하여 실패한 명령어를 다시 실행하십시오:
AWS_PROFILE=prod-readonly aws s3 ls s3://example-audit-logs --region us-east-1
aws sts get-caller-identity --profile prod-readonly
aws configure list --profile prod-readonly
자격 증명이 잘못된 경우 거기서 중지하십시오. 환경에서 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_PROFILE 및 AWS_REGION을 확인하십시오. 환경 자격 증명은 프로필보다 우선하여 CLI가 이전에 내보낸 역할로 작동하게 할 수 있습니다. CI에서는 실패 단계 근처에 aws sts get-caller-identity를 출력하여 빌드 로그가 런타임에 사용된 역할을 증명하도록 하십시오.
자격 증명이 올바른 경우 정확한 API 작업을 기록하십시오. 상위 수준 명령어는 이를 숨길 수 있습니다. aws s3 cp는 방향, 암호화 및 CLI가 버킷을 검사해야 하는지 여부에 따라 s3:GetObject, s3:PutObject, s3:ListBucket, kms:Decrypt 또는 kms:GenerateDataKey가 필요할 수 있습니다. 오류 메시지에 AccessDenied가 포함되어 있지만 작업이 포함되지 않은 경우 CloudTrail은 일반적으로 이벤트 이름과 리소스를 제공합니다.
S3의 경우 버킷 정책, 객체 소유권, 퍼블릭 액세스 차단 설정, VPC 엔드포인트 정책 및 KMS 키 정책을 확인하십시오. KMS로 암호화된 객체의 경우 S3 허용만으로는 충분하지 않습니다. 호출자에게 관련 KMS 권한도 필요하고 키 정책이 보안 주체 경로를 허용해야 합니다. 조직의 경우 ID 정책을 편집하기 전에 SCP를 확인하십시오. SCP는 액세스 권한을 부여할 수 없지만 계정의 모든 보안 주체가 수행할 수 있는 작업을 제한할 수 있습니다.
예방은 대부분 지루한 위생 상태입니다: 수명이 짧은 역할 자격 증명, 명확하게 명명된 프로필, 실제 ARN에 대해 테스트된 최소 권한 정책, 엔지니어가 실제로 쿼리할 수 있는 CloudTrail 활성화. 최선의 수정은 더 넓은 Action: "*"가 아니라 누락된 하나의 작업 또는 요청과 일치하는 하나의 거부 조건을 찾는 것입니다.