AWS WAF で 特定のバーチャルホストへのアクセスを IP 制限したい

AWS WAF (v2) を使って、バーチャルホストで構成した特定の Web サイトに対して IP 制限する方法を試してみました。
2020.02.28

みなさま Xin chao !

以前、以下のブログで Application Load Balancer (以下 ALB) のリスナールールを使って、バーチャルホストで構成した特定の Web サイトに対して IP 制限する方法を試してみました。

ALB で 特定のバーチャルホストへのアクセスを IP 制限したい

ALB と共に AWS WAF を使用する環境では、AWS WAF のカスタムルールでも IP 制限を行うことができそうなので、今回は AWS WAF (v2) で同じことを試してみました。

なお、IP 制限以外の部分については、上記 ALB でのブログと同じなので一部割愛しています。

やりたいこと

太字の部分以外は ALB の場合と同じです。

  • IIS に名前ベースのバーチャルホストで以下の Web サイトを構築
    • サービス提供用の Web サイト (https://www.masawo.classmethod.info/)
    • 管理機能提供用の Web サイト (https://masawo.classmethod.info/)
  • ドメインを取得済みで、Route 53 に登録済みのホストゾーンに必要なレコードを追加
  • ALB のリスナールールにより HTTPS でのアクセスを強制するため HTTP でのアクセスは HTTPS にリダイレクト
  • AWS WAF (v2) のカスタムルールにより 管理機能提供用 Web サイトへのアクセスを特定の IP アドレスからのみに制限
    • 特定の IP アドレス以外から管理機能提供用 Web サイトにアクセスした場合は ブロック

やってみた

前述の ALB でのブログに沿って、以下を行います (再度リンクを貼っておきますので、本ブログでは手順を割愛します)。 ALB に適用するセキュリティグループは、すべての HTTP, HTTPS アクセスを受け付けるようにします。

ALB で 特定のバーチャルホストへのアクセスを IP 制限したい - Developers.IO

  • IIS の Web サイトを設定
  • Route 53 にレコードを登録
  • ALB に SSL 証明書を登録

ALB リスナールールを設定

ALB では IP 制限を行わないので、デフォルトアクションのルールとして、ターゲットグループに転送するようにします。 ターゲットグループには Web サイトを構築した EC2 を登録しておきます。

また、HTTP でのアクセスは HTTPS にリダイレクトさせるよう、HTTP リスナーのルールを以下のようにします。

WAF カスタムルールを設定

AWS WAF (v2) のカスタムルールを 2 つ作成していきます。 今回はバーチャルホストが 2 つなので、ルールをシンプルにするために「特定の IP アドレスからのアクセスはすべて許可し、それ以外からの管理機能提供用 Web サイトへのアクセスをすべてブロックする」ようにカスタムルールを作成します。

事前に、管理機能提供用の Web サイトへのアクセスを許可する、特定の IP アドレスを登録するための IP sets を作成します。

Web ACL を新規作成します。 作成する Web ACL は ALB に関連づけます。

優先順位 1 のルールとして、特定の IP アドレス (=先ほど作成した IP sets) からのアクセスはすべて許可するルールを作成します。

優先順位 2 のルールとして、管理機能提供用 Web サイトへのアクセスをすべてブロックするルールを作成します。 管理機能提供用 Web サイトへのアクセスかどうかの判断は、host ヘッダーで行います。

デフォルトアクション (=それ以外のアクセス) は すべて許可します。 まとめると、以下のようになります。

接続確認

特定の IP アドレスからは、管理機能提供用の Web サイトである https://masawo.classmethod.info/ にアクセスできます。

PS C:\> $html=(Invoke-WebRequest -URI "https://masawo.classmethod.info/")
PS C:\> $html.RawContent
HTTP/1.1 200 OK
Connection: keep-alive
Accept-Ranges: bytes
Content-Length: 230
Content-Type: text/html
Date: Xxx, dd Mmm yyyy hh:nn:ss GMT
ETag: "942c14284cbd51:0"
Last-Modified: Xxx, dd Mmm yyyy hh:nn:ss GMT
Server: Microsoft-IIS/10.0

<!doctype html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Admin Web Site</title>
</head>
<body>
You accessed https://masawo.classmethod.info/
</body>
</html>

特定の IP アドレス以外から、管理機能提供用の Web サイトである https://masawo.classmethod.info/ にアクセスすると、「403 Forbidden」エラーで期待通りアクセスできませんでした。

PS C:\> $html=(Invoke-WebRequest -URI "https://masawo.classmethod.info/")
Invoke-WebRequest : 403 Forbidden
発生場所 行:1 文字:8
+ $html=(Invoke-WebRequest -URI "https://masawo.classmethod.info/")
+        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、WebExce
 ption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

最後に、HTTP でアクセスした場合に、HTTPS にリダイレクトされることも確認しておきます。 これは WAF のカスタムルールではなく、ALB のリスナールールによって行われます。

PS C:\> $html=(Invoke-WebRequest -URI "http://www.masawo.classmethod.info/" -MaximumRedirection 0)
Invoke-WebRequest : リダイレクトの最大数を超えています。許容されるリダイレクトの数を増やすには、-MaximumRedirection パラメーターの値を大きくしてください。
発生場所 行:1 文字:8
+ $html=(Invoke-WebRequest -URI "http://www.masawo.classmethod.info/" - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest]、InvalidOperationException
+ FullyQualifiedErrorId : MaximumRedirectExceeded,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
PS C:\> $html.RawContent
HTTP/1.1 301 Moved Permanently
Connection: keep-alive
Content-Length: 150
Content-Type: text/html
Date: Xxx, dd Mmm yyyy hh:nn:ss GMT
Location: https://www.masawo.classmethod.info:443/
Server: awselb/2.0

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
</body>
</html>

まとめ

AWS WAF (v2) のルールでも、特定のバーチャルホスト宛てのアクセスに対してのみ IP 制限を掛けることができました。

では、今回のように WAF で行うのと、以前ご紹介した ALB で行うのとどちらが良いのか? を少し考えてみたいと思います。

AWS WAF (v2) で行う場合、特定の IP アドレス以外からの管理機能提供用 Web サイトへのアクセスログを、WAF で使用している他のルールのログと一緒に閲覧・管理できますが、アクセスを遮断するのみでリダイレクト等はできません。 また、もともとの構成が WAF を使用しない構成の場合、IP 制限のためだけに WAF を導入するのは、管理コスト・料金コスト的にも避けたい気がします。

ALB で行う場合、特定の IP アドレス以外からの管理機能提供用 Web サイトへのアクセスを、(やさしく?) サービス提供用の Web サイトにリダイレクトするといったことができますが、もともと WAF も使用する構成では、管理機能提供用 Web サイトへのアクセスがうまく行かないなど問題が発生した場合には、WAF のログと ALB ログの両方を調査する必要が出てきます。

それ以外に、WAF と ALB を組み合わせて、管理機能提供用 Web サイトへのアクセスを WAF 側ではログ取得 (=カウント) のみ、ALB 側ではサービス提供用 Web サイトにリダイレクト、という構成も考えられますが、管理機能提供用 Web サイトへのアクセスを許可する IP アドレスの管理を WAF と ALB の両方で行う必要があります。

ALB のみの構成では ALB で、WAF も使用する構成では、特定の IP アドレス以外からのアクセスをどう処理するかで決める、というのが一つの目安になるのではないかと思います。