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
|
安全最佳實踐
- 最小權限原則:只授予完成任務所需的最少權限
- 使用條件限制:加入 IP 限制、MFA 要求等條件
- 定期輪換 External ID:定期更新 External ID 以增強安全性
- 啟用 CloudTrail:記錄所有 AssumeRole 操作
- 設定適當的會話持續時間:避免過長的臨時憑證有效期
加入 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
|
參考資料