AWS WAF で国外からのアクセスを禁止しつつ、例外許可IPアドレスを設定してみた

# はじめに

用意する Web アプリケーションに日本のみアクセスを許可したいときがあります。こういったときに、AWS WAF を使うと、どの国からアクセスを許可するのかコントロール可能です。国を指定したアクセス許可に加えて、特定の IP アドレスからのアクセスは海外からのアクセスも許可したいときがあります。また、国外からのアクセスでも誤って海外からのアクセスと判別される可能性はゼロではないと思うので、その例外の設定方法も視野に入っています。



今回の記事では、次の設定方法を確認する内容となります

- 日本以外からのアクセスを禁止
- 特定の IP アドレスはアクセス許可



それでは設定方法を確認していきましょう。



# 利用するCloudFront

今回は、CloudFront で配信している単純な Web サイトを用意しました。CloudFront にアクセスすると、次のように html が表示されるだけのシンプルなサイトです。

![image-20220320145039926.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c6f51ab4-3e55-d949-20fa-4a18e72f59fe.png)



# WAF WebACL の作成

上記の CloudFront に対して、WAF を設定していきます。AWS WAF の設定ページに移動して、Create web ACL を選択します。

![image-20220320145154624.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/3257c47b-c5e9-4de5-7793-de287cae7745.png)



- WebACL の名前を指定
- CloudFront と連携する指定

![image-20220320145307820.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/aa8e2918-4124-9015-1527-65281d685151.png)



連携する CloudFront を選択して、Nextをおします

![image-20220320145405094.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2fad49d4-e683-edbf-dcd2-1c16885d2f3d.png)



デフォルトのアクションを Block にしておきます。日本許可などのルールは後から設定することにします

![image-20220320145538292.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/522b36a1-1328-b639-8088-d0b57e67bfb9.png)



このまま Next を押します

![image-20220320145557207.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/0a846d20-8c38-ba98-10d9-f2da752ff4ce.png)



サンプリングを有効にして、Next を押します

![image-20220320145641981.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/32785cbc-fd3d-1109-2b0b-98c9c543c69c.png)



Create web ACL を押します

![image-20220320145658603.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/897aa4a3-9e0a-6bb8-5361-701659c264b3.png)



作成されました

![image-20220320145724152.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/68281cbb-f793-57b8-d04f-e54c1ec8f0d5.png)



なお、この時点で CloudFront て配信しているサイトはアクセスできなくなりました

![image-20220320145828953.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/b562a0a2-70d9-d613-6665-b5ef11065075.png)



# 日本国内のみ許可する設定を入れる

Web ACL のルール設定を進めていきます。Add my own rules and rule groups を選択します。

![image-20220320150232176.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/223ae49a-db04-ffff-5648-8a5ff6b01ae5.png)



- Rule builder を選択
- 名前を指定
- Type で Regular rule を指定

![image-20220320150656619.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2b405345-0802-33be-0043-29ec82012089.png)



日本国内からのアクセスの場合は、許可する設定をいれます。Web ACL のデフォルトのアクションが Block なので、日本以外からのアクセスはデフォルトアクションが選ばれて Block される設定となります。

![image-20220320150848789.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/c77aa0fd-b2c5-46b5-b7c8-59aa5876a264.png)



Add rule を押します。

![image-20220320150913554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/02ff627c-7cb4-adda-ad95-d6caa07b4185.png)



Save を押します

![image-20220320150929634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/5f153824-d0bb-9006-4ae6-98f627adf000.png)



設定されました

![image-20220320151329889.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/d1d2fc33-b989-a9b1-babe-d8ee2426aceb.png)



# 動作確認1 : 海外からアクセスが出来ない

この設定を加えることで、日本からのアクセスが出来る用になっています。

![image-20220320151307764.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/986b2850-b5f8-8c50-539e-b66330c5e5d8.png)



なお、海外からのアクセスは、正常に Block されています

```
$ curl <my site>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Request blocked.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: BwDBqUYuqN_POjd-snmXnpbuWm0MXNnkPXUViR2RZ-6pHfqHV48LSg==
</PRE>
<ADDRESS>
</ADDRESS>
```



# 特定の IP アドレスの例外設定を行う

特定の IP アドレスからのアクセスを許可する例外設定を行っていきます。海外の特定の IP アドレスや、国内の誤検知されたユーザーを許可する使い方を想定しています。

例外的に許可したい IP アドレス群は、IP set という概念で定義していきます。IP set のメニューから、Create IP set を選択します。

![image-20220320152805088.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/4105f041-2122-84b7-957a-5b9e27a6ca40.png)



許可したい IP アドレスをセットします

- この IP アドレスは、とあるオレゴンの EC2 インスタンスの Public IP を指定しています

![image-20220320153332700.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/cac9d6ea-9bbb-66b8-fef2-8383995da7f0.png)



作成されました

![image-20220320153412814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/86602663-3a75-e963-3da7-22dee1b07b89.png)



Web ACL に、作成した IP set の許可をしていきます

![image-20220320152702491.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/66e1a289-606b-2d23-0e0e-ecb4bf33e5b7.png)



IP set を選択します

![image-20220320153515626.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/fe593ec7-be21-f173-b66e-0212ce0213f0.png)



- 名前を指定
- 作成した IP set を指定
- Action を Allow にする

![image-20220320153559293.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/a2d6e6df-82a6-93a3-74b9-44d1e1ae0666.png)



Save を押します

![image-20220320153616770.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/597f1627-31d8-48c4-9caf-db417f428dd4.png)



保存されました

![image-20220320153624874.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1002774/2d3768d1-d326-4581-6344-6013c4d33e88.png)



# 動作確認2 : 特定の IP アドレスは、海外からでもアクセス許可

IP set で許可された IP アドレスから、curl でアクセスしてみます。許可されているので正常にアクセスできました。

```
$ curl <My CloudFront>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
        <title>トップページ</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>

    <body>
        <h1>トップページだよ！</h1>
    </body>
</html>
```



なお、許可されていない 海外のIP アドレスは引き続き Block されています

```
$ curl <my site>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD><BODY>
<H1>403 ERROR</H1>
<H2>The request could not be satisfied.</H2>
<HR noshade size="1px">
Request blocked.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
<BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
<BR clear="all">
<HR noshade size="1px">
<PRE>
Generated by cloudfront (CloudFront)
Request ID: KwofoRhbgnrTAc4jVwe0HWNN0Ryg5OiyhPIk_ArLFxYZqVfMzz4BwA==
</PRE>
<ADDRESS>
</ADDRESS>
```