1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS S3単体で「任意のIPからのみアクセスできる」静的サイトを公開する手順

Posted at

はじめに

本記事では、S3だけで静的サイトをホスティングし、任意のIPからのみアクセス可能にする方法を紹介します。
※コストを最小にする目的で、バケットポリシーでアクセス制御を行っていますが、高セキュリティ運用する場合は CloudFront+WAF を推奨します。

公式ドキュメント
https://docs.aws.amazon.com/AmazonS3/latest/userguide/HostingWebsiteOnS3Setup.html

手順(詳細)

1. S3バケットを作る

  • S3 → 「バケットを作成」 → バケット名(例 example.com:ドメインをバケット名にする場合) → リージョン選択 → 作成
    スクリーンショット 2025-10-08 011407.png

スクリーンショット 2025-10-08 011918.png

image.png

スクリーンショット 2025-10-08 012111.png

2. バケットポリシーでIP制限を設定

スクリーンショット 2025-10-08 012403.png

スクリーンショット 2025-10-08 012854.png

例:任意のIP からのみ s3:GetObject を許可

推奨パターン(安全):明示的な Deny を使って、許可IP以外を拒否する(NotIpAddress + Deny)。Deny は Allow を打ち消すため、誤った Allow による漏れを防ぎます(AWSのポリシー評価は explicit Deny が最優先)。

↓そのままコピペして example.com(バケット名) と SourceIpの0.0.0.0 を書き換えてご自身の環境に合わせて書き換えてください

policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowGetFromMyIP",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example.com/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "0.0.0.0/32"
        }
      }
    },
    {
      "Sid": "DenyGetFromOtherIPs",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example.com/*",
      "Condition": {
        "NotIpAddress": {
          "aws:SourceIp": [
            "0.0.0.0/32"
          ]
        }
      }
    }
  ]
}

上記は「許可(特定IP)+それ以外を明示的に拒否」のパターンです。Deny が優先されるため、他の Allow が誤ってあっても遮断できます。バケットポリシーの例(一般)や IP 制限の実装例は公式やナレッジセンター参照を推奨します。

公式ドキュメント
https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html

補足:
複数のIPアドレスからアクセスを許可することも可能です。
その場合はSourceIpの配列の要素に列挙してください。

"aws:SourceIp": [
    "0.0.0.0/32",
    "1.1.1.1/32"
]

3. Block Public Access の設定

バケットポリシーを有効にして IP 制限をかけるため、少なくとも BlockPublicPolicy を false にする必要があります。
※アカウント単位で BlockPublicPolicy が有効だとバケット側で変えられないので注意。

スクリーンショット 2025-10-08 013015.png

スクリーンショット 2025-10-08 013055.png

スクリーンショット 2025-10-08 013147.png

4. 静的ウェブサイトホスティングを有効化

  • S3 → バケット → Properties → 「静的ウェブサイトホスティング」 → 有効にする
  • インデックスドキュメント: index.html
  • エラードキュメント: index.html (SPAを想定 React のルーティングはすべて index.html に任せるので、404でもindexを返す設定が必須です。)

プロパティタブの最下部にあります
スクリーンショット 2025-10-08 013643.png

スクリーンショット 2025-10-08 022309.png

スクリーンショット 2025-10-08 022411.png

※S3の「ウェブサイトエンドポイント」は http://example.com.s3-website-.amazonaws.com の形式です(HTTPSはサポートされません。HTTPSが必要なら CloudFront 経由を検討してください)。

5. ファイルをアップロード

ご自身で公開したい静的ファイルを用意してください。

今回は試験的にReactのデフォルトappをアップロードします。

Reactのデフォルトアプリケーションを作成

npx create-react-app my-app

ビルドして静的ファイルを作成

cd my-app
npm run build

build/配下のファイルをS3バケットにアップロード

スクリーンショット 2025-10-08 020043.png

全選択してドラッグアンドドロップ
スクリーンショット 2025-10-08 015817.png

スクリーンショット 2025-10-08 020240.png

6. 動作確認

エンドポイントはプロパティタブ最下部( 静的ウェブサイトホスティング )から確認できます。
スクリーンショット 2025-10-08 020433.png

  • 許可したIPからブラウザで http://example.com.s3-website-.amazonaws.com にアクセス → ページが表示される(200)
    スクリーンショット 2025-10-08 021104.png

  • 別のIPからアクセス → 403 Forbidden(または 404/403 のいずれか。ポリシー次第)
    https___qiita-image-store.s3.ap-northeast-1.amazonaws.com_0_4185481_851cccd1-5ca3-47b3-b3d6-bbb65b2a39cf.png

S3単体での静的サイトホスティングのメリット・デメリット

項目 メリット デメリット
コスト 非常に安価。アクセスが少ない場合、月数十円〜数百円で運用可能 大量アクセスやグローバル配信には非効率。CloudFrontに比べるとパフォーマンスは劣る
設定の簡単さ AWSコンソールだけで簡単に公開可能。CloudFront不要 HTTPS対応不可(HTTPのみ)。独自ドメインでHTTPSを使うにはCloudFront必須
メンテナンス性 静的ファイルをアップロードするだけでOK SPAのルーティング対応やカスタムエラーページは設定がやや複雑
アクセス制御 バケットポリシーでIP制限やIAMユーザー単位の制御が可能 IP制限のみの柔軟な制御。WAFのような高度な制御はできない
配信性能 AWS内部ネットワークの高速S3エンドポイントを利用可能 世界中への低レイテンシ配信は難しい。CloudFrontの方が高速
可用性・耐障害性 AWS S3自体の耐障害性・冗長性あり 高トラフィックやグローバルアクセス時のキャッシュ最適化は不可
SEO・SNSシェア対応 基本的なHTML公開は可能 HTTPS非対応だとSEOや一部サービスのリンク表示で不利

まとめと補足

なぜバケットポリシーで /32 を使うのか

S3のバケットポリシーでアクセス制御を行う際、IPアドレスの範囲は CIDR(Classless Inter-Domain Routing)表記 で指定します。

/32 は 32ビットすべてがネットワーク部分 という意味で、単一のIPアドレスだけを許可 する指定です。

例えば 0.0.0.0/32 とすると、許可されるのは 0.0.0.0 だけで、それ以外のIPは拒否されます。

単一IPだけを厳格に許可したい場合に /32 が便利です。

複数IPを許可したい場合は、配列で /32 を列挙したり、サブネット(例 /24)でまとめて指定することも可能です。

※ /32 はポート番号ではなく、IPアドレス範囲の指定です。

静的ウェブサイトとは

静的ウェブサイトとは、サーバー側で動的に処理をせず、あらかじめ用意されたHTMLやCSS、JavaScriptファイルをそのまま配信するウェブサイト のことです。

特徴:

  • ファイルの中身は固定で、アクセスするたびに変化しません。

  • S3のようなストレージにファイルを置くだけで公開可能。

  • SPA(Single Page Application)やReactアプリのように、クライアント側で動的処理を行う設計も可能。

  • サーバーサイド処理(PHP, Node.jsなど)は不要なため、運用コストや設定が非常にシンプルです。

静的ウェブサイトは、小規模な社内ツールや検証サイト、低コストでの公開に最適です。HTTPSやアクセス制御など高度な機能が必要な場合は、CloudFrontなどと組み合わせて運用するのが一般的です。

最後に

今回は、ReactのデフォルトアプリをS3単体でホスティングし、特定IPからのみアクセス可能にする手順を紹介しました。

S3単体でのホスティングは非常に簡単でコストも低く、少人数向けの検証サイトや社内ツールに最適です。一方で、HTTPS非対応、柔軟なアクセス制御ができない、グローバル配信には不向きなどの制約があります。

公開範囲を広げたり、HTTPS対応が必要な場合は、CloudFront併用やWAF、署名付きURLなどの拡張も検討してください。

小規模なサイトであればS3単体でも十分実用可能と考えておりますので、今回の手順を参考にぜひ試してみてください。

勉強中の身なので、この手法についてコスト面やリスクについて皆さんの見解をコメントしていただけるとありがたいです。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?