何が起きたか
ランサムウェアだとかDDosだとかそういう重大事ではないんですが、なんらかの原因(詳しい原因不明、バズったとかでもない)でアクセスが集中した結果、DBインスタンスがリクエストを捌ききれなくなって、システム全体がダウンするという状態になりました。最初は「バッチのメールが送られてこないんだよね」ぐらいの気軽な問い合わせだったんですが、よくよく見てみたらショップサイトもバックオフィスもバッチも全部動かない、動いてもエラー多数みたいなことになってて、いやダメだろこれ。
何をしたか
応急措置としてDBインスタンスを目一杯までスケールアップして暫定復旧させたのち、アクセスをコントロールしていくという手順を取ったのですが、コントロールする手段がサーバに手を突っ込んでなんかするっていう昔ながらの手段しかなくてそれはちょっとキツい。ということで、先方に説明して急遽ELB(ALB)を入れて、ALBにAWS WAFを設定して対応しました。それだけで月$150~300ぐらいのコスト増になるけれど、それぐらいなら必要経費でしょう。
WAFで何をしたか
WAFには無料で使えるマネージドルールグループと、有料になるマネージドルールグループがあるんですが、とりあえず無料で使えるマネージドルールグループから必要最低限のものをカウントモードでセット(誤検知を避けるため)。その後様子を見つつ、経験上、誤検知が起きにくいルールに関してブロックモードに移行。無料で使えるマネージドルールグループ(抜粋)
- AWS-AWSManagedRulesAmazonIpReputationList
- AWS-AWSManagedRulesPHPRuleSet
- AWS-AWSManagedRulesCommonRuleSet
- AWS-AWSManagedRulesKnownBadInputsRuleSet
さらに有料になるルールセットをセットしてみて、効果がありそうなものを選んでセット。
有料のマネージドルールグループ(抜粋)
- AWS-AWSManagedRulesBotControlRuleSet
- AWS-AWSManagedRulesACFPRuleSet
さらに90%以上国内向けサービスなのになぜかアメリカからのリクエストが過半数を超えていたので、確認を取った上で海外からのアクセスを一時的に遮断。
海外からのアクセスを遮断するルール
{
"Name": "block-from-overseas",
"Priority": 6,
"Statement": {
"NotStatement": {
"Statement": {
"GeoMatchStatement": {
"CountryCodes": [
"JP"
]
}
}
}
},
"Action": {
"Allow": {}
},
"RuleLabels": [
{
"Name": "comefrom:overseas"
}
],
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "block-from-overseas"
}
}
ちなみに海外からのアクセスに関しては、BotControlRuleSetとACFPRuleSet(アカウントの作成を監視するルールセット)に対して設定を行ったら、怪しいリクエストにはきちんとチェックを入れられるようになったので、現在は解除しています。
どうなったか
WAFの導入に合わせてCPUクレジットが徐々に回復。緊急対応で一部テーブルの日本語全文検索用インデックスが消失したことがわかり(そんなことあるんですね)、それが原因で一時的に負荷が上がったものの、INDEXを復旧させるとともに海外からのアクセスを遮断、マネージドルールを設定することで負荷を安定して下げることに成功しました。
まとめ
転ばぬ先のWAFいやマジで。
アクセスが集中した原因は結局海外からのBotの攻勢だった可能性が強く、結果的にWAFで上手く捌けた感じがあります。アカウント作成が自動化されるみたいな被害もちらほらあったそうなので、副次的にそれらも制御できたかな。
今後、様子を見つつWAFのルールを厳しくしたり、または緩くしたりしながら、DBインスタンスをちょうど良いサイズまでスケールダウン出来れば、コスト面的にも良い感じに出来るかなと思いますが、やはり基本的には規模に合わせた適切な投資が必要だよねと強く思いました。なんとか出来てほんと良かった。経験が生きたな。
ブロントさん名言集