スポンサーリンク
AWSIAMOrganizationsS3

IAMポリシーで”aws:SourceIp”を利用する際の注意点

AWS

概要

特定のアクセス元IP以外からのアクセスを拒否したい場合、下記のようにポリシー内のConditionブロックへ“aws:SourceIp”を記述する事で実現可能です。
※ユースケース:IAMユーザに付与するポリシー、OUのSCP等https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_examples_aws_deny-ip.html

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Deny",
        "Action": "*",
        "Resource": "*",
        "Condition": {
            "NotIpAddress": {
                "aws:SourceIp": [
                    "192.0.2.0/24",
                    "203.0.113.0/24"
                ]
            }
        }
    }
}

ただし、下記のようにAWSサービスがユーザ(アクセス元IP)に代わって処理を実行するケースでは、アクセス元IPがAWSサービスのものへ置き換わるため、アクセスが拒否されエラーが発生します。

<エラーが発生するケースの例>

  • KMSで暗号化されたS3バケットから、ファイルをDL/ULする
    ※AWSがユーザに代わってKMS経由でファイルを暗号化・複合化する際にエラーが発生する
  • KMSで暗号化されたEBSボリュームを作成する
  • CloudFormationによるアクセス
  • CloudShellによるアクセス

解決策

下記のようにポリシー内のConditionブロックへ、“aws:ViaAWSService”を追記します。
“aws:ViaAWSService”は、AWS サービスがユーザに代わって別のサービスへアクセスする場合、”true”を返却します。
下記ポリシーでは、ユーザによるアクセスは”aws:SourceIp”によるIP制限を適用し、AWSサービスがアクセスする場合はIP制限を適用しません。https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-viaawsservice

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

ただし、一部サービスは”aws:ViaAWSService”でサポートされていないようです。
※未サポート:CloudShellやAWS Backup、EC2、AWS Glue等

解決策(CloudShell)

CloudShellからのアクセスは、裏でAWSが稼働させているコンテナのIPでアクセスされる形となります。
また、CloudShellはAWSサービス経由で呼び出されるもの扱いではないため、“aws:ViaAWSService”でサポートされていません。
CloudShellからのアクセスを許容する場合は、下記のようにポリシー内のConditionブロックへ、“aws:UserAgent”を追記します。
“aws:UserAgent”で、アプリケーションを指定可能です。下記ポリシーではCloudShellを指定してIP制限を回避しています。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Deny",
        "Action": "*",
        "Resource": "*",
        "Condition": {
            "NotIpAddress": {
                "aws:SourceIp": [
                    "192.0.2.0/24",
                    "203.0.113.0/24"
                ]
            },
            "Bool": {"aws:ViaAWSService": "false"},
            "StringNotLike": {
                "aws:userAgent": "*exec-env/CloudShell*"
            }
        }
    }
}

ただし、以下の通りHTTPヘッダー内で改ざんが可能な値なので、外部からポリシー設定値を参照出来ないよう制限するなど、ガバナンスを効かせる必要があります。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-useragent

このキーは慎重に使用する必要があります。しかし、aws:UserAgent 値は HTTP ヘッダー内の発信者によって渡されるため、不正な当事者が改造またはカスタムブラウザを使用して任意の aws:UserAgent 値を渡すことができます。そのため aws:UserAgent は、不正な当事者から AWS にリクエストが直接行われることを防止するために使用しないでください。このステートメントを使用して、ポリシーをテストした後にのみ、特定のクライアントアプリケーションのみを許可できます。

解決策(最小限の範囲)

AWSサービスがアクセスする範囲を最小限としたい場合、”aws:ViaAWSService”ではなく対象サービスの条件キーや”aws:UserAgent”で指定します。
下記ポリシーでは、KMSで暗号化されたリソースへAWSサービス経由でのアクセスを許可するため、KMSの条件キーを使用して、”Null”:{“kms:ViaService”: “true”}を記述しています。

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Deny",
        "Action": "*",
        "Resource": "*",
        "Condition": {
            "NotIpAddress": {
                "aws:SourceIp": [
                    "192.0.2.0/24",
                    "203.0.113.0/24"
                ]
            },
            "Null": {
                "kms:ViaService": "true"
            }
        }
    }
}

コメント

タイトルとURLをコピーしました