ひろろの思うがままに。

自由奔放。思ったことや感じたこと、そんなことを書き溜めて、レベル上げて。

【Nginx】でアクセスを規制してみる

f:id:tack13:20190702225317p:plain

お久しぶりです。

最近多忙でなかなか更新できていませんでした。 三日坊主とかではないです。

今回は、Nginxでアクセス制限を設定してみようと思います。

ことの経緯は、Laravel+Vueで構築していたSPAで、429が頻発(ではないけどちょいちょい発生)していました。

本来ならLaravel使ってるんなら、アクセス制限なんかアプリでやれよ!

って思われるかもしれませんが、バックエンド転送の総量を制限したいってことで、それはまた別の機会に。

そもそも429とは

Http Status 429: Too Many Requests 文字通りですが、短時間(ユーザが設定した時間間隔内)にたくさんアクセスし過ぎとのことです。

AjaxAPIを大量に呼んでいるため、フル活用しているアプリならすぐに引っかかっちゃいそう。

そういうことで、MiddleWare側でアクセス制限を設定しようと思います。

nginxのリクエスト制御モジュール ngx_http_limit_req_module を使用してアクセスを規制してみます。

概要

  • 使用方法
  • rate limit(limit_req_zone)でアクセス頻度を設定
  • burstで一時的な大量アクセスを保持し、正しいアクセス頻度で実施
  • nodelayである基準に従い、即座にリクエストを処理するか弾く
  • 設定内容

使用方法

http {
  limit_req_zone $binary_remote_addr zone=zone:10m rate=10r/s;
  ...

  server {
    ...
    location = /some/application/path {
      limit_req zone=zone;
    }
    ...
  }
}

limit_req_zonehttp ブロックにしか記述できないので注意してください。

limit_req_zone

limit_req_zone $binary_remote_addr zone=zone:10m rate=10r/s;

アクセス制限を行うためのものです。

$binary_remote_addrIPアドレスを示すので、 IPアドレスごとに制限をかけ、zoneという名称で定義し、10MB分のIPアドレスを保持します。

rateで設定している10r/sはアクセス頻度のことで、1秒間に10アクセスする程度の頻度を表します。

1秒間に10アクセスできる。というわけでもないのでここもご注意を。

limit_req

limit_req zone=zone;

limit_req_zoneに定義したzoneという名称の制限を実際に適用している部分になります。

burst

limit_req zone=zone burst=10;

上限を超えたリクエストはburstに指定した数だけ保持します。

リクエスト数がburstを超えたら503が返されます。

nodelay

limit_req zone=zone burst=5 nodelay;

処理を遅延させないためのオプション。

burstが設定された場合は、nodelayを設定可能です。

burstのみの場合、処理はrateを超えないように遅延されますが、 一時的なリクエストの増加を許容したいときには遅延は不要になるため指定します。

nodelay についてはちょっとややこしいんですが、上記のように一時的に許容量を増やしてくれるんだな。 くらいで考えたほうが楽です(自分的に)。

設定内容

記述した設定内容に関して説明すると、

IPアドレスごとに、1秒間に10アクセスする程度の頻度を許容する。

という形になります。

10アクセス程度とは10r/sなので、「1/10秒」のアクセス間隔でないといけないということになります。

そのため、リクエスト間隔が0.1秒未満になるとアクセス制限に引っかかってしまう。というわけですね。

紛らわしい。

まとめ

そういうわけで、Nginxでアクセス制限を設定してみました。

アクセス制限というよりかは、アクセス流量ですね。

今回設定した内容以外にも、いろんなパターンを想定した流量制御もNginxだけで実現可能なので、いつかその辺も触れていきたいと思います。

そもそもだけど、もっとMiddlewareに強くならないとな〜。

rate limitに関してももっと理解しなければ。