ARCHIVESDRIVE HB

オイラはホームベーカリー!

429 Too Many Requestsとは一体

429 Too Many Requestsとは

アプリケーションサイドさんから「429ってなんだよ……」と言われたので調べてみるなど。

RFC6585

RFC6585で定義されているらしい。日付見ると2012年の4月とかなってるしこれわりと新しいですね。

RFC 6585 - Additional HTTP Status Codes

一定時間内に制限に引っかかったリクエストに対して返却するステータスコードですかね。TwitterAPI制限とかそういうアレが一番想像しやすいでしょうか。 まあそんなDoS攻撃よろしく大量のリクエスト送ったら503になってしまうのでは?みたいな指摘もあり、その通りっすねという面もあります。

実装状況

という訳で、思いついて30分位で簡単に試してみました。 間違ってるじゃねーか!って所があったら、気付いた時になおします。

ロケ地

[root@vps ~]# cat /etc/redhat-release
CentOS release 6.8 (Final)

Apache 2.2.15

MySQL 5.7入れるためにリポジトリ追加してるのは許してください! とりあえずCentOS6公式の現在一番新しいバージョン2.2.15です。

[root@vps ~]# yum update httpd
Loaded plugins: fastestmirror
Setting up Update Process
Loading mirror speeds from cached hostfile
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
base                                                                                                                                     | 3.7 kB     00:00
extras                                                                                                                                   | 3.4 kB     00:00
mysql-connectors-community                                                                                                               | 2.5 kB     00:00
mysql-tools-community                                                                                                                    | 2.5 kB     00:00
mysql57-community                                                                                                                        | 2.5 kB     00:00
updates                                                                                                                                  | 3.4 kB     00:00
updates/primary_db                                                                                                                       | 2.0 MB     00:00
vz-base                                                                                                                                  |  951 B     00:00
vz-updates                                                                                                                               |  951 B     00:00
No Packages marked for Update
[root@vps ~]# httpd -v
Server version: Apache/2.2.15 (Unix)
Server built:   Jul 18 2016 15:24:00

httpd.confに以下の記述を追加してconfigtestを実行してみます。

ErrorDocument 429 /error/index.html.var

サポートしとらんがな!と言われました。実装時期的に、当然ですがこのバージョンはだめなようですね。

[root@vps730 ~]# /etc/init.d/httpd configtest
Syntax error on line 890 of /etc/httpd/conf/httpd.conf:
Unsupported HTTP response code 429

ちなみに、Apache 2.4のErrorDocumentページにも一覧とかはありません。

core - Apache HTTP サーバ バージョン 2.4

2.4のheadとかなら対応してるのかな? とりあえずErrorDocumentで蹴られたのでエラーページを設定できないのでダメなようですね。

Nginx 1.2.5

Nginx 1.2.6ならサポートしとるぞ!とStackOverflowのコメントに書いてあったので、一つ前の1.2.5を入れて確かめてみます。

stackoverflow.com

[root@vps ~]# wget https://nginx.org/download/nginx-1.2.5.tar.gz
[root@vps ~]# tar -zxvf nginx-1.2.5.tar.gz
[root@vps ~]# cd nginx-1.2.5
[root@vps ~]# ./configure --prefix=/usr/local
[root@vps ~]# make
[root@vps ~]# make install
[root@vps ~]# nginx -V
nginx version: nginx/1.2.5
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
configure arguments: --prefix=/usr/local

導入でき申した。 早速コンフィグ/usr/local/conf/nginx.confに以下を追加してApache同様エラーにならないか、テストしてみましょう! (429.htmlは実際に存在しなくても大丈夫なはずです。)

        error_page  429              /429.html;
[root@vps ~]# nginx -t
nginx: the configuration file /usr/local/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/conf/nginx.conf test is successful

おっ通りました。しかしerror_pageに何を指定されても通すガバ設定だと困るので、あり得ない値を付与して確かめてみましょう。

        error_page  114514              /429.html;

オォン!アォン!!

[root@dti-vps-srv730 conf]# nginx -t
nginx: [emerg] value "114514" must be between 300 and 599 in /usr/local/conf/nginx.conf:48
nginx: configuration file /usr/local/conf/nginx.conf test failed

怒られました、300-599の間だけやぞ!とのことなので、逆にこの間ならなんでも設定できるようです。 Apacheとは違ってerror pageの実装がされてないからダメ!と安易な判断は出来ないようです。

ではNginxは結局どうなのか

limit_reqが実装されている場合、使用することで制限できるようです。

nulab-inc.com

じゃあ1.2.5はどうなのってことでlimit_req_statusが動くかどうかでテストしてみました。

limit_req_status 429;
[root@vps conf]# nginx -t
nginx: [emerg] unknown directive "limit_req_status" in /usr/local/conf/nginx.conf:18
nginx: configuration file /usr/local/conf/nginx.conf test failed

だめなようです、しゃーなし。

Nginx 1.10.1

最新版の1.10.1を入れてみましょう!流石にコレは対応してるはず!

[root@vps ~]# wget https://nginx.org/download/nginx-1.10.1.tar.gz
[root@vps ~]# tar -zxvf nginx-1.10.1.tar.gz
[root@vps ~]# cd nginx-1.10.1
[root@vps ~]# ./configure --prefix=/usr/local
[root@vps ~]# make
[root@vps ~]# make install
[root@vps ~]# nginx -V
nginx version: nginx/1.10.1
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
configure arguments: --prefix=/usr/local

はいもう一回コンフィグ投入してみます。

limit_req_status 429;
[root@vps ~]# nginx -t
nginx: the configuration file /usr/local/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/conf/nginx.conf test is successful

おっ動きましたね、Nginx最新版では429 Too Many Requestsは扱えると思っていいでしょう。

Nginxで導入された時期

1.3.15かららしいです。その他のバージョンも大体これくらいの時期(2013/3/26あたり)を目安にすれば取り込まれているのでは?

nginx-1.3.15

Module ngx_http_limit_req_module

結局429 Too Many Requestsを扱いたい時はどうすればいいのか

Nginxは1.3.15以降を、Apacheはよくわかんないのでそのうち2,4の最新版あたりを調べますです……。