AWS WAFでWordPressの管理画面を保護する

当サイトは2016年秋よりCloudFront経由での配信に切り替えておりますが、この度セキュリティ強化のためAWS WAFの設定を追加しましたので記録しておきます。

経緯・構成

経緯

当サイトはWordPressで構築されており、CloudFront経由で配信されております。
WordPress管理者画面へのログインについては各種プラグイン等による設定でセキュリティを強化しており、特に脆弱な状態という訳ではありませんでしたが、それでも昨秋頃から不正ログインを試みるアクセスを大量に受けることがあり、保護機能が働き管理画面へのログインが(管理者である私も)できない状態が時折発生するようになることがありました。

直ぐに問題という訳ではありませんでしたが、流石にこの状態を放置するわけにはいかないと判断し、AWS WAFにて自宅ネットワーク以外からの管理者画面へのログインを禁止する設定を追加することにしました。

構成

AWS WAFはAmazon CloudFront、もしくは各リージョンに設置されたALB(Application Load Balancer)やAmazon API Gatewayと連動し、WAF機能をつくるフレームワークを提供するサービスです。
巷のWAF製品は、その機能を有効にするだけで外部からの攻撃を検出・防御することをウリにしていることが多いですが、AWS WAFはそれ単体では防御機能は有せず、別途外部ベンダーやAWS自身が提供しているカスタムルールを用いることで防御を行ったり、ユーザ自身がルールを設定することで簡易な防御を行うこともできます。

今回は自宅IP以外からのアクセスを防御するということで、カスタム設定を行います。
構成はこんな感じで、CloudFrontと連動した設定となります。

本記事の設定例を行うことで、月6ドル+100万リクエストあたり0.6ドルの課金が発生しますのでご留意ください。(ACL:$5 x1、ルール:$1 x1)※2021年3月時点

AWS WAF設定方法

概要

さて、AWS WAFのルール設定の仕組みが解りにくいと感じるのは私だけでしょうか。
今回の設定を例に、設定方法を図示すると以下のようになります。

  1. IPSetを作成し(当方環境はIPv6デュアルスタック構成のため、IPv4とv6の両方を設定)
  2. それに応じた許可・拒否ルールを設定
  3. 複数ルールを交えたルールグループを作成して
  4. WebACLで紐付け先とデフォルト動作を設定する

以下の手順では個々の段取りに応じて設定していくことにします。

IP Setの作成

まず、IPSetの作成を行います。
WAF & Shield Consoleを開くか、AWS ConsoleからWAFを選択します

まず、左側メニューより「IP Sets」を選択し、IP Setの設定画面を開きます。

続けて設定画面より「Create IP Set」を選択します。

入力画面が開きますので、IP Setの名前、IPv4/v6の選択、IPアドレスを入力します。
今回はCloudFrontに適用しますので、Regionは「Global(CloudFront)」となります。
今回はIPv4/v6両方のエントリを追加しました。


Rule/RuleGroupの作成

続けて判定ルールとルールグループの設定を行います。
今回は前述のように、3つのルールを束ねたルールグループを作成します。

左側メニューから「Rule groups」を選択し「Create rule group」をクリックします。

最初にRuleGroupの名前と、適用先としてCloudFrontを選択します。

ルールの設定画面に遷移します。「Add rule」をクリックしルール設定画面に入ります。

ルールの設定画面で、今回は3つのルールを作成します。
まず、IPv4/v6各々のIPアドレスからのアクセスは許可する設定を追加します。

同様に、/wp-admin ロケーション以下へのアクセスは拒否する設定を追加します。

3つのルールがルールグループに追加されたことを確認し、「Next」をクリックします。

次の画面でルールの判定順序を指定できます。
事前に計画した判定順序通りか確認し「Next」をクリックします。

最後に設定内容の確認画面に遷移しますので、内容を確認し「Create rule group」をクリックし完了です。

WebACLの作成

いよいよ最終工程であるACLの作成です。
まず左側メニューの「Web ACLs」から「Create web ACL」をクリックします。

最初にWeb ACLの名前と、リソースタイプ(今回はCloudFrontに適用するため「CloudFront distributions」)を選択します。また、「Add AWS resources」より適用するリソース(CloudFront Distribution)を選択します。

続けて、判定に用いるルールグループとの紐づけを行います。
前工程でルールグループは作成済のため、「Add my own rules and rule group」を選びます。

Rule typeとして「Rule group」を選択、ルール名と紐づけるRule groupを選択します。
終わりましたら「Add rule」を選択します。

Ruleが登録されたことを確認します。
Default actionとして今回は「Allow」を選択し「Next」をクリックします。

次にRuleのプライオリティを指定します。
今回は1つのためそのまま「Next」

CloudWatch metricsに統計情報を出力することが可能です。(私は無効としました)
また、ACL設定画面にアクセスの一部をサンプル出力することが可能です(私は有効としました)

最後に確認画面です。
設定内容が正しいことを確認し、「Create web ACL」をクリックします。

これで設定完了です。
自宅外のネットワークから管理者画面にアクセスし、403エラーが出力されることが確認できました。

AWS WAFブロック時のカスタム応答の設定

タイミングよく、2021/3/29 よりカスタム応答のサポートが始まりましたので設定してみます。

AWS WAF が、カスタム応答のサポートを追加

今までAWS WAFで拒否した場合のエラー画面は以下のようなものでしたが、カスタマイズできるようになったというアップデートになります。

403応答のカスタム画面

RuleGroup内の設定「/wp-admin ロケーション以下へのアクセスは拒否するルール」に以下のような設定を行うことで、403応答の画面をカスタムすることができます。なお、Response Codeは200~500番台の各種応答コードから幅広く選択可能ですので「アクセスは弾いたけど200応答で正常応答を装う」ことも可能ですね。

新規のResponse Bodyを作る際には、「Choose how you would like to specify the response body」メニューから「Crete a custom response body」を選択し作成します。

新規Custom Response bodyの名前、および形式、内容を記入します。
形式は JSON/HTML/テキスト から選択可能です。

Response bodyは全て1行で、4KB以下にする必要があります。

ということで本設定を行うことで、エラー画面を表示することができました。

302リダイレクトの設定

エラー画面を表示せず、別のURLにリダイレクトすることも可能です。
応答コードに302を指定、Locationヘッダに転送先のURLを指定するだけで設定可能です。

おわりに

ここまでの設定で、WordPress管理者画面へのアクセスを抑止できるようになりました。

AWS WAFはコストも掛かるということで及び腰だったのですが、カスタマイズし甲斐があって面白いな、と思いました。コスト見合いの検討にはなりますが、カスタムルールの追加や一部マネージドルールの適用も検討してみたいと思います。

コメント