AWS WAF でメンテナンスモードの開始・解除を実現する ( +特定のIPアドレスだけはアクセスを許可する )
概要
サービスメンテナンス中に、レスポンスコード 503 Service Temporarily Unavailable
と、メンテナンス表示用のHTMLをユーザーに返したい
ALBとの比較
ALBでやる欠点は
- 構成によってはALBで実現しようとすると作業が煩雑だったり、困難だったりする。
- 特定のIPアドレスだけ許可しようとしても、1ルールあたりのIPアドレス設定の上限があり、やりづらい。
- 1ルールの中でレスポンスヘッダが指定できないので、キャッシュコントロールがしづらい。
思い出してほしい。ALBは「バランサー」である。
メンテナンスモードに限らず、WAFでもALBでも実現できる動作はあるが、あくまでALBはパスに対してのリソースの振り分けに徹した方が良いと思った。
WAFの設定手順
STEP 1 . WAFにカスタムレスポンスを作成しておく
AWS WAF > Web ACLs > ACL名 > Custom Response Bodies から
- 文字化けしないようにHTMLで文字コード系の指定をしておく
- キャッシュが問題にならないようにキャッシュコントロールのmetaタグを指定しておく
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="content-language" content="ja">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<title>メンテナンス中 </title>
</head>
<body>
ただいまメンテナンス中です
</body>
</html>
STEP 2. WAF ルールの追加
登録開始
AWS WAF > Web ACLs > ACL名 > Rules > Add my own rules and rule groups を選ぶ
Actions の指定
- Blockを選ぶ
- カスタムレスポンスを利用する
- レスポンスコードは503
- ヘッダに
Cache-Control
no-cache
を指定する ( メンテナンスモードを解除しても、ユーザ端末のキャッシュによって解除されていないように見えるのを防ぐ )
ルール同士の優先順位を決めてSaveする
設定すべき優先順位は構成による
STEP 3. 特別に許可するIPアドレスの設定
必要な場合は、STEP2と同じWAFのルールに、メンテナンスモードでもアクセスできるIPアドレスを設定する
まずは事前にWAFでIPセットを登録しておく
単一のIPセットを許可する場合は
「リクエストのIPアドレスが、IPセット1のものでない場合」にルールを適用するという条件を設定すれば良い
複数のIPセットを許可対象にする場合は
「リクエストのIPアドレスが、IPセット1のものでなく、なおかつ、IPセットのものでもない2場合」にルールを適用する条件を設定すれば良い
STEP 4. WAF ルールの削除
メンテナンスが終わったらWAFのルールを削除するだけ
STEP 5. 再度メンテナンスモードにする時
AWSからの直接登録だと、メンテナンスをする時に1回ずつが面倒だと思うが、どうするか
JSONで設定する
JSONでルールを保持できるようなので、それを次の登録時にも使うと良いだろう
ただし今回のようにAWS上の他のリソース (カスタムレスポンスのBODYやIPセット)も参照する形だと、ひとつのAWSアカウントのJSONは、他のAWSアカウントの環境では使えないので注意
優先順位で工夫する
ルール自体は削除せず保持したまま、他のルールとの優先順位の入れ替えでも簡単な切り替えを実現できるかもしれないが、未検証
チャットメンバー募集
何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。
プロフィール・経歴
公開日時
2024-07-05
Discussion
思い出してほしい。WAFは「ファイヤーウォール」である。
CloudFront や ALB に横付けするのがWAFであり、別料金がかかる。
L7で処理できるALB(のリスナールール)のほうが柔軟な対応ができる(場合がある)。
既にWAFを利用していて、IPアドレス以外の条件では分岐を行わず、ALBのリスナールールが既に十分複雑である(から弄りたくない)場合、はWAFを使う選択もありだと思うが、それ以外はALBのリスナールールを採用したほうが総合的に楽。
そもそもパスベースのルーティングで管理画面のアクセス制限する時もALBで実現できる。
メンテモードはこのパス指定がないのと同じ(全てのパスで指定のIPアドレスの時に既存のターゲットグループに流す)なので、メンテモードのメンテナンスも楽。
WAFでもALBでも管理を terraform や cdk などの IaC を活用していれば適用も復元も問題ないと思われる。
手作業で json 管理は勧められない。
ちなみにALBでやるなら優先度を変えるだけで条件をとっておいても大丈夫(実際に処理されないように最後に持っていく。使う時に優先度を上げることで処理されるようにする)な点もWAFよりALBを採用する理由にできると思う。