こんにちは!
エンタープライズクラウド部技術2課の日高です。
本日は、特定IAMユーザー&IAMロール以外のS3バケットへのアクセスを拒否するバケットポリシーの記載方法についてまとめます。
はじめに(困っていたこと)
お客様から次のようなご要望をいただきました。
- 特定のIAMユーザーとIAMロールのみがS3バケットにアクセスできるように制限をかけたい。
- 承認されたユーザー以外はS3バケットの情報を一切閲覧できないようにしたい。
AWSの「グローバル条件コンテキストキー」を使用した"Condition"句によりアクセス制限が可能だと予想していましたが、具体的にどのように"Condition"句を設定すれば良いのかが分からず、この点について調査を進めました。
解決方法
S3バケットポリシー
結論から申し上げると、下記のS3バケットポリシーを利用することで、アクセスを特定の条件下で制限することが可能です。
IAMユーザーとIAMロールの両方にアクセス権を付与する必要がある場合、「aws:username」ではIAMユーザーのみしか制限できないため「aws:userId」を使用しました。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::<バケット名>", "arn:aws:s3:::<バケット名>/*" ], "Condition": { "StringNotLike": { "aws:userId": [ "<UserId>", "<RoleId>:*" ] } } } ] }
※<バケット名>を制限したいバケットの名前に、
S3バケットポリシーの解説
- 「バージョン」は、ポリシー言語がリリースされた日付、「2012-10-17」を指します。
- ポリシーの「ステートメント」は、そのルールを具体的に定める部分です。
ステートメントには次のような指示が含まれます:
- 「効果」は、「Deny」と設定されており、指定した操作を禁止することを意味します。
- 「プリンシパル」は、「*」と設定されており、すべてのユーザーが対象です。
- 「アクション」は、「s3:*」と設定されており、S3のすべての操作が対象です。
- 「リソース」は、「arn:aws:s3:::<バケット名>」と「arn:aws:s3:::<バケット名>/*」が指定されており、特定のバケットとその中のすべてのオブジェクトが対象です。
- 「条件」は、「StringNotLike」というキーを使用し、特定のユーザーID(「aws:userId」)が指定した値に合致しない場合に限り、この禁止ルールが適用されます。
つまり、このポリシーは全ユーザーに対し、特定のS3バケット及びその内容物への全操作を禁止しますが、一部のIAMユーザーやIAMロール(条件で指定されたUserIdやRoleIdを持つ者)はこの規則から除外されるバケットポリシーになっています。
これにより、指定されたユーザーやロールのみにアクセスを許可し、他のユーザーのアクセスを防ぐことで、バケットのセキュリティを強化しています。
UserIdの調べ方
下記の、AWS CLIを実行することで調べることができます。(<ユーザー名>は対象のIAMユーザー名に置き換えてください。)
aws iam list-users --query 'Users[?UserName==`<ユーザー名>`].UserId' --output text
aws iam list-users(何もオプションをつけずに)を実行すると、下記のように全てのユーザーの情報が表示されてしまいます。 ※UserNameやUserIdはでたらめな値にしています。
{ "Users": [ { "Path": "/", "UserName": "aaaaaaaaaaaa", "UserId": "AIDAUMRDAFDAHXEQ4DAF3G", "Arn": "arn:aws:iam::××××××××××:user/aaaaaaaaaaaa", "CreateDate": "2022-07-05T02:07:33+00:00", "PasswordLastUsed": "2023-09-07T05:32:52+00:00" }, { "Path": "/", "UserName": "bbbbbbbbbbbb", "UserId": "FADJF3DALDKFA2DAFJFA", "Arn": "arn:aws:iam::××××××××××:user/bbbbbbbbbbbb", "CreateDate": "2023-08-08T06:45:37+00:00", "PasswordLastUsed": "2023-08-08T06:46:35+00:00" } ] }
そのため--query 'Users[?UserName==<ユーザー名>
].UserId' で、指定したIAMユーザーのUserIdだけ表示されるようにフィルタリングしています。
- コマンドの実行結果
% aws iam list-users --query 'Users[?UserName==`aaaaaaaaaaaa`].UserId' --output text AIDAUMRDAFDAHXEQ4DAF3G
RoleIdの調べ方
下記の、AWS CLIを実行することで調べることができます。(<ロール名>は対象のIAMロール名に置き換えてください。)
aws iam get-role --role-name <ロール名> --query 'Role.RoleId' --output text
aws iam get-role --role-name Test-Role(フィルタリングしないで)を実行すると、下記のように色々な情報が表示されてしまいます。
{ "Role": { "Description": "Test Role", "AssumeRolePolicyDocument":"<URL-encoded-JSON>", "MaxSessionDuration": 3600, "RoleId": "AROA1234567890EXAMPLE", "CreateDate": "2019-11-13T16:45:56Z", "RoleName": "Test-Role", "Path": "/", "RoleLastUsed": { "Region": "us-east-1", "LastUsedDate": "2019-11-13T17:14:00Z" }, "Arn": "arn:aws:iam::123456789012:role/Test-Role" } }
そのため--query 'Role.RoleId' で、指定したIAMロールーのRoleIdだけ表示されるようにフィルタリングしています。
- コマンドの実行結果
% aws iam get-role --role-name Test-Role --query 'Role.RoleId' --output text AROA1234567890EXAMPLE
まとめ
意外と調べてみると時間がかかったので、ブログにまとめてみました。
本記事だ誰かの助けになれば幸いです。
日高 僚太(執筆記事の一覧)
2024 Japan AWS Jr. Champions / 2024 Japan AWS All Certifications Engineers
EC部クラウドコンサルティング課所属。2022年IT未経験でSWXへ新卒入社。
記事に関するお問い合わせや修正依頼⇒ hidaka@serverworks.co.jp