rspamdのRatelimitモジュールにおけるレートリミットの振る舞い

自分の業務でrspamdを使う場面が増えてる。 rspamdはメールのスパム検知などをになってくれるソフトウェアで、postfixなどからmilterとして利用することができる。 最近だとRatelimitモジュールを使ってるのだが、レートリミットの振る舞いについて理解が浅かったので整理した。

rspamdのRatelimitモジュールとは

rspamdではさまざまなモジュール提供しており、Ratelimitモジュールもその一つ。 文字通りレートリミットをかけられる。

ref:https://rspamd.com/doc/modules/ratelimit.html

設定例

この記事では以下のような設定を考える。 rspamd触りたての自分は、この設定は以下のような意味だろうと考えていた。

  • <制限したいドメイン>について1時間あたり60通送信したらレートリミットがかかる
  • ただし、5通だけは超過を許容している

この考え方は合っているようで合ってない。 以下もう少し詳しく触れていく。

$ sudo cat /etc/rspamd/local.d/ratelimit.conf

rates {
  sample = {
    selector = 'rcpts';
    key = '<制限したいドメイン>';
    bucket = [
      {
        burst = 5;
        rate = "60 / 1h"; 
      },
    ];
  }

Token Bucket Algorithm

前提として Token Bucket Algorithm というものを理解する必要がある。 Ratelimitモジュールでもこのアルゴリズムが採用されており、上記パラメータはこのアルゴリズムで利用されるからである。

Token Bucket Algorithmとはデータの流量を制御する時に採用されるアルゴリズムの一種で、メールに限らずあらゆる帯域制御やレートリミットで採用されている。 大まかなコンセプトとしては「一定時間のデータ転送に制限をかけつつある程度のバースト性を許容する」というもの。 データの送信がある度に消費されるトークンと、トークンを蓄えるバケットを利用して流量を制御する。

具体的には以下のようにして流量制御される。

  • 一定時間おきにバケットトークンが追加される
  • ただしバケットが満杯の時は新しいトークンは破棄される
  • メッセージが到達すると、バケット内に十分なトークンが残っているかチェック
    • ある場合は、その分だけトークンを消費してメッセージが送信される
    • 足りない場合は、そのメッセージはsoft rejectされる(振る舞いの変更は可能っぽい)
  • バースト分についてはバケット内のトークン数をマイナスにする形で許容されるが、その後はトークンが補充されるまでレートリミットがかけられる

今回の設定だとどうなるか

ここでもう一回設定例をみてみる。

    selector = 'rcpts';
    key = '<制限したいドメイン>';
    bucket = [
      {
        burst = 5;
        rate = "60 / 1h"; 
      },

burstrateはどちらもToken Bucket Algorithmで使うパラメータである。 このアルゴリズムに当てはめると以下のようになる。

  • アルゴリズムの適用対象は宛先が<制限したいドメイン>の場合とする(それ以外のメールには影響しない)
  • 1時間で60個のトークンを継続的に補充する(60秒で1トークン)
  • バケットの容量は60
  • バーストは5なので、一時であればバケット内のトークン数-5にして送信できるが、その後レートリミットがかかる
  • レートリミットがかかったらバケット内のトークン数が0以上になるまで解除されない

タイムラインでイメージしてみる

0:00〜1:00の間で考えてみる。 簡略化のためにタイムラインは10分刻みとしている。

10分刻みで考えているのでトークンの補充頻度は10分で10トークンとなる。 この補充頻度に対して、送信量が超過してバケット内のトークン数が0下回った場合、0以上までトークンが補充されるまではレートリミットがかかったままになる。 以下の表だと0:40にburstしたので、0:40〜0:50の間はレートリミットがかかる。 これが解除されるのはトークンが補充されて0以上になる0:50である(0でもバーストはできるので送信可能らしい)。

時刻 送信されたメール数 補充 or 消費されるトークン数 バケット内のトークン数 備考
00:00 0 10 補充 / 0 消費 60.0
00:10 40 10 補充 / 40 消費 30.0
00:20 10 10 補充 / 10 消費 30.0
00:30 15 10 補充 / 15 消費 25.0
00:40 45 10 補充 / 45 消費 -10.0 burst
- / - -10.0 から徐々に補充 ratelimit exceeded
00:50 0 10 補充 / 0消費 0.0 ratelimit lifted
01:00 0 10 補充 / 0 消費 10.0