S3バケットへのアクセスを特定のIPとVPCに制限する

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

はじめに

オンプレミスにあるデータをAWS上で分析する場合、いったんオンプレからS3にデータをアップロードし、そのデータをAWS上のEC2等で参照/分析するのはよくあるパターンです。
s3_access_from_ip_and_vpc

その際、オンプレミスのサーバにはS3の操作権限をもったIAMユーザのアクセスキーを設置することになりますが、万が一アクセスキーが漏えいすると第三者に重要な情報を盗まれたり改変されたりする恐れがあります。

そのような事態を避けるために、S3バケットには必要なリソース以外からのアクセスを遮断するような制限をかけることをお勧めします。
具体的には下記からのアクセス以外は遮断した方が安全です。

  • オンプレミスのサーバのIPアドレス
  • 分析環境が構築されているAWS VPC
  • S3バケットの管理を行う拠点(AWSマネジメントコンソールを利用する場所)のIPアドレス

S3バケットへのアクセス制御の方法はいくつかありますが、今回はバケットポリシーを利用して外部からのアクセスを制限します。
各アクセス制御の違いについては次の記事で詳しく検証されているので、よろしければこちらもご覧ください。
S3のアクセスコントロールが多すぎて訳が解らないので整理してみる

S3バケットへのアクセス制限

では、実際に設定していきます。
まず、S3へのVPCエンドポイントを作成します。VPC内からのアクセスであることをS3バケットが判断できるようにするためです。
この設定がない場合、S3バケットはVPC内のリソースからのアクセスと外部のパブリックIPからのアクセスを区別できません。
こちらを参考に作成してください。
【新機能】S3がVPCのプライベートサブネットからアクセス可能になりました!

S3へのVPCエンドポイントを作成したら、S3のバケットポリシーを設定します。
S3のバケット一覧から対象のバケットを選択し、Properties内のPermissionsを選択します。 s3-properties

ポップアップが開くので次のようなポリシーを指定します。
s3-policy-edit

{
  "Version": "2012-10-17",
  "Id": "PolicyDemo",
  "Statement": [
    {
      "Sid": "Allow-from-specific-IP-and-VPC-only",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::<<S3バケット名>>",
        "arn:aws:s3:::<<S3バケット名>>/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpc": "<<分析環境のVPC ID>>"
        },
        "NotIpAddress": {
           "aws:SourceIp": [
      	     "<<オンプレミスサーバのIPアドレス>>",
             "<<S3バケット管理拠点のIPアドレス>>"
           ]
        }
      }
    }
  ]
}

Conditionブロック内に条件(StringNotEqualsやNotIpAddress)が複数ある場合、それらはAND結合されます。
そして、条件キー(aws:sourceVpcやaws:SourceIp)の値が複数ある場合、それらはOR結合されます。
したがって、上のバケットポリシーは
- 分析環境のVPC以外
かつ
- オンプレミスサーバのIPアドレスまたはバケット管理拠点のIPアドレス以外
のアクセス元から該当のS3バケットにアクセスがあった場合、それは拒否される
というポリシーになります。

明示的な拒否が設定されている場合、たとえほかのアクセス制限方法(例えばIAM)でアクセスが許可されていてもアクセスは拒否されます。
そのため、万が一IAMユーザのアカウントキーが漏えいしたとしても、あらかじめ設定されたアクセス元以外からのアクセスは拒否されるので、情報が盗まれたり改ざんされたりする可能性を抑えることができます。

ただし、AWSのrootアカウントは例外です。
rootアカウントでログインしたユーザやrootアカウントのAPIキーを利用すると、バケットポリシーの制限に関係なくS3バケットにアクセスできます。

rootアカウントによるアクセスについて誤りがありました。 バケットポリシーでDenyされた場合は、rootアカウントでもアクセスできなくなります。 ただし、バケットポリシー設定画面でポリシーの変更ができるため、rootアカウントが漏洩した場合は制限を解除された上で情報を盗まれる可能性があります。 ご指摘くださった方、ありがとうございました!

セキュリティ事故を避けるためにrootアカウントはMFAの設定をしたうえでAPIキーを無効化し、普段はIAMユーザを利用するようにしてください。

まとめ

S3バケットへのアクセスを特定のIPアドレスとVPCだけに制限する方法を紹介いたしました。
バケットポリシーを利用すると今回紹介した方法以外でもきめ細やかなアクセス制御が可能です。
アクセス可能な範囲をできるだけ狭め、セキュアな環境を作るようにしましょう。

参考サイト

  • Manabu Sakai

    文中で紹介されているバケットポリシーだと明示的な Deny しか書かれていないのでアクセスできないように思います(実際に試してもアクセスできませんでした)。
    明示的な Allow が抜けているように見えるのですがいかがでしょうか?