Static Website Hosting を特定の VPC にだけ公開する

Posted on

Amazon S3 の Static Website Hosting は静的コンテンツを HTTP で公開するのにとても便利です。

この機能を使って VPC 内から HTTP でアクセスできるプライベートリポジトリを作りたかったのですが、特定の VPC にだけ公開する方法を知らなかったので調べてみました。

VPC エンドポイントを設定する

VPC エンドポイントを作らないと、インターネット経由のアクセスになってしまうので VPC 単位で制限できません。まずは VPC エンドポイントを設定して、プライベートネットワークから S3 にアクセスできるようにします。

バケットポリシーを設定する

Static Website Hosting を有効にしたあと、S3 のバケットポリシーを設定します。 aws:SourceVpcaws:SourceVpce という条件キーがあるのでこれが使えそうです。

上記ドキュメントに例が載っているのですが、Static Website Hosting の場合はこのポリシーではアクセスできません。自分はここでハマりました。

Static Website Hosting を特定の VPC に公開するバケットポリシーはこんな感じです。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example.com/*",
      "Condition": {
        "StringEquals": {
          "aws:sourceVpc": "vpc-xxxxxxxx"
        }
      }
    }
  ]
}

肝になるのは Condition のところだけで、他は Static Website Hosting の通常のポリシーです。 aws:SourceVpce を使っても同じように制限できます。

ちなみに、上記のバケットポリシーは明示的な Deny を設定していないので、他の VPC から AWS CLI などでアクセスすることは可能です。それも制限したいときは明示的な Deny を追加します(これがドキュメントに載っている例です)。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "*",
      "Resource": "arn:aws:s3:::example.com/*",
      "Condition": {
        "StringNotEquals": {
          "aws:sourceVpc": "vpc-xxxxxxxx"
        }
      }
    },
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example.com/*",
      "Condition": {
        "StringEquals": {
          "aws:sourceVpc": "vpc-xxxxxxxx"
        }
      }
    }
  ]
}

バケットポリシーは、明示的な Deny > 明示的な Allow > 暗黙的な Deny の順で評価されるので、最初のステートメントで StringNotEquals を使って許可する VPC 以外を Deny しています。

まとめ

Static Website Hosting を特定の VPC に公開するには、

  • VPC エンドポイントを設定する
  • バケットポリシーに Condition を追加する

の 2 つの手順が必要です。自分は VPC エンドポイントを設定していない VPC で検証を始めてしまったので、ゴールにたどり着くまで時間がかかってしまいました。