1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

principal に IAM ロールを指定するとき~検証:ロールの連鎖(Role chaining)

Last updated at Posted at 2023-01-09

principal に IAM ロールを指定したことはありますか?
あまりないような気もしますが、ドキュメントに気になる内容を発見したので書いてみます。

principal に IAM ロールを指定するとは

IAM ポリシーは以下のように、
Principal が Resource に対して Action することを Condition の条件のもと Effect する
という構成になっています。
image.png

例1)
Lambda (Principal)が S3(Resource)に対して s3:GetObject(Action)することを Allow(Effect)する
という IAM ポリシーを書くことができます。
image.png

例2)
IAM ユーザー(Principal)が IAM ロール(Resource)に対して sts:AssumeRole(Action)することを Allow(Effect)する
という IAM ポリシーを書くことができます。
IAM ロールに設定する信頼ポリシーでよくあるパターンです。
image.png

つまり、principal に IAM ロールを指定するとは、
IAM ロール(Principal)が Resource に対して Action することを Effect する
という内容のポリシーを設定することと言えます。
image.png

で今回発見したこと

以下ドキュメントの「重要」という赤の網掛け部分です。

ロール信頼ポリシーの Principal 要素に、特定の IAM ロールを指し示す ARN が含まれている場合、その ARN はポリシーを保存するときにロールの一意のプリンシパル ID に変換されます。これにより、ロールを削除して再作成することにより、誰かがそのユーザーの特権をエスカレートするリスクを緩和できます。
通常、この ID はコンソールには表示されません。これは、信頼ポリシーが表示されるときに、IAM が ロール ARN への逆変換を行うためです。
ただし、ロールを削除すると、関係が壊れます。
ロールを再作成した場合でも、ポリシーは適用されません。これは、新しいロールは信頼ポリシーに保存されている ID と一致しない新しいプリンシパル ID を持っているためです。
この場合、プリンシパル ID はリソースベースポリシーに表示されます。これは AWS が有効な ARN に戻って ID をマッピングできなくなるためです。その結果、信頼ポリシーの Principal 要素で参照されているロールを削除して再作成する場合は、ロールを編集して正しくなくなったプリンシパル ID を正しい ARN に置き換える必要があります。ポリシーを保存するときに、ARN は再びロールの新しいプリンシパル ID に変換されます。

なんだか難しい感じがしますが、
「principal に IAM ロールを指定して、その IAM ロールを削除してから同じロール名で別の IAM ロールを作成しても、同じようにアクセスすることはできません」
ということのようです。
image.png

動作確認してみたい

検証

ロールの連鎖(Role chaining) で検証してみます。
IAM ユーザー「principal-test-user」から、IAM ロール「principal-test-role」にスイッチロールし、さらに IAM ロール「s3-access-role」にスイッチロールして S3 バケット「20221220-emiki-s3bucket」にアクセスできるか確認します。
image.png

ここでキモになるのが、IAM ロール「s3-access-role」の信頼ポリシーの Principal に IAM ロール「principal-test-role」を指定するところです。
image.png

IAM ロール「principal-test-role」を削除し、全く同じポリシーで全く同じロール名のロールを再作成した場合、S3 バケット「20221220-emiki-s3bucket」にアクセスできるのか試します。
image.png

1. IAM ユーザー「principal-test-user」を作成する

IAM ユーザー「principal-test-user」を作成します。
IAM コンソールからサクッと作成します。

  • パスワード - AWS マネジメントコンソールへのアクセス

アクセス許可の設定はしません。
AWS マネジメントコンソールへのアクセスをするために、パスワードだけ設定します。

2. IAM ロール「principal-test-role」を作成する

IAM ロール「principal-test-role」を作成します。
IAM コンソールからサクッと作成します。

  • ステップ 1 信頼されたエンティティを選択

    • 信頼されたエンティティタイプ:AWS アカウント
    • AWS アカウント:このアカウント
  • ステップ 2 許可を追加

    • AWSCloudShellFullAccess
  • ステップ 3 名前、確認、および作成

    • ロール名:principal-test-role
    • 説明:principal-test-role before
    • タグを追加
      • key:Environment
      • Value:before

image.png

作成した IAM ロール「principal-test-role」の信頼ポリシーを少し編集します。
AWS アカウントに所属する IAM ユーザーすべてが principal になっているので、先ほど作成した IAM ユーザー「principal-test-user」を principal に設定します。

principal-test-role 信頼ポリシー編集前
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

principal-test-role 信頼ポリシー編集後
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/principal-test-user"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

image.png

3. IAM ロール「s3-access-role」を作成する

S3 へのアクセス権限を持つ IAM ロール「s3-access-role」を作成します。
IAM コンソールからサクッと作成します。

  • ステップ 1 信頼されたエンティティを選択

    • 信頼されたエンティティタイプ:AWS アカウント
    • AWS アカウント:このアカウント
  • ステップ 2 許可を追加

    • AmazonS3FullAccess
  • ステップ 3 名前、確認、および作成

    • ロール名:s3-access-role
    • 説明:s3-access-role

作成した IAM ロール「s3-access-role」の信頼ポリシーを少し編集します。
AWS アカウントに所属する IAM ユーザーすべてが principal になっているので、先ほど作成した IAM ロール「principal-test-role」を principal に設定します。

s3-access-role 信頼ポリシー編集前
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

s3-access-role 信頼ポリシー編集後
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:role/principal-test-role"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

4. S3 バケットにアクセスする

「principal-test-user」で「principal-test-role」にスイッチロールし、CloudShell で「s3-access-role」にスイッチします。
二重にスイッチ後、S3 バケットにアクセスできるか確認します。

4-1. スイッチロール 1 回目

「principal-test-user」で AWS マネジメントコンソールにログインします。
続いて「principal-test-role」にスイッチロールします。
スイッチロール後の「principal-test-role」で CloudShell を開きます。
この段階で aws sts get-caller-identity すると、現在の権限が「principal-test-role」であることが分かります。

[cloudshell-user@ip-10-6-47-215 ~]$ aws sts get-caller-identity
{
    "UserId": "AROA4LMX2UGT7Q4RLBOOI:principal-test-user",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/principal-test-role/principal-test-user"
}
[cloudshell-user@ip-10-6-47-215 ~]$

4-2. スイッチロール 2 回目

この後スイッチロールする「s3-access-role」のプロファイルを設定します。
まず CloudShell で「~/.aws」ディレクトリを作成します。
(デフォルトでは存在しないようです)

[cloudshell-user@ip-10-6-47-215 ~]$ mkdir ~/.aws
[cloudshell-user@ip-10-6-47-215 ~]$ ls -la
total 37
drwxr-xr-x 5 cloudshell-user cloudshell-user 4096 Jan  9 06:53 .
drwxr-xr-x 3 root            root            1024 Jan  9 06:24 ..
drwxrwxr-x 2 cloudshell-user cloudshell-user 4096 Jan  9 06:53 .aws
-rw------- 1 cloudshell-user cloudshell-user  118 Dec 22 13:56 .bash_history
-rw-r--r-- 1 cloudshell-user cloudshell-user   18 Dec 22 13:28 .bash_logout
-rw-r--r-- 1 cloudshell-user cloudshell-user  193 Dec 22 13:28 .bash_profile
-rw-r--r-- 1 cloudshell-user cloudshell-user  314 Dec 22 13:28 .bashrc
drwxr-xr-x 3 cloudshell-user cloudshell-user 4096 Dec 22 13:28 .config
drwxr-xr-x 3 cloudshell-user cloudshell-user 4096 Jan  9 06:25 .local
-rw-r--r-- 1 cloudshell-user cloudshell-user  777 Dec 22 13:28 .zshrc
[cloudshell-user@ip-10-6-47-215 ~]$

「credentials」ファイルを作成します。
vim で「credentials」ファイルを開きます。

[cloudshell-user@ip-10-6-47-215 ~]$ vim ~/.aws/credentials

「i」を押下して編集モードに移行し、以下のように設定します。

[s3-access-role]
role_arn = arn:aws:iam::123456789012:role/s3-access-role
credential_source = EcsContainer

「esc」を押下して編集モードから抜け、「:wq」で保存します。

この段階で aws sts get-caller-identity --profile s3-access-role すると、現在の権限が「s3-access-role」であることが分かります。

[cloudshell-user@ip-10-6-47-215 ~]$ aws sts get-caller-identity --profile s3-access-role
{
    "UserId": "AROA4LMX2UGTS5YWJ3QKR:botocore-session-1673247507",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/s3-access-role/botocore-session-1673247507"
}
[cloudshell-user@ip-10-6-47-215 ~]$

4-3. S3 バケット内のオブジェクト表示

バケットとオブジェクトの一覧表示 を参考に、S3 バケット内のオブジェクトを表示します。

[cloudshell-user@ip-10-6-47-215 ~]$ aws s3 ls s3://20221220-emiki-s3bucket --profile s3-access-role
2022-12-20 14:02:16          0 test - コピー (2).txt
2022-12-20 14:02:16          0 test - コピー (3).txt
2022-12-20 14:02:16          0 test - コピー (4).txt
2022-12-20 14:02:16          0 test - コピー.txt
2022-12-20 14:02:16          0 test.txt
[cloudshell-user@ip-10-6-47-215 ~]$ 

image.png

表示できました。
ここで、CloudShell を閉じ、「principal-test-user」にスイッチバックします。

5. 「principal-test-role」を削除する

「principal-test-role」を削除します。
image.png

6. 再度同じ名前と権限で「principal-test-role」を作成する

再度同じ名前と権限で「principal-test-role」を作成します。
IAM コンソールからサクッと作成します。

  • ステップ 1 信頼されたエンティティを選択

    • 信頼されたエンティティタイプ:AWS アカウント
    • AWS アカウント:このアカウント
  • ステップ 2 許可を追加

    • AWSCloudShellFullAccess
  • ステップ 3 名前、確認、および作成

    • ロール名:principal-test-role
    • 説明:principal-test-role after
    • タグを追加
      • key:Environment
      • Value:after

image.png

作成した IAM ロール「principal-test-role」の信頼ポリシーを編集します。
AWS アカウントに所属する IAM ユーザーすべてが principal になっているので、既存の IAM ユーザー「principal-test-user」を principal に設定します。

principal-test-role 信頼ポリシー編集前
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:root"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

principal-test-role 信頼ポリシー編集後
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/principal-test-user"
            },
            "Action": "sts:AssumeRole",
            "Condition": {}
        }
    ]
}

image.png

7. S3 バケットにアクセスする

「principal-test-user」で「principal-test-role」にスイッチロールし、CloudShell で「s3-access-role」にスイッチします。
二重にスイッチ後、S3 バケットにアクセスできるか確認します。

7-1. スイッチロール 1 回目

「principal-test-user」で AWS マネジメントコンソールにログインします。
続いて「principal-test-role」にスイッチロールします。
スイッチロール後の「principal-test-role」で CloudShell を開きます。
この段階で aws sts get-caller-identity すると、現在の権限が「principal-test-role」であることが分かります。

[cloudshell-user@ip-10-6-20-151 ~]$ aws sts get-caller-identity
{
    "UserId": "AROA4LMX2UGTZFOGO2J5M:principal-test-user",
    "Account": "123456789012",
    "Arn": "arn:aws:sts::123456789012:assumed-role/principal-test-role/principal-test-user"
}
[cloudshell-user@ip-10-6-20-151 ~]$

7-2. スイッチロール 2 回目

この後スイッチロールする「s3-access-role」のプロファイルを設定します。
まず CloudShell で「~/.aws」ディレクトリを作成します。

[cloudshell-user@ip-10-6-20-151 ~]$ mkdir ~/.aws
[cloudshell-user@ip-10-6-20-151 ~]$ ls -la
total 32
drwxr-xr-x 4 cloudshell-user cloudshell-user 4096 Jan  9 07:16 .
drwxr-xr-x 4 root            root            4096 Jan  9 07:06 ..
drwxrwxr-x 2 cloudshell-user cloudshell-user 4096 Jan  9 07:16 .aws
-rw-r--r-- 1 cloudshell-user cloudshell-user   18 Jan  9 07:06 .bash_logout
-rw-r--r-- 1 cloudshell-user cloudshell-user  193 Jan  9 07:06 .bash_profile
-rw-r--r-- 1 cloudshell-user cloudshell-user  314 Jan  9 07:06 .bashrc
drwxr-xr-x 3 cloudshell-user cloudshell-user 4096 Jan  9 07:06 .config
-rw-r--r-- 1 cloudshell-user cloudshell-user  777 Jan  9 07:06 .zshrc
[cloudshell-user@ip-10-6-20-151 ~]$ 

「credentials」ファイルを作成します。
vim で「credentials」ファイルを開きます。

[cloudshell-user@ip-10-6-20-151 ~]$ vim ~/.aws/credentials

「i」を押下して編集モードに移行し、以下のように設定します。

[s3-access-role]
role_arn = arn:aws:iam::123456789012:role/s3-access-role
credential_source = EcsContainer

「esc」を押下して編集モードから抜け、「:wq」で保存します。

この段階で aws sts get-caller-identity --profile s3-access-role すると、アクセスが拒否されます。

[cloudshell-user@ip-10-6-20-151 ~]$ aws sts get-caller-identity --profile s3-access-role

An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::123456789012:assumed-role/principal-test-role/principal-test-user is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::123456789012:role/s3-access-role
[cloudshell-user@ip-10-6-20-151 ~]$

7-3. S3 バケット内のオブジェクト表示

S3 バケット内のオブジェクト一覧も表示できません。

[cloudshell-user@ip-10-6-20-151 ~]$ aws s3 ls s3://20221220-emiki-s3bucket --profile s3-access-role

An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:sts::123456789012:assumed-role/principal-test-role/principal-test-user is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::12345689012:role/s3-access-role
[cloudshell-user@ip-10-6-20-151 ~]$ 

image.png

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?