aws:SourceIp キーを使用したIAM ポリシーを使う時に覚えておきたいこと

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

aws:SourceIp キーを使用してIAM ポリシーによりアクセス制限を実施していることがあると思います。例えばIAM グループが以下のようなポリシーを持っており、IAM ユーザーはそのIAM グループに属している場合です。

ポリシー例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "xxx.xxx.xxx.xxx/32",
                        "yyy.yyy.yyy.yyy/32",
                        "zzz.zzz.zzz.zzz/32"
                    ]
                }
            }
        }
    ]
}

このポリシーではaws:SourceIpのIPアドレス以外からのアクセスはDenyで拒否しています。特に問題がないポリシーかと思いますが、意図しない動作が発生する場合があります。

例えば、CloudFrontや、ELBでのACM証明書を登録した時、CloudFormation でテンプレートを Amazon S3 にアップロード時など。

これはaws:SourceIp条件キーが以下の性質を持っているためです。

  • aws:SourceIp 条件キーは、指定された IAMユーザー、グループ、ロール、フェデレーテッドユーザーのJSONポリシーでのみ使用する
  • ユーザーに代わり他のサービスがAIPをコールする場合はアクセスを拒否される

ドキュメントに記載されていますので引用します。

AWS グローバル条件コンテキストキー | aws:SourceIp 注記

aws:SourceIp 条件キーは、指定された IP 範囲内から API コールを行う IAM ユーザー、グループ、ロール、またはフェデレーティッドユーザーの JSON ポリシーでのみ使用する必要があります。このポリシーは、ユーザに代わって API をコールする AWS サービスへのアクセスを拒否します。 たとえば、AWS CloudFormation がインスタンスを停止するために Amazon EC2 を呼び出すことを許可するサービスロールがあるとします。この場合、ターゲットサービス (Amazon EC2) が発信ユーザーの IP アドレスではなく、発信サービス (AWS CloudFormation) の IP アドレスを認識するため、リクエストは拒否されます。JSON ポリシーで評価を行うために、発信元サービスを通じて元の IP アドレスをターゲットサービスに渡す方法はありません。

IAM JSON ポリシーエレメント: 条件演算子 | IP アドレス条件演算子

aws:SourceIp 条件キーは、テストされた API をユーザーとして直接呼び出す場合に JSON ポリシーでのみ機能します。代わりにサービスを使用してターゲットサービスを呼び出した場合、ターゲットサービスは元のユーザーの IP アドレスではなく呼び出し元サービスの IP アドレスを認識します。これは、AWS CloudFormation を使用して Amazon EC2 を呼び出すことでインスタンスを自動的に作成した場合などに生じることがあります。現在のところ、JSON ポリシーで評価を行うために、発信元サービスを通じて元の IP アドレスをターゲットサービスに渡す方法はありません。これらのタイプのサービス API 呼び出しでは、aws:SourceIp 条件キーを使用しないでください。

では、実際にエラーが発生した時にどのように対処すればいいでしょうか。ワークアラウンドについてみていきましょう。

ワークアラウンド

ドキュメントからも、発信元サービスを通じて元の IP アドレスをターゲットサービスに渡す方法はありません。 とありますが、以下2つの方法でエラーが解消されるか確認してみてください。

  • AWS KMS の条件キーkms:ViaServiceをつけて試してみる
  • 一時的にaws:SourceIp を利用したアクセス制限をやめる

AWS KMS の条件キーkms:ViaServiceをつけて試してみる

ソースIPによるアクセス制限ができないサービスがありますが、AWS KMSではkms:ViaServiceにより他サービスからKMSへのアクセスを許可することができます。

例えば、ELBで、ACM証明書を登録しようとした時にエラーが出た場合はこちらの方法で解決する可能性があります。これはACM証明書登録の際にKMSが使用されているためです。AWS KMSが関係している場合はこちらの対応でエラーが解消する可能性があります。

ACM のプライベートキーのセキュリティ

ACM には証明書と対応するプライベートキーが保存され、AWS Key Management Service(AWS KMS) を使用してプライベートキーを保護する役目を果たします。

AWS KMS でのポリシー条件の使用 | kms:ViaService

たとえば kms:ViaService を使用して、Amazon S3 がユーザー代理として行うリクエストにのみ、ユーザーがカスタマー管理の CMK を使用できるように許可することができます。または、ユーザー代理のリクエストが AWS Lambda から送信された時に、CMK へのユーザー許可を拒否するために使用することができます。

ボリシー例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
              "Null": {
                "kms:ViaService": "true"
              },
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "xxx.xxx.xxx.xxx/32",
                        "yyy.yyy.yyy.yyy/32",
                        "zzz.zzz.zzz.zzz/32"
                    ]
                }
            }
        }
    ]
}

KMSへのアクセスによるエラーの場合はこちらの対応で解消される可能性がありますが解消されない場合は以下方法にて対応します。

一時的にaws:SourceIp を利用したアクセス制限をやめる

一部のサービスではソースIPによるアクセス制限ができないため、一時的にソースIPによるアクセス制限を解除します。

まとめ

ソースIPアドレスによりアクセス制限をしている場合aws:SourceIpの仕様のため、意図しない動作が発生する場合がありますが本ブログでご紹介したワークアラウンドを参考にしていただけますと幸いです。

参考URL