AWSでBasic認証をかけるには？AWS WAF編　～AWS100本ノック～ 6/100

# はじめに

開発環境では特定の人（例えば自社の人）だけが見れるようにアクセス制限をすることがあると思います。
アクセス制限の選択肢としてBasic認証やIP制限が考えられますが、Basic認証をしたい場合、みなさんどうしていますか？

- AWS WAFでやる
- CloudFrontFunctionsでやる
- Lambda@Edgeでやる
- Webサーバ(Apacheなど)の設定でやる
などあるかと思います。

その中で今回は`AWS WAF`を使ってBasic認証を行う方法を説明します。

# やってみた

では、実際にやってみましょう。
今回は、ALB(Application Load Balancer)にBasic認証を設定します。

## Web ACLの作成

### 基本情報と紐づけるリソースの設定
左メニューの`Web ACLs`から`Create web ACL`をクリックします。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/2a8df570-2b76-5999-40a5-ea2203bc6389.png)

- `Resource type`として`Regional resouces`を選択します
- `Region`は`Tokyo`を選択します
- `Name`は任意のACL名にします。今回は`basic-authentication`とでもしておきます

:::note info
CloudFrontにBasci認証をかけたい場合は、`Resource type`として`CloudFront distributions`を選択してください！
:::

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/1ea13311-bd4f-84e1-adbd-c09e62e4a13e.png)

- `Resource type`として`Application Load Balancer`を選択します
- すると既存のALBがリスト表示されるので、Basic認証をかけたいALBにチェックを付けます

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/60461027-31f4-516d-b8ec-3f4dd6f510b4.png)

:::note info
他にもAPI GatewayなどにBasic認証をかけることが出来ます
:::

### ルールの作成
次にルールを作成します。
今回は、設定した認証情報以外は、`アクセスを拒否`するようなルールを作成します

- `Add rules`から`Add my own rules and rule groups`を選択します
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/71eaebbb-ba1f-7273-0906-d56e42cb6cb3.png)

ルールの基本情報を入力します
- `Rule builder`を選択します
- `Name`は任意のルール名にします。今回は`basic-authentication`とでもしておきます 
- `Rule`から`Regular Rule`を選択します
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/a9a675b8-9108-b8de-d4fc-9d2956780199.png)

ルールの詳細を入力します
- リクエストが一致しない場合に拒否したいので、`If a request`で`doesnt match the statement(NOT)`を選択します
- `Insepect`で`Single header`を選択します
- Basic認証に利用するヘッダーとして、`Header field name`に`authorization`を設定します
- `Match type`に`Exactly matches string`を選択します
- `String to match`に設定するBasic認証の情報を入力します
- `Text transformation`に`None`を選択します

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/e97d4979-e050-c9c8-aa74-d3172032a18d.png)

:::note info
例えば、ユーザ名がhoge、パスワードがhugaのBasic認証をかけたい場合は、以下のコマンドで出力されたBase64エンコード文字列を設定します
`echo -n 'hoge:huga' | base64`
:::

次に、ルールの評価結果どうするかを設定します
- 認証情報が誤っている場合はリクエストをブロックしたいので、`Action`に`Block`を設定します
- `Custom Response`を`Enable`にし、`Response Code`を`401`にします
- `Key`に`WWW-Authenticate`、`Value`に`Basic realm="Basic"`を入力し、エラー時のレスポンスヘッダーを設定します

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/bc4bf65a-9001-e801-631e-729ef2fee3a4.png)


- `Default action`は`Allow`を選択します
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/378d2b8e-fefe-54ab-9076-91468a1d8f5f.png)

### 確認と作成

後はそのままで、`Create web ACL`をクリックすると、Web ACLが作成されます :smile: 
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/6ddb4ef0-fd0e-d32e-fa67-aedf74430e28.png)

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/08f8f417-05e8-4924-4a06-3f155e639091.png)

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/2c307559-7577-68ea-d7c6-118829dc5fb1.png)


# アクセスしてみる

Basic認証がちゃんとかかったかALBのURLにアクセスしてみましょう。
ちゃんとBasic認証のダイアログが出ましたね :smile: 
間違った情報を入力すると、カスタムレスポンスに設定した`ステータスコード`と`レスポンスヘッダー`が返ってくることも確認出来ました
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/87924/38fd2a21-db60-d077-7af5-dc1754621734.png)


# おまけ(AWSを使わないでBasic認証を場合)

例えば、LAMP環境でBasic認証をしたいとなった場合、Apacheで設定することになると思います。

## Apacheの設定

以下簡単にWordPress環境のApacheでの設定例を記載します。
※Apacheのバージョンによって設定ファイルの場所などは変わりますので、ご注意ください :bow: 

```bash
# Basic認証のユーザを作成
sudo /opt/bitnami/apache/bin/htpasswd -cb /opt/bitnami/apache/test_user ${ユーザ名} ${パスワード}

# Apacheの設定ファイルに以下を追加
sudo vim /opt/bitnami/apache/conf/vhosts/htaccess/wordpress-htaccess.conf

<Directory "/opt/bitnami/wordpress">
    AuthType Basic
    AuthName "Authentication required"
    AuthUserFile "/opt/bitnami/apache/test_user"
    Require valid-user
</Directory>

#設定ファイルを読み込み
sudo apachectl graceful
```


# おわりに
今回はAWS WAFを使ってBasic認証を行う方法について紹介しました。
バックエンド側の修正をせず、AWSだけで行えるのは便利ですね :smile: