429 Too Many Requestsとは
アプリケーションサイドさんから「429ってなんだよ……」と言われたので調べてみるなど。
RFC6585
RFC6585で定義されているらしい。日付見ると2012年の4月とかなってるしこれわりと新しいですね。
RFC 6585 - Additional HTTP Status Codes
一定時間内に制限に引っかかったリクエストに対して返却するステータスコードですかね。TwitterのAPI制限とかそういうアレが一番想像しやすいでしょうか。 まあそんな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を入れて確かめてみます。
[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が実装されている場合、使用することで制限できるようです。
じゃあ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あたり)を目安にすれば取り込まれているのでは?
Module ngx_http_limit_req_module
結局429 Too Many Requestsを扱いたい時はどうすればいいのか
Nginxは1.3.15以降を、Apacheはよくわかんないのでそのうち2,4の最新版あたりを調べますです……。