mod_dosdetectorなどを使ってbotの大量アクセスを検知して、エラーをかえしたい場合に
DoSDetection on
DoSPeriod 10
DoSThreshold 30
DoSBanPeriod 60
DoSTableSize 200
DoSIgnoreContentType image|javascript|css
RewriteEngine On
RewriteCond %{ENV:SuspectDoS} =1
RewriteRule .* - [R=503,L]
と設定したりしますが、深遠なる理由でウェルノウンな503や402を使いたくない環境で、RFC6585で追加された”429 Too Many Requests“の存在に気付き、
RewriteRule .* - [R=429,L]
の様に設定したみたのですが、動きませんでした。
Syntax error on line xxx of /path/to/httpd/conf/httpd.conf:
RewriteRule: invalid HTTP response code '429' for flag 'R'
とエラーがでます。ApacheはまだRFC6585をサポートしていないようです
そこで無理矢理対応させたのが、
このgist。このパッチをあててApacheをrebuildすると 429が返せました。
$ curl -v http://localhost:8080/
< HTTP/1.1 429 Too Many Requests
< Date: Mon, 10 Dec 2012 16:18:56 GMT
< Server: Apache
< Content-Length: 192
< Connection: close
< Content-Type: text/html; charset=iso-8859-1
<
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>429 Too Many Requests</title>
</head><body>
<h1>Too Many Requests</h1>
<p>You sent too many requests.</p>
</body></html>
* Closing connection #0
ただ、429をかえす場合、RFC6585では
The response representations SHOULD include details explaining the condition, and MAY include a Retry-After header indicating how long to wait before making a new request.
とアクセスが成功しなかった理由について説明をいれることが求められているのでこのパッチのように固定の文字列で返してしまうのはイマイチなのかなと思いました。
なお、某所ではこのパッチは使用せずに、429を返すサーバを書いてproxyして対応しました。nginxの対応考えるとproxyのほうが楽