特定のLambda関数とIPアドレスからのアクセスに限定するS3バケットポリシー
アクセスログのレポートをLambdaで作成してS3バケットに保存し、特定のIPアドレスからのみアクセスできるようにしたいという要件があり、初めてS3のバケットポリシーを触りました。
少しだけ悩みましたが、意外と簡単にできたので紹介します。
なお、バケットポリシーについて、詳しくはドキュメントをご覧ください。
作成したポリシー
最終的に以下のポリシーになりました。
{
"Version": "2012-10-17",
"Id": "Policy1622780470027",
"Statement": [
{
"Sid": "Stmt1622780370514",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account ID>:role/IAM role Name"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::Backet Name/*"
},
{
"Sid": "Stmt1622780460676",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::Backet Name/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"IP Address",
"IP Address"
]
}
}
}
]
}
2つのブロック
Statementの中でブロックを2つに分けることで、うまくいきました。
当初は1つのブロックで、
- PrincipalにIAMロールを指定
- ConditionにIPアドレスを指定
という記述をしていたのですが、これだとIPアドレスの方のアクセスが拒否されてしまいました。
そこで、複数の否定条件を使ったS3バケットポリシーを正しく理解してますか? | DevelopersIOの以下の記述を参考にしました。
つまり複数条件を書く場合、以下のいずれかになります。
・"Effect" ブロックを分ける場合は OR 条件
・"Effect" ブロック内で "Condition" または "Key" を分ける場合は AND 条件
上記から、まずはブロックを分けて、
- PrincipalでLambdaにアタッチしたIAMロールからのみアクセスを許可する
- Conditionで特定のIPアドレスからのみアクセスを許可する
という記述に変えてみたところ、LambdaとIPの両方からのみアクセスできました。
Lambdaからのアクセスについて
これはすぐに解決したのですが、Lambdaからのアクセスは、Lambdaにアタッチしたロールを指定することで実現できました。
最初は単にLambdaのARNかと思って指定して失敗しましたが、公式QAを見て理解しました。
パブリックアクセスのブロック
デフォルトでS3バケットを作成すると、パブリックアクセスはすべてブロックになります。
この状態で、バケットポリシーのPrincipalでIAMロールを指定し、Lambdaからリクエストした際に、なぜかアクセスが拒否されるということもありました。
理由は、リクエストパラメーターにACL: 'public-read'
を付与していたことでした。
上記に関してはドキュメントにも記載がありました。
リクエストにパブリック ACL が含まれていると、PUT Object 呼び出しは失敗します。
ACL: 'public-read'
を除いてリクエストしたところ、アクセスできました。
ポリシージェネレータ
今までバケットポリシーを触ったことがなかったので知りませんでしたが、GUIでバケットポリシーを生成してくれるツールがS3コンソールにありました。
対象サービス、Principal、Conditionなどを選択、入力するだけでポリシーを生成してくれるので、すごく便利でした!
まとめ
今回は特定のLambda関数とIPアドレスからのアクセスに限定するS3バケットポリシーを紹介しました。
初めて触ったバケットポリシーで、少し苦戦しましたが、また1つセキュリティ対策の術を身に付けられた気がします。
ポリシージェネレーターがとても便利だったので、これで色々遊ぶと面白そうですが、設定ミスってバケットに触れなくなったという記事もあったので気を付けましょう!
初歩的な内容でしたが、参考になれば幸いです。
Discussion