設定受 MFA 保護的 API 存取 - AWS Identity and Access Management

設定受 MFA 保護的 API 存取

利用 IAM 政策,可以指定允許使用者呼叫的 API 操作。在一些情況下,您可能希望先要求使用者透過 AWS 多重要素驗證 (MFA) 進行身分驗證,然後才允許使用者執行尤其敏感的動作,藉以提高安全性。

例如,您可能擁有允許使用者執行 Amazon EC2 RunInstancesDescribeInstancesStopInstances 動作的政策。但您可能希望限制破壞性動作 (如 TerminateInstances),並確保使用者只能在使用 AWS MFA 裝置進行身分驗證後執行該動作。

概要

新增 MFA 防護到 API 操作將包括以下任務:

  1. 管理員為每個使用者配置 AWS MFA 裝置,這些使用者需要發出要求 MFA 身分驗證的 API 請求。此程序在 在 AWS 中為使用者啟用 MFA 裝置 中說明。

  2. 管理員為使用者建立包含 Condition 元素的政策,檢查使用者是否已使用 AWS MFA 裝置進行身分驗證。

  3. 使用者呼叫支援 MFA 參數 AWS STSAssumeRoleGetSessionToken 的其中一個 API 操作,取決於 MFA防護的方案而定,如下方內容所述。作為呼叫的一部分,使用者包含與其關聯的裝置的裝置識別碼。使用者也包含裝置產生之以時間為基礎的單次密碼 (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 條件來檢查以下屬性:

  • 存在 - 如果只是驗證使用者是否已使用 MFA 進行身分驗證,請檢查 aws:MultiFactorAuthPresent 金鑰在 Bool 條件中是否為 True。只有在使用者使用短期憑證進行驗證時,索引鍵才會存在。長期憑證,例如存取金鑰,則不包括此鍵。

  • 持續時間 - 如果您只希望在 MFA 身分驗證後的指定時間內授予存取權限,請使用數值條件類型將 aws:MultiFactorAuthAge 索引鍵的有效期與某個值 (如 3600 秒) 進行比較。請注意,如果未使用 MFA,則 aws:MultiFactorAuthAge 索引鍵不會顯示。

以下範例顯示 IAM 角色的信任政策,該政策包含一個 MFA 條件,用於測試是否存在 MFA 身分驗證。利用此政策,AWS 元素中指定 Principal 帳戶的使用者 (將 ACCOUNT-B-ID 替換為有效的 AWS 帳戶 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 提供兩種 API 操作,可供使用者傳遞 MFA 資訊:GetSessionTokenAssumeRole。使用者呼叫以獲取臨時安全憑證的 API 操作取決於適用於以下哪個案例。

針對以下案例使用 GetSessionToken

  • 呼叫存取與提出請求的 IAM 使用相同的 AWS 帳戶中的資源的 API 操作。請注意,只有在憑證請求中包含 MFA 資訊時,GetSessionToken 請求的臨時憑證才能存取 IAM 和 AWS STS API 操作。由於 GetSessionToken 傳回的臨時憑證包含 MFA 資訊,因此您可以檢查由該憑證發出的個別 API 操作中的 MFA。

  • 存取受到以資源為基礎且包含 MFA 條件的政策所保護的資源。

GetSessionToken 操作的目的是使用 MFA 驗證使用者的身分。您不能使用政策來控制驗證操作。

針對以下案例使用 AssumeRole

  • 呼叫存取相同的或不同的 AWS 帳戶中的資源的 API 操作。API 呼叫可包含任何 IAM 或 AWS STS API。請注意,要保護存取,您可以在使用者擔任角色時強制執行 MFA。由 AssumeRole 傳回的臨時憑證未將 MFA 資訊包含在上下文中,因此您無法檢查 MFA 的單一 API 操作。這就是您必須使用 GetSessionToken 限制對受到以資源為基礎之政策保護的資源的存取的原因。

本文件稍後將提供有關如何實施這些使用案例的詳細資訊。

有關受 MFA 保護的 API 存取的要點

瞭解 API 操作的 MFA 防護有下列數個層面非常重要:

  • MFA 防護僅透過使用臨時安全性憑證供,而該憑證必須使用 AssumeRoleGetSessionToken 來取得。

  • 無法將受 MFA 保護的 API 存取與 AWS 帳戶 根使用者憑證配合使用。

  • 無法搭配 U2F 安全性金鑰使用受 MFA 保護的 API 存取。

  • 無法分配 MFA 裝置給聯合身分使用者用於 AWS 服務,因此,聯合身分使用者無法存取受 MFA 控制的 AWS 資源。(請查看下一要點。)

  • 傳回臨時憑證的其他 AWS STS API 操作不支援 MFA。對於 AssumeRoleWithWebIdentityAssumeRoleWithSAML,使用者透過外部提供者進行身分驗證,並且 AWS 無法確定該提供者是否需要 MFA。對於 GetFederationToken,MFA 不一定要與特定使用者相關聯。

  • 同樣地,長期憑證 (IAM 使用者存取金鑰和根使用者存取金鑰) 無法用於受 MFA 保護的 API 存取,因為此類憑證不會過期。

  • 也可以在沒有 MFA 資訊的情況下呼叫 AssumeRoleGetSessionToken。在此情況下,呼叫者將取回臨時安全性憑證,但這些臨時憑證的工作階段資訊不會顯示使用 MFA 進行身分驗證的使用者。

  • 若要建立 API 操作的 MFA 防護,可將 MFA 條件加入到政策。政策必須包含 aws:MultiFactorAuthPresent 條件索引鍵,才能強制使用 MFA。對於跨帳戶委派,該角色的信任政策必須包含條件索引鍵。

  • 如果您允許其他 AWS 帳戶存取您帳戶中的資源,您的資源安全也會取決於可信任帳戶 (也就是其他帳戶,而不是您的帳戶) 的組態。即使您要求多重要素驗證,也是如此。有權建立虛擬 MFA 裝置的可信帳戶中的任何身分都可以建構 MFA 宣告,以滿足角色信任政策的該部分。在您允許另一個帳戶成員存取您的 AWS 資源之前 (其需要多重驗證),您應該確保信任的帳戶擁有者遵循安全最佳實務。例如,信任的帳戶應該限制存取敏感 API 操作 (例如 MFA 裝置管理 API 操作) 至特定的信任身分。

  • 如果政策包含 MFA 條件,則在以下情況下將拒絕請求:使用者未進行 MFA 身分驗證或使用者提供了無效的 MFA 裝置識別碼或無效的 TOTP。

使用案例:跨帳戶委派的 MFA 防護

在此案例中,您希望將存取權限委派給另一帳戶中的 IAM 使用者,但前提是該使用者已使用 AWS MFA 裝置進行身分驗證。(如需建立跨帳戶委派的詳細資訊,請參閱 角色術語和概念

假設您有一個帳戶 A (擁有要存取的資源的信任帳戶),其 IAM 使用者 Anaya 擁有管理員許可。她希望對帳戶 B (可信任的帳戶) 中的使用者 Richard 授予存取權,但希望確保 Richard 在擔任該角色之前已使用 MFA 進行身分驗證。

  1. 在信任帳戶 A 中,Anaya 建立一個名為 CrossAccountRole 的 IAM 角色,並將該角色信任政策中的委託人設定為帳戶 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"}} } }
  2. 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:*:ACCOUNT-A-ID:table/Books" }, { "Sid": "ListTables", "Effect": "Allow", "Action": "dynamodb:ListTables", "Resource": "*" } ] }
  3. 在信任帳戶 B 中,管理員確定 IAM 使用者 Richard 已使用 AWS MFA 裝置進行設定,而且知道裝置的 ID。如果是硬體 MFA 裝置,則裝置 ID 是序號,或如果是虛擬 MFA 裝置,裝置是 ARN。

  4. 在帳戶 B 中,管理員將以下政策連接到使用者 Richard (或該使用者所在的群組),該政策允許使用者呼叫 AssumeRole 動作。資源被設定到 Anaya 在第 1 步中所建立的角色 ARN。注意,該政策不包含 MFA 條件。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": ["sts:AssumeRole"], "Resource": ["arn:aws:iam::ACCOUNT-A-ID:role/CrossAccountRole"] }] }
  5. 在帳戶 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 (Python)

使用案例:目前帳戶中 API 操作存取的 MFA 防護

在此案例中,您應確定只有當您 AWS 帳戶中的使用者已使用 AWS MFA 裝置進行身分驗證後才能存取敏感 API 操作。

假設您擁有帳戶 A,其中包含一組需要使用 EC2 執行個體的開發人員。普通開發人員可以使用執行個體,但他們未獲得 ec2:StopInstancesec2:TerminateInstances 操作的許可。您希望僅允許幾個可信任的使用者執行這些「破壞性」特權操作,因此您將 MFA 防護加入到允許這些敏感 Amazon EC2 動作的政策中。

在此使用案例中,使用者 Sofía 是可信任的使用者之一。使用者 Anaya 是帳戶 A 中的管理員。

  1. Anaya 確定 Sofía 是以 AWS MFA 裝置設定,而且 Sofía 知道裝置的 ID。如果是硬體 MFA 裝置,則裝置 ID 是序號,或如果是虛擬 MFA 裝置,裝置是 ARN。

  2. Anaya 建立一個名為 EC2-Admins 的群組並將使用者 Sofía 加入到該群組中。

  3. Anaya 將以下政策連接到 EC2-Admins 群組。此政策授予使用者呼叫 Amazon EC2 StopInstancesTerminateInstances 動作的許可,但前提是該使用者已使用 MFA 進行身分驗證。

    { "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": [ "ec2:StopInstances", "ec2:TerminateInstances" ], "Resource": ["*"], "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}} }] }
  4. 注意

    要讓此政策生效,使用者必須先登出,然後再次登入。

    如果使用者 Sofía 需要停止或終止 Amazon EC2 執行個體,她 (或執行中的應用程式) 會呼叫 GetSessionToken。此 API 操作傳遞 MFA 裝置的 ID,以及 Sofía 從其裝置取得的目前 TOTP。

  5. 使用者 Sofía (或 Sofía 正在使用的應用程式) 使用由 GetSessionToken 提供的臨時憑證來呼叫 Amazon EC2 StopInstances 或者 TerminateInstances 動作。

    有關呼叫 GetSessionToken 的程式之範例,請參閱本文件後述的 使用 MFA 身分驗證呼叫 GetSessionToken (Python 和 C#)

使用案例:擁有以資源為基礎的政策之資源的 MFA 防護

在此案例中,您是 S3 儲存貯體、SQS 佇列或 SNS 主題的擁有者。您想要確保來自任何 AWS 帳戶存取資源的任何使用者都已由 AWS MFA 裝置進行身分驗證。

此使用案例介紹了一種提供跨帳戶 MFA 防護的方法,無需使用者先擔任角色。在此情況下,若符合三個條件,使用者便可存取資源。使用者必須通過 MFA 的身分驗證,能夠從 GetSessionToken 取得臨時安全性憑證,並且在資源政策所信任的帳戶中。

假設您在帳戶 A 中並建立一個 S3 儲存貯體。您希望授予數個不同 AWS 帳戶中的使用者對此儲存貯體的存取權,但前提是這些使用者已使用 MFA 進行身分驗證。

在此方案中,使用者 Anaya 是帳戶 A 中的管理員。使用者 Nikhil 是帳戶 C 中的 IAM 使用者。

  1. 在帳戶 A 中,Anaya 建立一個名為 Account-A-bucket 的儲存貯體。

  2. Anaya 將儲存貯體政策加入到儲存貯體。該政策允許帳戶 A、帳戶 B 或帳戶 C 中的所有使用者執行儲存貯體中的 Amazon S3 PutObjectDeleteObject 動作。該政策包含 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 刪除」功能。在您設定儲存貯體的版本控制狀態時,可啟用 Amazon S3 MFA Delete 功能。Amazon S3 MFA Delete 功能不適用於 IAM 使用者,在管理時獨立於 MFA 防護的 API 存取。即使 IAM 使用者有刪除儲存貯體的許可,但在啟用 Amazon S3 MFA Delete 功能時,也無法執行刪除。如需有關 Amazon S3 MFA Delete 的詳細資訊,請參閱 MFA Delete

  3. 在帳戶 C 中,管理員確定使用者 Nikhil 以 AWS MFA 裝置設定,而且知道裝置的 ID。如果是硬體 MFA 裝置,則裝置 ID 是序號,或如果是虛擬 MFA 裝置,裝置是 ARN。

  4. 在帳戶 C 中,Nikhil (或該使用者正在執行的應用程式) 呼叫 GetSessionToken。此呼叫包括 MFA 裝置的 ID 或 ARN 以及 Nikhil 從其裝置中取得的目前 TOTP。

  5. Nikhil (或 Nikhil 正在使用的應用程式) 使用由 GetSessionToken 傳回的暫時憑證來呼叫 Amazon S3 PutObject 動作,上傳檔案到 Account-A-bucket

    有關呼叫 GetSessionToken 的程式之範例,請參閱本文件後述的 使用 MFA 身分驗證呼叫 GetSessionToken (Python 和 C#)

    注意

    AssumeRole 傳回的暫時憑證在此案例中則不會運作。雖然使用者可以提供 MFA 資訊以取得角色,AssumeRole 傳回的暫時憑證不會包含 MFA 資訊。有了這項資訊,才能符合政策中的 MFA 條件。