MFA로 API 액세스 보안 강화

MFA로 API 액세스 보안 강화

IAM 정책으로 사용자가 호출할 수 있는 API 작업을 지정할 수 있어요. 특히 민감한 작업을 수행하기 전에 사용자가 다중 인증(MFA)으로 인증하도록 요구하는 추가 보안을 적용할 수 있어요.

출처: 문서

본문

예를 들어 사용자가 Amazon EC2 RunInstances, DescribeInstances, StopInstances 작업을 수행하도록 허용하는 정책이 있을 수 있어요. 하지만 TerminateInstances 같은 파괴적인 작업은 제한하고, 사용자가 AWS MFA 기기로 인증한 경우에만 그 작업을 수행할 수 있게 하고 싶을 수 있어요.

이번 강의에서 다룰 내용은 다음과 같아요.

  • 개요(Overview)
  • 시나리오: 교차 계정 위임에 대한 MFA 보호
  • 시나리오: 현재 계정의 API 작업 접근에 대한 MFA 보호
  • 시나리오: 리소스 기반 정책이 있는 리소스에 대한 MFA 보호

개요

API 작업에 MFA 보호를 추가하려면 다음 작업이 필요해요.

  • 관리자가 MFA 인증이 필요한 API 요청을 해야 하는 각 사용자에 대해 AWS MFA 기기를 구성합니다. 자세한 내용은 IAM의 AWS 다중 인증 문서를 참고하세요.
  • 관리자가 사용자가 AWS MFA 기기로 인증했는지 확인하는 Condition 요소를 포함한 정책을 사용자에게 만듭니다.
  • 사용자가 MFA 파라미터를 지원하는 AWS STS API 작업 중 하나인 AssumeRole 또는 GetSessionToken을 호출합니다. 호출의 일부로 사용자는 자신과 연결된 기기의 기기 식별자를 포함합니다. 또한 기기가 생성하는 시간 기반 일회용 비밀번호(TOTP)도 포함합니다. 어느 경우든 사용자는 AWS에 추가 요청을 하는 데 사용할 수 있는 임시 보안 자격 증명을 받습니다.

참고 서비스 API 작업에 대한 MFA 보호는 해당 서비스가 임시 보안 자격 증명을 지원하는 경우에만 가능해요. 이러한 서비스 목록은 임시 보안 자격 증명으로 AWS에 접근 문서를 참고하세요.

인증이 실패하면 AWS는 (허가되지 않은 모든 접근처럼) 접근 거부 오류 메시지를 반환해요. MFA 보호 API 정책이 적용되어 있으면, 사용자가 유효한 MFA 인증 없이 API 작업을 호출하려고 할 때 AWS는 정책에 지정된 API 작업에 대한 접근을 거부해요. API 작업 요청의 타임스탬프가 정책에 지정된 허용 범위 밖이어도 작업은 거부돼요. 사용자는 MFA 코드와 기기 일련 번호로 새 임시 보안 자격 증명을 요청해 MFA로 다시 인증해야 해요.

MFA 조건이 있는 IAM 정책

MFA 조건이 있는 정책은 다음에 연결할 수 있어요.

  • IAM 사용자 또는 그룹
  • Amazon S3 버킷, Amazon SQS 큐, Amazon SNS 토픽 같은 리소스
  • 사용자가 수임할 수 있는 IAM 역할의 신뢰 정책

정책에서 MFA 조건을 사용해 다음 속성을 확인할 수 있어요.

  • 존재(Existence) – 사용자가 MFA로 인증했는지 간단히 확인하려면 Bool 조건에서 aws:MultiFactorAuthPresent 키가 True인지 확인합니다. 이 키는 사용자가 단기 자격 증명으로 인증할 때만 존재해요. 액세스 키 같은 장기 자격 증명에는 이 키가 포함되지 않아요.
  • 기간(Duration) – MFA 인증 후 지정된 시간 내에만 접근을 허용하려면 숫자 조건 유형을 사용해 aws:MultiFactorAuthAge 키의 나이를 값(예: 3600초)과 비교합니다. MFA가 사용되지 않았다면 aws:MultiFactorAuthAge 키는 존재하지 않는다는 점에 유의하세요.

다음 예제는 MFA 인증의 존재를 테스트하는 MFA 조건을 포함한 IAM 역할의 신뢰 정책을 보여줘요. 이 정책을 사용하면 Principal 요소에 지정된 AWS 계정(유효한 AWS 계정 ID로 ACCOUNT-B-ID를 교체)의 사용자가 이 정책이 연결된 역할을 수임할 수 있어요. 단, 그러한 사용자는 MFA로 인증한 경우에만 역할을 수임할 수 있어요.

{
  "Version":"2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {"AWS": "ACCOUNT-B-ID"},
    "Action": "sts:AssumeRole",
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }
}

MFA 조건 유형에 대한 자세한 내용은 AWS 글로벌 조건 컨텍스트 키, 숫자 조건 연산자, 조건 키 존재 확인 연산자 문서를 참고하세요.

GetSessionToken과 AssumeRole 중에서 선택

AWS STS는 사용자가 MFA 정보를 전달할 수 있는 두 가지 API 작업인 GetSessionToken과 AssumeRole을 제공해요. 사용자가 임시 보안 자격 증명을 얻기 위해 호출하는 API 작업은 다음 시나리오 중 어느 것이 적용되는지에 따라 달라져요.

다음 시나리오에는 GetSessionToken을 사용하세요.

  • 요청하는 IAM 사용자와 같은 AWS 계정의 리소스에 접근하는 API 작업을 호출합니다. GetSessionToken 요청의 임시 자격 증명은 자격 증명 요청에 MFA 정보를 포함한 경우에만 IAM 및 AWS STS API 작업에 접근할 수 있습니다. GetSessionToken이 반환하는 임시 자격 증명에는 MFA 정보가 포함되므로, 자격 증명이 수행하는 개별 API 작업에서 MFA를 확인할 수 있어요.
  • MFA 조건이 포함된 리소스 기반 정책으로 보호되는 리소스에 대한 접근.

GetSessionToken 작업의 목적은 MFA로 사용자를 인증하는 것입니다. 정책으로 인증 작업을 제어할 수는 없어요.

다음 시나리오에는 AssumeRole을 사용하세요.

  • 같은 AWS 계정이나 다른 AWS 계정의 리소스에 접근하는 API 작업을 호출합니다. API 호출에는 모든 IAM 또는 AWS STS API가 포함될 수 있어요. 접근을 보호하려면 사용자가 역할을 수임할 때 MFA를 적용해야 합니다. AssumeRole이 반환하는 임시 자격 증명에는 컨텍스트에 MFA 정보가 포함되지 않으므로 개별 API 작업에 대해 MFA를 확인할 수 없어요. 그래서 리소스 기반 정책으로 보호되는 리소스에 대한 접근을 제한하려면 GetSessionToken을 사용해야 해요.

참고 IAM 사용자가 MFA로 로그인하면 AWS CloudTrail 로그에 MFA 정보가 포함돼요. IAM 사용자가 IAM 역할을 수임하면 CloudTrail은 수임된 역할로 수행된 작업에 대해 sessionContext 속성에 mfaAuthenticated: true도 기록해요. 하지만 CloudTrail 로깅은 수임된 역할의 자격 증명으로 API 호출을 할 때 IAM이 요구하는 것과는 별개예요. 자세한 내용은 CloudTrail userIdentity 요소 문서를 참고하세요.

이 시나리오를 구현하는 방법에 대한 자세한 내용은 이 문서의 뒷부분에서 제공해요.

MFA 보호 API 접근에 대한 중요 사항

API 작업에 대한 MFA 보호의 다음 측면을 이해하는 것이 중요해요.

  • MFA 보호는 AssumeRole 또는 GetSessionToken으로 얻어야 하는 임시 보안 자격 증명에서만 사용할 수 있어요.
  • AWS 계정 루트 사용자 자격 증명에는 MFA 보호 API 접근을 사용할 수 없어요.
  • U2F 보안 키에는 MFA 보호 API 접근을 사용할 수 없어요.
  • 페더레이션 사용자는 AWS 서비스에 사용할 MFA 기기를 할당받을 수 없으므로 MFA로 제어되는 AWS 리소스에 접근할 수 없어요. (다음 항목 참고)
  • 임시 자격 증명을 반환하는 다른 AWS STS API 작업은 MFA를 지원하지 않아요. AssumeRoleWithWebIdentity와 AssumeRoleWithSAML의 경우 사용자는 외부 공급자가 인증하며, AWS는 해당 공급자가 MFA를 요구했는지 판단할 수 없어요. GetFederationToken의 경우 MFA가 특정 사용자와 연결되어 있지 않을 수 있어요.
  • 마찬가지로 장기 자격 증명(IAM 사용자 액세스 키, 루트 사용자 액세스 키)은 만료되지 않으므로 MFA 보호 API 접근에 사용할 수 없어요.
  • AssumeRole과 GetSessionToken은 MFA 정보 없이도 호출할 수 있어요. 그 경우 호출자는 임시 보안 자격 증명을 받지만, 그 임시 자격 증명의 세션 정보는 사용자가 MFA로 인증했음을 나타내지 않아요.
  • API 작업에 MFA 보호를 설정하려면 정책에 MFA 조건을 추가해요. 정책에는 MFA 사용을 강제하는 aws:MultiFactorAuthPresent 조건 키가 포함되어야 해요. 교차 계정 위임의 경우 역할의 신뢰 정책에 조건 키가 포함되어야 해요.
  • 다른 AWS 계정에 계정의 리소스 접근을 허용할 때 리소스의 보안은 신뢰하는 계정(다른 계정, 즉 당신의 계정이 아닌)의 구성에 달려 있어요. 다중 인증을 요구하는 경우에도 마찬가지예요. 신뢰하는 계정에서 가상 MFA 기기를 만들 권한이 있는 모든 자격 증명은 역할 신뢰 정책의 해당 부분을 충족하는 MFA 주장(claim)을 구성할 수 있어요. MFA가 필요한 AWS 리소스에 다른 계정의 멤버 접근을 허용하기 전에 신뢰하는 계정의 소유자가 보안 모범 사례를 따르는지 확인해야 해요. 예를 들어 신뢰하는 계정은 MFA 기기 관리 API 작업 같은 민감한 API 작업에 대한 접근을 특정하고 신뢰할 수 있는 자격 증명으로 제한해야 해요.
  • 정책에 MFA 조건이 포함되면 사용자가 MFA 인증을 하지 않았거나, 잘못된 MFA 기기 식별자나 잘못된 TOTP를 제공하면 요청이 거부돼요.

시나리오: 교차 계정 위임에 대한 MFA 보호

이 시나리오에서는 다른 계정의 IAM 사용자에게 접근을 위임하되, 사용자가 AWS MFA 기기로 인증한 경우에만 위임하려고 해요. 교차 계정 위임에 대한 자세한 내용은 역할 용어와 개념 문서를 참고하세요.

계정 A(접근할 리소스를 소유하는 신뢰하는 계정)에 관리자 권한이 있는 IAM 사용자 Anaya가 있다고 가정해 보세요. Anaya는 계정 B(신뢰받는 계정)의 사용자 Richard에게 접근을 부여하고 싶지만, Richard가 역할을 수임하기 전에 MFA로 인증해야 한다는 것을 확인하고 싶어요.

  • 신뢰하는 계정 A에서 Anaya는 CrossAccountRole이라는 IAM 역할을 만들고 역할 신뢰 정책의 주체(principal)를 계정 B의 계정 ID로 설정합니다. 신뢰 정책은 AWS STS AssumeRole 작업에 권한을 부여합니다. Anaya는 다음 예제처럼 신뢰 정책에 MFA 조건도 추가합니다.
{
  "Version":"2012-10-17",
  "Statement": {
    "Effect": "Allow",
    "Principal": {"AWS": "ACCOUNT-B-ID"},
    "Action": "sts:AssumeRole",
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }
}
  • Anaya는 역할이 수행할 수 있는 작업을 지정하는 권한 정책을 역할에 추가합니다. MFA 보호가 있는 역할의 권한 정책은 다른 역할 권한 정책과 다르지 않아요. 다음 예제는 Anaya가 역할에 추가하는 정책으로, 수임하는 사용자가 계정 A의 Books 테이블에서 모든 Amazon DynamoDB 작업을 수행할 수 있도록 허용합니다. 이 정책은 콘솔에서 작업을 수행하는 데 필요한 dynamodb:ListTables 작업도 허용합니다.

참고 권한 정책에는 MFA 조건이 포함되지 않아요. MFA 인증은 사용자가 역할을 수임할 수 있는지 여부를 결정하는 데만 사용된다는 것을 이해하는 것이 중요해요. 사용자가 역할을 수임한 후에는 추가 MFA 검사가 이루어지지 않아요.

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Sid": "TableActions",
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "arn:aws:dynamodb:*:111122223333:table/Books"
        },
        {
            "Sid": "ListTables",
            "Effect": "Allow",
            "Action": "dynamodb:ListTables",
            "Resource": "*"
        }
    ]
}
  • 신뢰받는 계정 B에서 관리자는 IAM 사용자 Richard에게 AWS MFA 기기가 구성되어 있고 기기의 ID를 알고 있는지 확인합니다. 기기 ID는 하드웨어 MFA 기기면 일련 번호, 가상 MFA 기기면 기기의 ARN이에요.
  • 계정 B에서 관리자는 AssumeRole 작업을 호출하도록 허용하는 다음 정책을 Richard(또는 그가 속한 그룹)에 연결합니다. 리소스는 1단계에서 Anaya가 만든 역할의 ARN으로 설정됩니다. 이 정책에는 MFA 조건이 포함되어 있지 않다는 점에 유의하세요.
{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/CrossAccountRole"
            ]
        }
    ]
}
  • 계정 B에서 Richard(또는 Richard가 실행하는 애플리케이션)가 AssumeRole을 호출합니다. API 호출에는 수임할 역할의 ARN(arn:aws:iam::ACCOUNT-A-ID:role/CrossAccountRole), MFA 기기의 ID, Richard가 기기에서 얻은 현재 TOTP가 포함됩니다. Richard가 AssumeRole을 호출하면 AWS는 MFA 요구 사항을 포함해 유효한 자격 증명을 보유했는지 결정합니다. 그렇다면 Richard는 역할을 성공적으로 수임하고, 역할의 임시 자격 증명을 사용하는 동안 계정 A의 Books라는 테이블에서 모든 DynamoDB 작업을 수행할 수 있어요. AssumeRole을 호출하는 프로그램 예제는 MFA 인증으로 AssumeRole 호출 문서를 참고하세요.

시나리오: 현재 계정의 API 작업 접근에 대한 MFA 보호

이 시나리오에서는 계정의 사용자가 AWS MFA 기기로 인증된 경우에만 민감한 API 작업에 접근할 수 있도록 해야 해요.

EC2 인스턴스로 작업해야 하는 개발자 그룹이 있는 계정 A가 있다고 가정해 보세요. 일반 개발자는 인스턴스로 작업할 수 있지만 ec2:StopInstances나 ec2:TerminateInstances 작업에 대한 권한은 부여되지 않아요. 이 "파괴적인" 권한 작업을 몇몇 신뢰할 수 있는 사용자에게만 제한하려면, 이런 민감한 Amazon EC2 작업을 허용하는 정책에 MFA 보호를 추가해요.

이 시나리오에서 신뢰할 수 있는 사용자 중 하나는 사용자 Sofía입니다. 사용자 Anaya는 계정 A의 관리자입니다.

  • Anaya는 Sofía에게 AWS MFA 기기가 구성되어 있고 Sofía가 기기의 ID를 알고 있는지 확인합니다. 기기 ID는 하드웨어 MFA 기기면 일련 번호, 가상 MFA 기기면 기기의 ARN이에요.
  • Anaya는 EC2-Admins라는 그룹을 만들고 사용자 Sofía를 그룹에 추가합니다.
  • Anaya는 EC2-Admins 그룹에 다음 정책을 연결합니다. 이 정책은 사용자가 MFA로 인증한 경우에만 Amazon EC2 StopInstances와 TerminateInstances 작업을 호출할 수 있는 권한을 부여합니다.
{
  "Version":"2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": [
      "ec2:StopInstances",
      "ec2:TerminateInstances"
    ],
    "Resource": ["*"],
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }]
}
  • 참고 이 정책이 적용되려면 사용자가 먼저 로그아웃한 다음 다시 로그인해야 해요. 사용자 Sofía가 Amazon EC2 인스턴스를 중지하거나 종료해야 한다면, Sofía(또는 그녀가 실행하는 애플리케이션)는 GetSessionToken을 호출합니다. 이 API 작업은 MFA 기기의 ID와 Sofía가 기기에서 얻은 현재 TOTP를 전달합니다.

  • 사용자 Sofía(또는 Sofía가 사용하는 애플리케이션)는 GetSessionToken이 제공한 임시 자격 증명을 사용해 Amazon EC2 StopInstances 또는 TerminateInstances 작업을 호출합니다. GetSessionToken을 호출하는 프로그램 예제는 이 문서의 뒷부분에 있는 MFA 인증으로 GetSessionToken 호출 문서를 참고하세요.

시나리오: 리소스 기반 정책이 있는 리소스에 대한 MFA 보호

이 시나리오에서는 S3 버킷, SQS 큐, SNS 토픽의 소유자입니다. 어떤 AWS 계정의 어떤 사용자든 리소스에 접근하는 사용자가 AWS MFA 기기로 인증되었는지 확인하려고 해요.

이 시나리오는 사용자가 먼저 역할을 수임할 필요 없이 교차 계정 MFA 보호를 제공하는 방법을 보여줘요. 이 경우 사용자는 세 가지 조건이 충족되면 리소스에 접근할 수 있어요: MFA로 인증되었고, GetSessionToken에서 임시 보안 자격 증명을 얻을 수 있고, 리소스 정책이 신뢰하는 계정에 있어야 해요.

계정 A에 S3 버킷을 만들었다고 가정해 보세요. 여러 다른 AWS 계정의 사용자에게 이 버킷 접근을 부여하되, 그 사용자가 MFA로 인증된 경우에만 부여하려고 해요.

이 시나리오에서 사용자 Anaya는 계정 A의 관리자입니다. 사용자 Nikhil은 계정 C의 IAM 사용자입니다.

  • 계정 A에서 Anaya는 Account-A-bucket이라는 버킷을 만듭니다.
  • Anaya는 버킷에 버킷 정책을 추가합니다. 이 정책은 계정 A, 계정 B, 계정 C의 모든 사용자가 버킷에서 Amazon S3 PutObject와 DeleteObject 작업을 수행하도록 허용합니다. 정책에는 MFA 조건이 포함됩니다.
{
  "Version":"2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {"AWS": [
      "ACCOUNT-A-ID",
      "ACCOUNT-B-ID",
      "ACCOUNT-C-ID"
    ]},
    "Action": [
      "s3:PutObject",
      "s3:DeleteObject"
    ],
    "Resource": ["arn:aws:s3:::ACCOUNT-A-BUCKET-NAME/*"],
    "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
  }]
}

참고 Amazon S3는 루트 계정 접근에만 적용되는 MFA Delete 기능을 제공해요. 버킷의 버전 관리 상태를 설정할 때 Amazon S3 MFA Delete를 활성화할 수 있어요. Amazon S3 MFA Delete는 IAM 사용자에게 적용할 수 없으며, MFA 보호 API 접근과는 별개로 관리돼요. 버킷을 삭제할 권한이 있는 IAM 사용자는 Amazon S3 MFA Delete가 활성화된 버킷을 삭제할 수 없어요. Amazon S3 MFA Delete에 대한 자세한 내용은 MFA Delete 문서를 참고하세요.

  • 계정 C에서 관리자는 사용자 Nikhil에게 AWS MFA 기기가 구성되어 있고 Nikhil이 기기의 ID를 알고 있는지 확인합니다. 기기 ID는 하드웨어 MFA 기기면 일련 번호, 가상 MFA 기기면 기기의 ARN이에요.
  • 계정 C에서 Nikhil(또는 그가 실행하는 애플리케이션)은 GetSessionToken을 호출합니다. 호출에는 MFA 기기의 ID 또는 ARN과 Nikhil이 기기에서 얻은 현재 TOTP가 포함됩니다.
  • Nikhil(또는 그가 사용하는 애플리케이션)은 GetSessionToken이 반환한 임시 자격 증명을 사용해 Amazon S3 PutObject 작업을 호출해 Account-A-bucket에 파일을 업로드합니다. GetSessionToken을 호출하는 프로그램 예제는 이 문서의 뒷부분에 있는 MFA 인증으로 GetSessionToken 호출 문서를 참고하세요.

참고 이 경우 AssumeRole이 반환하는 임시 자격 증명은 작동하지 않아요. 사용자가 역할을 수임하기 위해 MFA 정보를 제공할 수는 있지만, AssumeRole이 반환하는 임시 자격 증명에는 MFA 정보가 포함되지 않아요. 정책의 MFA 조건을 충족하려면 그 정보가 필요해요.

더 알아보기 (Learn more)