AWS WAFV2でIPアドレス制限してみた

ウェブサイトに対して、IPアドレスでアクセス制限をかけたいことがあります。

今回は

  • 開発環境には自社ネットワークからしかアクセスさせない
  • 本番環境の管理系URLには自社ネットワークからしかアクセスさせない

という要件を AWS WAFv2で実現する方法をご紹介します。

従来のAWS WAF(AWS WAF Classic)を利用したIPアドレス制限方法は次の過去記事を参照ください。

AWS WAFを使って接続できるIPアドレスを制限してみた

構成

AWS WAFV2 は

  • Amazon API Gateway
  • Amazon CloudFront
  • Application Load Balancer(ALB)

と連携して利用できます。

検証では、下図のように、ALBと連携させました。

前提として、ALB 以下の構築は完了しているものとします。

AWS WAFv2 への切り替え

AWS WAF Classic のコンソールにアクセスしていると、「Switch to new AWS WAF」というリンクが表示されます。

クリックして、WAFV2 コンソールに移動して下さい。

開発環境には自社ネットワークからしかアクセスさせない

開発環境へのアクセス制限は、IPアドレスだけで行うものとします。

ホワイトリストのIPアドレスを登録し、ホワイトリストの IP アドレスからアクセスされた場合は Allow、それ以外の場合は Block します。

IPのホワイトリスト登録

アクセス可能なIPアドレスをホワイトリスト化します。

サイドメニューの「IP sets」から IP set の作成画面に移動し、許可する IP アドレスを登録します。

Region

Region には、WAF ACL を利用するリージョンを指定します。

CloudFrontと連携する場合は「Global(CloudFront)」を選択し、CloudFront以外の場合は、対象リージョンを選択します。

IP addresses にはホワイトリスト対象の IPアドレスを CIDR で指定します。

複数の IP アドレスをまとめて指定できます。その場合は、1行に1アドレスだけ入力して下さい。

Web ACLの登録

サイドメニューの「Web ACLs」から Web ACL の作成画面に移動し、Web ACLを登録します。

Step 1 : Describe web ACL and associate it to AWS resources

web ACL の基本情報を設定します。

Resource type/Region

Resource type に AWS WAFと連携するサービスを指定します。

CloudFrontと連携する場合は「CloudFront distributions」を選択し、CloudFront以外の場合は「Regional resources (Application Load Balancer and API Gateway)」を選択し、同時に Region から対象リージョンを選択します。

Associated AWS resources

「Associated AWS resources」 から連携する AWS リソースを選択します。

Web ACL 作成後に連携させることもできます。

Step 2 : Add rules and rule groups

ACL に紐付けるルールを設定します。

IPアドレスはユーザーが管理するため、「Add rules」から「Add my own rules and rule groups」を選択します。

次に、Rule type の設定画面で ホワイトリスト化された IP アドレスからのアクセスを許可するため、以下の様に入力します。

項目
Rule type IP set
Rule name 任意
IP set 登録したIP setの名前
Action Allow

最後に、ホワイトリスト化されていないIPアドレスからのアクセスを遮断するため、 「Default web ACL action for requests that don't match any rules」の Default action を Block にします。

Step 3:Set rule priority

ルールが一つしか存在しないため、優先度(priority)の設定は不要です。

デフォルトのまま Next をクリックします。

Step 4:Configure metrics

AWS WAFのアクティヴィティをトラッキングしたい場合は、CloudWatch にメトリクスを送信します。

Step 5 : Review and create web ACL

設定内容に問題がなければ、「Create web ACL」ボタンからACLを作成します。

動作確認

Web ACL を動作確認します。

ホワイトリストされた IP アドレス からのアクセス

許可された IP アドレスからアクセスすると、オリジンサーバーがレスポンスを返します。

オリジンサーバーはレスポンスヘッダーの Server フィールドから確認できます。

$ curl -I http://DUMMY.eu-west-1.elb.amazonaws.com/
HTTP/1.1 200 OK
Date: Thu, 16 Jan 2020 17:51:42 GMT
Content-Type: text/html
Content-Length: 13
Connection: keep-alive
Server: SimpleHTTP/0.6 Python/3.7.4
Last-Modified: Thu, 16 Jan 2020 16:00:56 GMT
ホワイトリストされていない IP アドレス からのアクセス

許可されていない IP アドレスからアクセスすると、WAFと連携した ALB がステータスコード 403 のレスポンスを返します。

$ curl -I http://DUMMY.eu-west-1.elb.amazonaws.com/
HTTP/1.1 403 Forbidden
Server: awselb/2.0
Date: Thu, 16 Jan 2020 17:50:10 GMT
Content-Type: text/html
Content-Length: 134
Connection: keep-alive

$ curl -D - http://DUMMY.eu-west-1.elb.amazonaws.com/
HTTP/1.1 403 Forbidden
Server: awselb/2.0
Date: Thu, 16 Jan 2020 17:53:01 GMT
Content-Type: text/html
Content-Length: 134
Connection: keep-alive

<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
</body>
</html>

本番環境の管理系URLには自社ネットワークからしかアクセスさせない

本番環境へのアクセス制限は、URIパスとIPアドレスで行い、制限対象外のURIパスへのアクセス制限はないものとします。

パスごとにアクセス可能な IPアドレスが異なる事も考えられますが、今回は、管理すべき IP set は一つとします。

この要件を AWS WAFV2 で実現する場合、

  1. 「URIパス」条件と「IPアドレス」条件を ANDで満たす時は Allow
  2. 「URIパス」条件だけを満たす時は Block
  3. デフォルトは Allow

というように文字通りにルールを定義することも可能ですが

  1. 「IPアドレス」条件を満たす時は Allow
  2. 「URIパス」条件を満たす時は Block
  3. デフォルトは Allow

とすると、シンプルになります。

今回は後者でルール定義を行います。

IPのホワイトリスト登録

先程と同じです。

Web ACLの登録

差分を中心に解説します。

Step 2 と Step 3 が重要です。

Step 1 : Describe web ACL and associate it to AWS resources

先程と同じです。

Step 2 : Add rules and rule groups

ここで以下のルールを定義します。

  1. 「IPアドレス」条件を満たす時は Allow
  2. 「URIパス」条件を満たす時は Block
  3. デフォルトは Allow

まず、前回と同じように、ホワイトリストIPアドレスからのアクセスを Allow するルールを追加します。

次に、Rule type の設定画面で 次に、特定の URI パスへのアクセスを遮断するために以下の様に入力します。

項目
Rule type Rule builder
Rule name 任意
If a request matches at least one of trhe statements (OR)
Inspect URI path
Match type starts with string(例)
String to match /admin
Action Block

制限対象の URI パスが複数ある場合、 「Add another statement」からステートメントを OR 条件で追加してください。

  • Match type
  • String to match

は実際の URI パスに合わせて指定してください。

検証では

  • /admin
  • /manage

の先頭一致へのアクセスを制限しました。

これらのステートメントを満たしたアクセスを遮断するため、アクションを Block とします。

最後に、特定のURIパスだけアクセス制限されているため、デフォルトのアクションを Allow にします。

Step 3:Set rule priority

今回の ACL では2つのルールが存在します。

上にあるルールほど優先されます。

IP制限のルールがURIパス制限のルールよりも上に来るようにしてください。

Step 4:Configure metrics

先程と同じです。

Step 5 : Review and create web ACL

先程と同じです。

動作確認

Web ACL を動作確認します。

ホワイトリストされた IP アドレス からのアクセス

許可された IP アドレスからは任意の URI パスに対してアクセスできます。

$ curl -I http://DUMMY.eu-west-1.elb.amazonaws.com/
HTTP/1.1 200 OK
Date: Thu, 16 Jan 2020 18:03:21 GMT
Content-Type: text/html
Content-Length: 13
Connection: keep-alive
Server: SimpleHTTP/0.6 Python/3.7.4
Last-Modified: Thu, 16 Jan 2020 16:00:56 GMT

$ curl -I http://DUMMY.eu-west-1.elb.amazonaws.com/admin/
HTTP/1.1 200 OK
Date: Thu, 16 Jan 2020 18:03:33 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive
Server: SimpleHTTP/0.6 Python/3.7.4
Last-Modified: Thu, 16 Jan 2020 18:02:30 GMT
ホワイトリストされていない IP アドレス からのアクセス

サイトトップは制限されていないため、オリジンサーバーがレスポンスを返します。

$ curl -I http://DUMMY.eu-west-1.elb.amazonaws.com/
HTTP/1.1 200 OK
Date: Thu, 16 Jan 2020 18:02:38 GMT
Content-Type: text/html
Content-Length: 13
Connection: keep-alive
Server: SimpleHTTP/0.6 Python/3.7.4
Last-Modified: Thu, 16 Jan 2020 16:00:56 GMT

許可されていない IP アドレスから制限対象の URI パスにアクセスすると、WAFと連携した ALB がステータスコード 403 のレスポンスを返します。

sh-4.2$ curl -I http://DUMMY.eu-west-1.elb.amazonaws.com/admin/
HTTP/1.1 403 Forbidden
Server: awselb/2.0
Date: Thu, 16 Jan 2020 18:02:46 GMT
Content-Type: text/html
Content-Length: 134
Connection: keep-alive

これらのアクセスは、コンソールからも確認可能です。

最後に

今回は AWS WAFv2 を使って IP アクセス制限する方法を紹介しました。

AWF WAFV2 は UI がより直感的になっており(※個人差があります)、基本的な操作であれば、ドキュメントを見なくても画面ポチポチで操作できちゃうのが嬉しいですね。

また、複数のIPアドレスをテキストエリアから一括で登録できるようになったののも、地味に嬉しいです。

以上、どなたかのお役に立てれば光栄です。