概要

IAMユーザを使用できるプリンシパルをIPやソースのVPCエンドポイントで絞りたいです。

※プリンシパル:AWSのリソースに対してアクションやオペレーションを実行できる人、もしくはアプリケーションのこと

図にすると以下となります。

要件を満たすIAM ポリシーを作成する

やりたいこと:プログラム経由(CLI、SDK等)のIAMを使うプリンシパルが以下の場合はアクセスを許可したい

  1. アカウントAのVPCエンドポイントを経由している
  2. 特定のパブリックIP
  3. AWSのサービス

つまり1 or 2 or 3であればIAMが使えます。
ソースIPを絞りたい場合、こちらの公式ドキュメントを参考にIAMポリシーを作成しました。
また、経由するVPCエンドポイントを絞るのは「StringNotEquals」と「aws:SourceVpce」の組み合わせを使いました。
以下が完成したIAMポリシーです。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Deny",
        "Action": "*",
        "Resource": "*",
        "Condition": {
            "StringNotEquals": {
                "aws:SourceVpce": [
                    ""
                ]
            },
            "NotIpAddress": {
                "aws:SourceIp": [
                    ""
                ]
            },
            "Bool": {
                "aws:ViaAWSService": "false"
            }
        }
    }
}

これは以下の3つのAND条件となります。

  1. アカウントAのVPCエンドポイントを経由していない
  2. 特定のパブリックIPではない
  3. AWSのサービスではない

なぜこんなややこしい書き方をするかというと、
IAMポリシーのConditionに対する評価ロジックはAND条件となるためです。

つまり、この章の初めに記載したOR条件ではポリシーを記述することができず、中学生・高校生の時にやった集合でいうところの対偶(正反対)の条件に書き換える必要がありました。

文字だと分かりにくいため、図にすると以下となります。

検証

念のため、以下の条件で動作検証をしてみました。

  1. Account Aのプライベートサブネット上に存在するEC2へuser Aのクレデンシャルを登録してAccount BのS3へアクセスできる(図のオレンジの経路)
  2. Account Aのパブリックサブネット上に存在するEC2へuser Aのクレデンシャルを登録してAccount BのS3へアクセスできる(図の水色の経路)

※水色の経路はローカルからCLIを実行しているのと同じです

以下コマンドでアカウントBのバケットへアクセスすることができました。

aws s3 ls s3://バケット名

また、逆にIAMポリシーのConditionに記述しているIPやVPCエンドポイントのIDを存在しないものに書き換えた場合、アクセスができなくなりました。

おわりに

IAMポリシーのCondition句「StringNotEquals」や「NotIpAddress」といったNotのDenyは分かりづらいですが、整理して考えることができれば大変柔軟が効くポリシーを書くことができます。
機会があれば使ってみてください!

元記事はこちら

IPとVPC EndpointでIAM Userが使えるプリンシパルを制限
著者:@suzuki_kento


アイレットなら、AWS で稼働するサーバーを対象とした監視・運用・保守における煩わしい作業をすべて一括して対応し、経験豊富なプロフェッショナルが最適なシステム環境を実現いたします。AWS プレミアコンサルティングパートナーであるアイレットに、ぜひお任せください。

AWS 運用・保守サービスページ

その他のサービスについてのお問合せ、お見積り依頼は下記フォームよりお気軽にご相談ください。
https://cloudpack.jp/contact/form/