WAFでメンテナンス画面を表示してみた
以前運用保守チームでWAFを使ってメンテナンス画面を表示できる、という話をしていて、ちょっと試してみるかと思いやってみました。
以下のような構成を作りました。
許可したIPアドレスのみ通常のアプリ画面に飛ばし、それ以外はメンテナンス画面にリダイレクトさせます。メンテナンス中に動作確認したい場合はVPN経由などで見れます。
非許可のIPアドレスからのアクセスの場合は、WAFからステータスコード302を返して、メンテナンス画面にリダイレクトさせています。
メンテナンス画面もCloudFront + S3にデプロイしており、サブドメイン(maintenance.example.com)でホストしています。
ちなみに今回はやっていませんが、WAFはカスタムレスポンスで直接htmlを返すことができます。S3にhtmlを配置しなくてもいいので手間を省けます。
メンテナンス画面の作成
まずはメンテナンス画面を作成します。今回はReactのpublicフォルダーに静的htmlを配置しました。
react-app/
public/
maintenance/
index.html
index.css
サブドメイン
ドメインをお名前.comから無料で取得してきました。お名前.comは無料で取得できるドメインがありますが、一年後などドメインを更新する時に料金がかかります。
次にSSL証明書をAWS ACMで取得します。今回はサブドメインも利用するので、ドメインの設定にワイルドカードを使いました。
CloudFront
CloudFrontのディストリビューションをアプリ用のものと、メンテナンス画面用のもので2つ作成します。アプリ用の方はデフォルトパスを /index.html とします。
メンテナンス画面用の方はデフォルトパスを /maintenance/index.html とし、サブドメインを紐付けます。
まだRoute 53でレコードを登録していないので、ドメインを開いてもアプリの画面は見れませんが、ディストリビューションドメイン名を開くとページを確認できます。
Route 53
次にRoute 53でホストゾーンを作成し、 お名前.com側にNSレコードの設定をします。
Route 53でAレコードを作成して、メインドメインをアプリ画面用のCloudFrontディストリビューションに、サブドメインをメンテナンス画面用のディストリビューションにそれぞれ紐づけます
ここまででサブドメインを開いて見ると、メンテナンス画面を開けるようになったことが確認できます。
WAF
次にWAFの設定を行います。
自分のPCのグローバルIPを調べて、IPsetsに記入します
curl ifconfig.me
ipアドレスが一致した場合にアクセスを許可するルールを作成します
デフォルトでアクセスをブロックして、カスタムレスポンスでメンテナンス画面に遷移させます。ステータスコード302、レスポンスヘッダーでメンテナンス画面のサブドメインを指定します。
自分のPCから開いた時には、通常の画面を表示し、それ以外のipだとメンテナンス画面に遷移するようにしました。
今回の構成であれば、サイトを訪問中のユーザーもリロードするとメンテナンス画面に遷移します。また次回からはこのweb-aclをCloudFrontに割り当てたり、外したりすることで、メンテナンス画面とアプリ画面を切り替えることができます。
AWS SDKを使ってメンテナンス画面に切り替えるようなLambda関数を作っておけば、EventBridge スケジューラでcronを設定して定時で自動で切り替えることもできますね。
マネジメントコンソールを色々触れて勉強になりました!
参考記事