AWS IAM 角色與跨帳戶存取

AWS IAM Roles and Cross-Account Access

IAM 角色概述

AWS Identity and Access Management (IAM) 角色是一種 AWS 身分,具有特定權限的安全認證。與 IAM 使用者不同,角色並不與特定的人員或應用程式綁定,而是可以被需要的任何人或服務「扮演」(assume)。

角色的主要用途包括:

  • 為 AWS 服務(如 EC2、Lambda)授予權限
  • 提供跨帳戶存取權限
  • 為聯合身分使用者提供存取權限
  • 臨時提升權限以執行特定任務

角色與使用者差異

特性IAM 使用者IAM 角色
長期憑證有(密碼、存取金鑰)
臨時憑證
可被多方使用
跨帳戶存取困難容易
適用對象特定人員服務、應用程式、多人

建立 IAM 角色

使用 AWS CLI 建立一個基本的 IAM 角色:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 建立信任政策文件
cat > trust-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF

# 建立角色
aws iam create-role \
    --role-name MyEC2Role \
    --assume-role-policy-document file://trust-policy.json \
    --description "允許 EC2 執行個體存取 S3 的角色"

# 附加權限政策
aws iam attach-role-policy \
    --role-name MyEC2Role \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

信任政策設定

信任政策(Trust Policy)定義了誰可以扮演這個角色。以下是常見的信任政策範例:

允許特定 AWS 帳戶扮演角色

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

允許特定使用者扮演角色

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/DevUser"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

跨帳戶存取架構

跨帳戶存取允許一個 AWS 帳戶中的使用者或服務存取另一個帳戶中的資源。典型架構如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
帳戶 A (來源帳戶: 111111111111)     帳戶 B (目標帳戶: 222222222222)
┌─────────────────────────┐        ┌─────────────────────────┐
│                         │        │                         │
│   IAM 使用者/角色       │───────▶│   跨帳戶角色            │
│   (需要存取權限)        │  扮演   │   (CrossAccountRole)    │
│                         │        │                         │
└─────────────────────────┘        └─────────────────────────┘
                                   ┌─────────────────────────┐
                                   │   目標資源              │
                                   │   (S3、DynamoDB 等)     │
                                   └─────────────────────────┘

設定跨帳戶角色

步驟 1:在目標帳戶建立角色

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 在帳戶 B (222222222222) 中執行
cat > cross-account-trust-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}
EOF

aws iam create-role \
    --role-name CrossAccountS3Access \
    --assume-role-policy-document file://cross-account-trust-policy.json

# 附加所需權限
aws iam attach-role-policy \
    --role-name CrossAccountS3Access \
    --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

步驟 2:在來源帳戶授予扮演權限

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 在帳戶 A (111111111111) 中執行
cat > assume-role-policy.json << 'EOF'
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::222222222222:role/CrossAccountS3Access"
        }
    ]
}
EOF

aws iam put-user-policy \
    --user-name DevUser \
    --policy-name AssumeRolePolicy \
    --policy-document file://assume-role-policy.json

AssumeRole 操作

使用 AWS CLI 扮演跨帳戶角色:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 扮演角色並取得臨時憑證
aws sts assume-role \
    --role-arn arn:aws:iam::222222222222:role/CrossAccountS3Access \
    --role-session-name MySession \
    --duration-seconds 3600

# 回傳結果範例
{
    "Credentials": {
        "AccessKeyId": "ASIAXXXXXXXXXXXXXXXX",
        "SecretAccessKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "SessionToken": "FwoGZXIvYXdzEBYaDK...",
        "Expiration": "2024-09-01T12:00:00Z"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAXXXXXXXXXXXXXXXXX:MySession",
        "Arn": "arn:aws:sts::222222222222:assumed-role/CrossAccountS3Access/MySession"
    }
}

# 使用臨時憑證
export AWS_ACCESS_KEY_ID="ASIAXXXXXXXXXXXXXXXX"
export AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export AWS_SESSION_TOKEN="FwoGZXIvYXdzEBYaDK..."

# 現在可以存取帳戶 B 的資源
aws s3 ls

External ID 使用

External ID 是一種額外的安全機制,用於防止「混淆代理人」(Confused Deputy) 攻擊。

設定包含 External ID 的信任政策

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "StringEquals": {
                    "sts:ExternalId": "unique-external-id-12345"
                }
            }
        }
    ]
}

使用 External ID 扮演角色

1
2
3
4
aws sts assume-role \
    --role-arn arn:aws:iam::222222222222:role/CrossAccountS3Access \
    --role-session-name MySession \
    --external-id unique-external-id-12345

安全最佳實踐

  1. 最小權限原則:只授予完成任務所需的最少權限
  2. 使用條件限制:加入 IP 限制、MFA 要求等條件
  3. 定期輪換 External ID:定期更新 External ID 以增強安全性
  4. 啟用 CloudTrail:記錄所有 AssumeRole 操作
  5. 設定適當的會話持續時間:避免過長的臨時憑證有效期

加入 MFA 要求的信任政策

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:user/DevUser"
            },
            "Action": "sts:AssumeRole",
            "Condition": {
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        }
    ]
}

使用 MFA 扮演角色

1
2
3
4
5
aws sts assume-role \
    --role-arn arn:aws:iam::222222222222:role/CrossAccountS3Access \
    --role-session-name MySession \
    --serial-number arn:aws:iam::111111111111:mfa/DevUser \
    --token-code 123456

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy