Azure FunctionとWebJobで、Azure Storage Queueを介して、LINE Bot APIのメッセージの収集と送信を行うサンプルを作成しました。
LINE Bot APIへリクエストするにはServer whitelistにIPアドレスを設定する必要があります。*1
おそらく同一MIDを使ったDDoS攻撃への対策だと思いますが、このwhitelistのせいでグローバルIPアドレスを固定できないPaaSが使えなくなってしまいます。 *2
DDoS攻撃への対策についてはwhitelistではなく、一定時間内に一定数を超える複数のIPアドレスから、同一MIDが正しいChannel IDとChannel Secretでリクエストしてきた場合、ブラックリストへ登録してリクエストを一定時間遮断するような実装にするのが良いと思います。*3
例えば下記のような方法があります。
- Redisに、MIDをKeyに含めて、下記のようなHashを一定時間のExpireでSetしておく。
- isBlockedをチェックしtrueなら遮断
- リクエスト元IPアドレスがipAddressと異なる場合、新たなIPアドレスをipAddressをSetしてaddressChangedCountをIncrement
- addressChangedCountが一定数を超えたらisBlockedをtrueにしてExpireを延長しておく
{ "ipAddress": "192.168.1.1", "addressChangedCount": 0, "isBlocked": false }
現状、whitelistチェックのためにデータストアへアクセスしているならば、処理コストをあまり増やさずにBOT開発者の利便性を向上させることができると思います。
ちなみにサンプルで作成した構成は下記の通りで
- Azure Functionでメッセージを収集しAzure Storage Queueへストア
- Azure WebJobでAzure Storage Queueをデキューして返信メッセージを生成しSending messages APIへPOST
この構成だと返信ジョブが失敗した場合に、一定回数のリトライも、リトライに失敗した場合のデータの保存もWebJob SDKが面倒見てくれます。*4
PaaSだと面白いBOTを思いついたら手軽に試せてスケールもしやすいので、LINE Bot APIの開発者の方にはServer whitelistの撤廃を検討頂けるとありがたいです。*5
*1:Callback URLをリクエストしてもらうのはServer whitelistの設定不要
*2:「Azure Web AppsはグローバルIPアドレスを固定にすることは可能ですか?」とMicrosoftに問い合わせてみたところ「まだその機能がありません。将来的にも組み込まれるかどうかもわからないようです。」とのこと
*3:弊社のゲームではBOT検出&遮断アルゴリズムの1つにリクエスト元IPアドレスを使ったものを実装している
*4:queueのアイテム名に「-poison」を付けて別queueに保存される
*5:トライアル版だからServer whitelistがあっただけだったなら杞憂