AWS WAFV2でIPアドレス制限してみた
ウェブサイトに対して、IPアドレスでアクセス制限をかけたいことがあります。
今回は
- 開発環境には自社ネットワークからしかアクセスさせない
- 本番環境の管理系URLには自社ネットワークからしかアクセスさせない
という要件を AWS WAFv2で実現する方法をご紹介します。
従来のAWS WAF(AWS WAF Classic)を利用したIPアドレス制限方法は次の過去記事を参照ください。
構成
AWS WAFV2 は
- Amazon API Gateway
- Amazon CloudFront
- Application Load Balancer(ALB)
と連携して利用できます。
検証では、下図のように、ALBと連携させました。
前提として、ALB 以下の構築は完了しているものとします。
AWS WAFv2 への切り替え
AWS WAF Classic のコンソールにアクセスしていると、「Switch to new AWS WAF」というリンクが表示されます。
開発環境には自社ネットワークからしかアクセスさせない
開発環境へのアクセス制限は、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 で実現する場合、
- 「URIパス」条件と「IPアドレス」条件を ANDで満たす時は Allow
- 「URIパス」条件だけを満たす時は Block
- デフォルトは Allow
というように文字通りにルールを定義することも可能ですが
- 「IPアドレス」条件を満たす時は Allow
- 「URIパス」条件を満たす時は Block
- デフォルトは 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
ここで以下のルールを定義します。
- 「IPアドレス」条件を満たす時は Allow
- 「URIパス」条件を満たす時は Block
- デフォルトは 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アドレスをテキストエリアから一括で登録できるようになったののも、地味に嬉しいです。
以上、どなたかのお役に立てれば光栄です。