Upgrade to Pro — share decks privately, control downloads, hide ads and more …

閉域要件におけるS3周辺ポリシーの組み合わせ方

 閉域要件におけるS3周辺ポリシーの組み合わせ方

Security-JAWS第23回での登壇資料です。
イベントURL:https://s-jaws.doorkeeper.jp/events/127684
登壇動画URL:https://youtu.be/Q-dKRmVgpRA?t=5860

More Decks by みずほリサーチ&テクノロジーズ株式会社 先端技術研究部

Other Decks in Technology

Transcript

  1. 閉域要件における S3周辺ポリシーの組み合わせ方 2021.11.11 Security-JAWS 第23回 Copyright (c) Mizuho Research &

    Technologies, Ltd. All Rights Reserved. (免責事項) 当資料は情報提供のみを目的として作成されたものであり、商品の勧誘を目的としたものではありません。 本資料は、当社が信頼できると判断した各種データに基づき作成されておりますが、その正確性、確実性を 保証するものではありません。また、本資料に記載された内容は予告なしに変更されることもあります。
  2. 自己紹介  氏名:松尾 優成(まつお ゆうせい)  所属:先端技術研究部 兼 プロジェクト推進部 

    役割:  AWS社内案件の設計・構築サポート  みずほコミュニティ ERG ”コクリエ” の運営
  3. アカウントA 構成概要  オンプレミスからS3に格納したユーザー情報を、EC2 で分析して還元するシステム。 VPC Corporate data center bucket-a

    Direct Connect VPCe (I/F型) VPCe (G/W型) 閉域用 bucket-b S3 ・ ・ ・ EC2 運用者 ①オンプレミスにある ユーザー情報を・・・
  4. アカウントA 構成概要  オンプレミスからS3に格納したユーザー情報を、EC2 で分析して還元するシステム。 VPC Corporate data center bucket-a

    Direct Connect VPCe (I/F型) VPCe (G/W型) 閉域用 bucket-b S3 ・ ・ ・ EC2 運用者 ②S3にアップロード
  5. アカウントA 構成概要  オンプレミスからS3に格納したユーザー情報を、EC2 で分析して還元するシステム。 VPC Corporate data center bucket-a

    Direct Connect VPCe (I/F型) VPCe (G/W型) 閉域用 bucket-b S3 ・ ・ ・ EC2 運用者 ③S3のデータをEC2でETL処理
  6. アカウントA 構成概要  オンプレミスからS3に格納したユーザー情報を、EC2 で分析して還元するシステム。 VPC Corporate data center bucket-a

    Direct Connect VPCe (I/F型) VPCe (G/W型) 閉域用 bucket-b S3 ・ ・ ・ EC2 運用者 ④EC2から再度S3に アップロードし・・・
  7. アカウントA 構成概要  オンプレミスからS3に格納したユーザー情報を、EC2 で分析して還元するシステム。 VPC Corporate data center bucket-a

    Direct Connect VPCe (I/F型) VPCe (G/W型) 閉域用 bucket-b S3 ・ ・ ・ EC2 運用者 ⑤オンプレミスに処理済みの ユーザー情報を還元
  8. 閉域網だからといって、きちんと対策しないと・・・ VPC Corporate data center Direct Connect VPCe (I/F型) VPCe

    (G/W型) EC2 閉域用 運用者 アカウントC(社外) アカウントA bucket-z 流出! C C データ流出リスクがある!→ C
  9. データ流出観点で着目するポリシーは3つ VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA Ⅰ. IAMポリシー Ⅱ. VPCエンドポイントポリシー Ⅲ. バケットポリシー Ⅰ Ⅰ Ⅲ Ⅱ
  10. アカウントA 重要データを保持するのは3箇所 VPC Corporate data center bucket-a Direct Connect VPCe

    (I/F型) VPCe (G/W型) 閉域用 bucket-b S3 ・ ・ ・ EC2 ① 閉域用端末 ② EC2 ③ S3バケット 運用者 ←これらに置かれたデータが流出するのを防ぎたい・・・! ① ② ③
  11. VPCe利用者のアクセス権限 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ① ② ③
  12. VPCe利用者のアクセス権限 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ① 閉域用端末 ② EC2 ③ S3バケット ←①と②に焦点を絞ってみる ① ② ③
  13. VPCe利用者のアクセス権限 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ }
  14. VPCe利用者のアクセス権限 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ } IAMポリシーのAction句は最小権限を前提。
  15. VPCe利用者のアクセス権限 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ } 最小権限を厳密にするならば、Resource句で bucket-a, bucket-b のように書くべきだが・・・
  16. VPCe利用者のアクセス権限 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ } S3バケット増加に伴うポリシー更新体力を 抑えるため、ワイルドカードを使いたい
  17. VPCe利用者のアクセス権限 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ } というわけで、やはりワイルドカードを使いたい!
  18. VPCe利用者:不正経路 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントC(社外) アカウントA bucket-z bucket-zをアカウントCに作成
  19. VPCe利用者:不正経路 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントC(社外) アカウントA bucket-z IAMポリシーにワイルドカードを利用 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ }
  20. VPCe利用者:不正経路 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントC(社外) アカウントA bucket-z 社外のS3バケットポリシーに以下を設定 { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::{アカウントA-ID}:root" }, "Action": "s3:*", "Resource”: "arn:aws:s3:::bucket-z/*" } IAMポリシーにワイルドカードを利用 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ }
  21. VPCe利用者:不正経路 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントC(社外) アカウントA bucket-z IAMポリシーにワイルドカードを利用 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*“ } 社外のS3バケットポリシーに以下を設定 { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::{アカウントA-ID}:root" }, "Action": "s3:*", "Resource”: "arn:aws:s3:::bucket-z/*" } 流出!
  22. VPCe利用者:不正経路 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントC(社外) アカウントA bucket-z 流出! ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*" }
  23. IAMロール:S3アカウント制限を追加 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントC(社外) アカウントA bucket-z ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*" } ・追加IAMポリシー例 { "Effect": "Deny", "Action": "s3:*", "Resource": "*", "Condition": { "StringNotEquals": { "s3:ResourceAccount": "アカウントA-ID" } } 参考) https://dev.classmethod.jp/articles/iam-condition-keys-amazon-s3-resource-account/
  24. IAMロール:S3アカウント制限を追加 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントC(社外) アカウントA bucket-z ・追加IAMポリシー例 { "Effect": "Deny", "Action": "s3:*", "Resource": "*", "Condition": { "StringNotEquals": { "s3:ResourceAccount": "アカウントA-ID" } } 制限可能! 参考) https://dev.classmethod.jp/articles/iam-condition-keys-amazon-s3-resource-account/ ・IAMポリシー例 { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:ListBucket" ], "Resource": "arn:aws:s3:::bucket-*" }
  25. クレデンシャル持ち込みパターン VPC Corporate data center Direct Connect VPCe (I/F型) VPCe

    (G/W型) EC2 閉域用 運用者 アカウントC(社外) アカウントA bucket-z アクセス者側で アカウントCの クレデンシャルを利用 C C C
  26. クレデンシャル持ち込みパターン VPC Corporate data center Direct Connect VPCe (I/F型) VPCe

    (G/W型) EC2 閉域用 運用者 アカウントC(社外) アカウントA bucket-z 流出! C C C
  27. クレデンシャル持ち込みパターン VPC Corporate data center Direct Connect VPCe (I/F型) VPCe

    (G/W型) EC2 閉域用 運用者 アカウントC(社外) アカウントA bucket-z 流出! C C 社外のクレデンシャルを持ち込まれると、 S3 データイベントの CloudTrail ログが アカウントAで記録されないため、要注意。 C
  28. { "Statement": [ { "Effect": "Deny", "Principal": {"AWS": "*"}, "Action":

    "*", "Resource": "*", "Condition": { "StringNotEquals": { "aws:PrincipalAccount": "アカウントA-ID" } } }, { "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": "*" } ] } 本ポリシーでクレデンシャルの持ち込み 利用を制限可能。 ※s3:ResourceAccountの記載は割愛。 VPCエンドポイントポリシー例 VPC VPCe (I/F型) VPCe (G/W型) アカウントA
  29. { "Statement": [ { "Effect": "Deny", "Principal": {"AWS": "*"}, "Action":

    "*", "Resource": "*", "Condition": { "StringNotEquals": { "aws:PrincipalAccount": "アカウントA-ID" } } }, { "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": "*" } ] } ただし、EC2でAmazon Linuxの リポジトリを利用している場合は要注意。 VPCエンドポイントポリシー例 VPC VPCe (I/F型) VPCe (G/W型) EC2 アカウントA
  30. { "Statement": [ { "Effect": "Deny", "Principal": {"AWS": "*"}, "Action":

    "*", "Resource": "*", "Condition": { "StringNotEquals": { "aws:PrincipalAccount": "アカウントA-ID" } } }, { "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": "*" } ] } yum updateのリクエストでは アカウントAのprincipal情報をもたないため、 アクセス拒否されてしまう。 VPCエンドポイントポリシー例 VPC VPCe (I/F型) VPCe (G/W型) EC2 アカウントA AWS管理 amazonlinux リポジトリ
  31. { "Statement": [ { "Effect": "Deny", "Principal": {"AWS": "*"}, "Action":

    "*", “NotResource": "arn:aws:s3:::amazonlinux.{region}.amazonaws.com/*", "Condition": { "StringNotEquals": { "aws:PrincipalAccount": "アカウントA-ID" } } }, { "Effect": "Allow", "Principal": "*", "Action": "*", "Resource": "*" } ] } アカウントA EC2が使用するVPCeのエンドポイントポリシーでは NotResource句 を使って以下を指定すれば、 AmazonLinuxリポジトリにアクセス可。 VPCエンドポイントポリシー例 VPC VPCe (I/F型) VPCe (G/W型) EC2 AWS管理 amazonlinux リポジトリ
  32. 重要データを保持するのは3箇所 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ① 閉域用端末 ② EC2 ③ S3バケット ←①と②は前述の対策で大丈夫そう ① ② ③
  33. 重要データを保持するのは3箇所 VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ① 閉域用端末 ② EC2 ③ S3バケット ←次に③S3バケットへの正常・不正経路を考えてみる ① ② ③
  34. アカウントA S3バケット:正常経路の洗い出し VPC Corporate data center bucket-a Direct Connect VPCe

    (I/F型) VPCe (G/W型) EC2 Management Console アカウントB(ユーザー管理) IAM User 閉域用 インターネット用 Read Only Role bucket-b S3 ・ ・ ・ CloudFormation S3 Replication 運用者 ① ② ③ ④ ⑤ IP制限
  35. S3バケット:不正経路の洗い出し VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 インターネット用 bucket-b S3 ・ ・ ・ AWS Services 運用者 ③ ① ② アカウントC(社外) アカウントA Public Access AWS Services
  36. "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket-a", "arn:aws:s3:::bucket-a/*"

    ], "Condition": { "StringNotEquals": { "aws:sourceVpce": [ “S3VPCe(I/F型)のID", “S3VPCe(G/W型)のID" ] }, "StringNotLike": { "aws:userId": [ "{ReadOnlyRoleID}:*", "{CFnRoleID}:*", "{S3ReplicationRoleID}:*" ] } ①~⑤のいずれかに一致しない場合 Denyする例。 S3バケットポリシー例 ※色々書き方はあるのでご参考程度に・・・ アカウントA bucket-a VPCe (I/F型) VPCe (G/W型) Read Only Role S3 CloudFormation S3 Replication ① ② ③ ④ ⑤ ① ② ③ ④ ⑤
  37. S3 "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket-a",

    "arn:aws:s3:::bucket-a/*" ], "Condition": { "StringNotEquals": { "aws:sourceVpce": [ “S3VPCe(I/F型)のID", “S3VPCe(G/W型)のID" ] }, "StringNotLike": { "aws:userId": [ "{ReadOnlyRoleID}:*", "{CFnRoleID}:*", "{S3ReplicationRoleID}:*" ] } 逆に言うと、①~⑤のいずれかに 一致すればアクセス可能。 S3バケットポリシー例 ※色々書き方はあるのでご参考程度に・・・ アカウントA VPCe (I/F型) VPCe (G/W型) Read Only Role CloudFormation S3 Replication ① ② ③ ④ ⑤ ① ② ③ ④ ⑤ bucket-a
  38. "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket-a", "arn:aws:s3:::bucket-a/*"

    ], "Condition": { "StringNotEquals": { "aws:sourceVpce": [ “S3VPCe(I/F型)のID", “S3VPCe(G/W型)のID" ] }, "StringNotLike": { "aws:userId": [ "{ReadOnlyRoleID}:*", "{CFnRoleID}:*", "{S3ReplicationRoleID}:*" ] } リクエスト元のVPCエンドポイントIDを検査。 S3バケットポリシー例 ※色々書き方はあるのでご参考程度に・・・ アカウントA VPCe (I/F型) VPCe (G/W型) ① ② ① ② bucket-a S3
  39. S3 "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket-a",

    "arn:aws:s3:::bucket-a/*" ], "Condition": { "StringNotEquals": { "aws:sourceVpce": [ “S3VPCe(I/F型)のID", “S3VPCe(G/W型)のID" ] }, "StringNotLike": { "aws:userId": [ "{ReadOnlyRoleID}:*", "{CFnRoleID}:*", "{S3ReplicationRoleID}:*" ] } S3バケットポリシー例 ※色々書き方はあるのでご参考程度に・・・ アカウントA Read Only Role CloudFormation S3 Replication ③ ④ ⑤ ③ ④ ⑤ bucket-a リクエスト元の IAM ロールIDを検査。
  40. "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket-a", "arn:aws:s3:::bucket-a/*"

    ], "Condition": { "StringNotEquals": { "aws:sourceVpce": [ “S3VPCe(I/F型)のID", “S3VPCe(G/W型)のID" ] }, "StringNotLike": { "aws:userId": [ "{ReadOnlyRoleID}:*", "{CFnRoleID}:*", "{S3ReplicationRoleID}:*" ] } (注意点) ③のスイッチロール時はランダムにセッション名が発行 されるが、Principal 句でワイルドカード利用不可。 aws:userId を使用して制御する。 参考) https://dev.classmethod.jp/articles/s3-bucket-acces-to-a-specific-role/ S3バケットポリシー例 ※色々書き方はあるのでご参考程度に・・・ アカウントA Read Only Role ③ ③ bucket-a アカウントB (ユーザー管理) IAM User AWS STS S3
  41. S3 "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket-a",

    "arn:aws:s3:::bucket-a/*" ], "Condition": { "StringNotEquals": { "aws:sourceVpce": [ “S3VPCe(I/F型)のID", “S3VPCe(G/W型)のID" ] }, "StringNotLike": { "aws:userId": [ "{ReadOnlyRoleID}:*", "{CFnRoleID}:*", "{S3ReplicationRoleID}:*" ] } S3バケットポリシー例 ※色々書き方はあるのでご参考程度に・・・ アカウントA CloudFormation S3 Replication ④ ⑤ ③ ④ ⑤ bucket-a AWSサービスの場合は、Principal句や aws:PrincipalServiceName でも記述可。
  42. S3 "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::bucket-a",

    "arn:aws:s3:::bucket-a/*" ], "Condition": { "StringNotEquals": { "aws:sourceVpce": [ “S3VPCe(I/F型)のID", “S3VPCe(G/W型)のID" ] }, "StringNotLike": { "aws:userId": [ "{ReadOnlyRoleID}:*", "{CFnRoleID}:*", "{S3ReplicationRoleID}:*" ] } S3バケットポリシー例 ※色々書き方はあるのでご参考程度に・・・ アカウントA bucket-a バケット自体のArnをResource句に指定すると Condition句の設定ミス時にrootユーザー以外で バケットを全く触れなくなるので要注意。
  43. アカウントA VPCe (I/F型) VPCe (G/W型) Read Only Role S3 CloudFormation

    S3 Replication bucket-a Access point Access point VPC access point S3アクセスポイントポリシーのざっくり説明 ※詳細は割愛 バケットポリシー: 特定のアクセスポイントからのリクエスト以外をDeny。
  44. アカウントA VPCe (I/F型) VPCe (G/W型) Read Only Role S3 CloudFormation

    S3 Replication Access point Access point VPC access point S3アクセスポイントポリシーのざっくり説明 ※詳細は割愛 アクセスポイントポリシー: 各アクセスポイントで設定。特定経路以外をDeny。
  45. 脱線しましたが、S3バケットもバケットポリシーで 特定経路以外をDenyすれば、大丈夫そう VPC Corporate data center bucket-a Direct Connect VPCe

    (I/F型) VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA ① ② ③ ① 閉域用端末 ② EC2 ③ S3バケット
  46. ポリシー関連をまとめてみる VPC Corporate data center bucket-a Direct Connect VPCe (I/F型)

    VPCe (G/W型) EC2 閉域用 bucket-b S3 ・ ・ ・ 運用者 アカウントA Ⅰ. IAMポリシー: s3:ResourceAccountで 社外バケットへのアクセスをDeny ※S3に触れる全IAMロールに適用推奨 Ⅱ.VPCeポリシー: aws:PrincipalAccount で クレデンシャルの持込をDeny ※ResourceAccountの併用もあり Ⅲ.バケットポリシー: aws:sourceVpceなどで 特定経路以外をDeny ※アクセスポイント利用がおすすめ Ⅰ Ⅰ Ⅲ Ⅱ