[Oracle Cloud] WAF を使って、iPhone と Android を識別してアクセス制御してみた

# はじめに

Oracle Cloud Infrastructure(以下OCI)では、Web Application Firewall が提供されています。Webアプリケーションの手前にWAFを置くことで、既存のアプリケーションを改修することなく、セキュリティを高められます。WAF の概要は、[こちら](https://blogs.oracle.com/sec/introducing-the-oci-waf-jp) で紹介されているので、興味があればご参照ください。

今回は、WAF の動作確認の一環で、User-Agent を使用したアクセスコントロールを確認してみます。iPhone や Android の端末からアクセスすると、User-Agent の中に「Android」や「iPhone」 という文字列が入ります。これらの文字列が入っているときには、アクセスを許可する設定を確認していきます。

注意点 : User-Agent はアクセス元で簡単に変更が出来るので、これだけではセキュリティ対策としては不十分です。他の仕組みと一緒に使うのが良いでしょう。また、Chrome では [User-Agent が凍結される予定](https://qiita.com/paddy-oti/items/fae9ecca9facc9797035)もあるようなので、この仕組みが将来的に使えなくなる懸念もあります。

こういった注意点を理解した上で、実際に使ってみようということで試してみたところ、若干のハマりポイントがありました。自分の環境で動作した手順を紹介します。



# Webアプリケーションの作成

OCI で CentOS の仮想マシンを適当に作成して、Nginx をインストールしていきます。Nginx のインストール作業は、詳細は省きますが以下のコマンドで構成しました

```
# Stop Firewalld
sudo systemctl stop firewalld
sudo systemctl disable firewalld

# Nginx Install
sudo yum install -y nginx

# Nginx Configure
sudo su -
cat <<'EOF' > /usr/share/nginx/html/index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {        width: 35em;        margin: 0 auto;        font-family: Tahoma, Verdana, Arial, sans-serif;    }</style>
</head>
<body>
<h1>I am web01</h1>
</body>
</html>
EOF

# Nginx Start
systemctl restart nginx
systemctl enable nginx
```



上記コマンドでインストールすると、次の画面が表示されます。

![1589270969745.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/9bea2ee7-d26d-bfb7-d723-6ea9464c0899.png)



# WAF設定

Webアプリケーションが出来たので、WAF Policy を作成していきます。Create を押します。

![1589253229865.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/7ec4bc85-6a8a-ddc9-c0b9-4d38680888ab.png)



各種パラメータを入力します。

- Policy Name : 任意の名前
- Primary Domain : ユーザーにWAFを経由してアクセスさせたいURLを入力
- Origin Name : 任意の名前
- URI : Webアプリケーションの稼働元を指定

特に注意が必要なのは、`Primary Domain` でした。ここで入れるパラメータは、最終的にユーザーがアクセスするドメインです。アクセスするドメインと異なると、503エラーが表示され続けるので注意して設定しましょう。

![1589265607900.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/0c848480-197a-349c-0085-e38df869b000.png)



Creating となります。自分の環境では 1分ほど待つと ACTIVE になりました。

![1589265638740.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/590862c7-75c5-1f62-b27e-1e6350148dee.png)



ACTIVE になると、WAF としての CNAME Target が表示されます。これが、WAF の Endpoint になります。
CNAME : `waf-sugioci-tokyo.o.waas.oci.oraclecloud.net`

![1589265761210.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/39254183-8210-2ade-bc84-51ce82bcd1d6.png)



ちなみに、ここでもハマりポイントがあります。WAF の CNAME Target に直接アクセスしても、503 エラーが表示されます。実際のオリジンサーバーは表示されないのでご注意ください。(もしかすると、自分の設定が悪い可能性もあるかも)

http://waf-sugioci-tokyo.o.waas.oci.oraclecloud.net

![1589271387852.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/63e572bc-4846-18d9-e6fb-2fcf1e5d3fcf.png)



# DNS設定

実際にWAFにアクセスするために、WAF の CNAME Target を、DNSサーバーでCNAMEレコードとして登録します。自分の環境の場合は、`sugioci.tokyo`というドメインを OCI DNS で管理しているので、次のが用のようにCNAME レコードを作成しています。環境に合わせて適宜変更してください。

![1589271788776.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/37bb915d-db70-00a7-e345-b5872e337b2c.png)



登録した CNAME でアクセスすると、WAF を経由して Webサーバーが表示されます。
http://waf.sugioci.tokyo/

![1589271516326.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/241880be-1ee1-ce76-fc94-7d335383958a.png)



ここでもハマりポイントがあって、WAF Policy を Create した後に ACTIVE ステータスになりますが、ACTIVE でも実際には表示されず、503エラーとなる現象に出会いました。自分の環境では、時間が解決してくれて、10分ほど待機することでアクセスできるようになりました。



# User-Agent

ここまでてWAFが利用出来るようになりました。WAFの動作確認のため、User-Agent を使用したアクセスコントロールの設定をします。User-Agent の中に、「iPhone」 と 「Android」 の文字列が入っている時はアクセスを許可します。入っていない場合は、400 の Bad Request エラーにします。これによって、iPhone と Android の機種の場合はアクセスがやりやすくなる設定となります。

注意点です。**繰り返し書きますが、User-Agent はアクセス元のクライアント側で簡単に偽装できます。User-Agent 以外の仕組みも使って、セキュリティを担保する必要があります。例えば、ID/Pass で認証する機構など。**

それでは、WAF設定のため、詳細画面を開きます。

![1589415867156.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/4e71d60e-265f-e525-1dad-03a203cee45e.png)



Add Access Rule を押します

![1589416035423.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/92c53a40-719f-1856-e793-57dd9838e83a.png)



次の3種類のパラメータを入れます。iPhoneの許可

![1589416148930.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/6c122cb1-b016-b55a-64f1-2236930ba88d.png)



Android の許可

![1589416212571.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/a2a67eb8-7e18-7d8c-63eb-e914103312b4.png)



Android と iPhone という文字列にマッチしなかったときは、アクセスをブロックする設定です。「マッチしなかったとき」というConfition の指定が無いので、User-Agent の文字列が `test` じゃないときに全てブロックする設定にしています。

![1589416460580.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/d73bc640-316b-e338-12ee-f8e2dc57f513.png)



Publish All を押すと、実際に WAF のポリシーが変更されます。自分の環境では、変更の反映に45分ほどの時間が掛かりました。環境やタイミングに依存すると思います。気長に待ちましょう。

![1589416493960.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/4f40c9e6-bf78-d6b4-b614-5153a8063396.png)



# 動作確認

PC でアクセスすると、400 Bad Request が返ってきます。

![1589416635224.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/1281c06f-948c-e1c1-8b1f-4af66bac9b24.png)



手元の Android や iPhone でアクセスすると、「I am Web01」と表示されます。

![1589416857100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/a91a3794-89bd-042a-4df6-7a6ebca5afe2.png)


改めて書きますが、**User-Agent だけでセキュリティを担保するのは非常に危険**なので、他の仕組みと併用する考え方が重要です。User-Agent 以外の制御方法も使っていくのがよいでしょう