■概要

CloudFront – S3 の静的ウェブホスティングの構成で、CloudFront の前に AWS WAF を設定し特定のディレクトリの閲覧を特定のアクセスからのみ許可するようなルールを設定します。

■要件

・S3 のバケットの状態は以下のようなディレクトリ構成になっています。
murakami-test-iret (S3バケット)

├test01-directory
|           └test01.html
|           └test02-directory
|                  └test02.html
|
├test03-directory
           └test03.html
           └test04-directory
                  └test04.html
  • 制限をかけるパス
    • /test01-directory/test02-directory/*
    • /test03-directory/test04-directory/*
  • 許可するネットワーク
    • 特定の IP
    • 日本を接続元とするもの
  • 拒否するネットワーク
    • 上記以外のネットワーク
  • ただし、許可するネットワークは他のパスにもアクセスできること

つまり、制限対象のパスにのみ特定のアクセスを制限することになります。

特定の IP 日本からのアクセス その他のアクセス
制限対象パス
/test01-directory/test02-directory/*
/test03-directory/test04-directory/*
×
その他のパス

■設定してみる

今回は S3 + CloudFront の静的Webホスティングの構成をすでに組んである状態から AWS WAF を設定する手順になります。

① AWS WAFの IPset で指定の IP で設定する

※リージョンは Global を選択する

② Web ACLs の作成

名前は任意
リージョンは Global にし、ディストリビュージョンは指定のものを選択する。 

③ルールを作成する

先ほど作った WebACL の Rules タブから以下のルールを作成する

(ルール1)

・特定の IP を指定のディレクトリにアクセスを許可するルール(ディレクトリごとに作る)

Rule type Rule builder
Name 任意の名前
Type Regular rule
If a request matches all the statement(AND)

<Statement 1>

Inspect Originates from an IP address in
IP set ①で作成したIPset
IP address to use as the originating address Source IP address

<Statement 2>

Statement URI Path
Match type Starts with string
String to match /test01-directory/test02-directory/ #特定のディレクトリパス
Text transformation None
Statement URI Path

<Action>

Action Allow
その他項目 デフォルト

(ルール2)

・特定の国からのアクセスを特定のディレクトリに許可するルール(ディレクトリごとに作る)

Rule type Rule builder
Name 任意の名前
Type Regular rule
If a request matches all the statement(AND)

<Statement 1>

Inspect Originates from a country
Country codes Japan – JP
IP address to use as the originating address Source IP address

<Statement 2>

Statement URI Path
Match type Starts with string
String to match /test01-directory/test02-directory/ #特定のディレクトリパス
Text transformation None
Statement URI Path

<Action>

Action Allow
その他項目 デフォルト

 

(ルール3)

・そのほかのアクセスを特定のディレクトリでブロックするルール

Rule type Rule builder
Name 任意の名前
Type Regular rule
If a request matches at least one of the statement (OR)

<Statement 1>

Statement URI Path
Match type Starts with string
String to match /test01-directory/test02-directory/ #特定のディレクトリパス
Text transformation None
Statement URI Path

<Statement 2>

Statement URI Path
Match type Starts with string
String to match /test03-directory/test04-directory/ #特定のディレクトリパス
Text transformation None
Statement URI Path

<Action>

Action Allow
その他項目 デフォルト

ルール作成時の注意点として、 WebACL のルール作成時は「If a request」の項目でstatementの条件を決めます。
その際、AND 条件と OR 条件を組み合わせるような設定は一つのルール内では不可能です。

例)この IP のアクセスかつこのディレクトリもしくはこのディレクトリは許可

また、一つの statement に複数のディレクトリパスは指定できないため制限をかけるディレクトリ分ルールを作成する必要があります。
今回の場合だと「/test01-directory/test02-directory/* 」と「/test03-directory/test04-directory/*」へ制限をかけるため合計5つルールを作成します。

  • IP制限 + ディレクトリ指定のルール:2つ
  • 国からのアクセス制限 + ディレクトリ指定のルール:2つ
  • ブロックするルール:1つ

 

④ルールの優先順位を決める

ここが今回の肝となる部分になります。
ルールを作成した時に<ルール1><ルール2>でディレクトリに対するアクセスを許可するルールを作りました。
しかし、<ルール3>でディレクトリへの全てのアクセスをブロックするルールを作りました。
この3つのルールの優先順位次第で挙動が変わります。
<ルール3>を優先してしまうと、全てのアクセスがディレクトリにアクセスできない状況となります。
今回は<ルール1><ルール2>を優先することで特定のアクセスのみ特定のディレクトリへのアクセスを許可することができます。

 

■動作確認

①アクセスする IP が指定の IP だった場合 / 指定した国からのアクセスだった場合

想定の挙動:全てのディレクトリにアクセスできる

② 指定外 IP かつ指定外の国からのアクセスだった場合

想定の挙動:「/test01-directory/test02-directory/* 」と「/test03-directory/test04-directory/*」へのアクセスが不可

下記添付画像は海外からのアクセスを模擬したもので、URLによってページの挙動がわかります。