2014-02-16
制限したいUserAgentが増えると管理が面倒。
Nginxの場合だと
if ($http_user_agent ~ (ZmEu|VeryBadBot|MaliciousBot) {
return 403;
}
で出来るのは知っているのだけど、これだと制限したいUserAgentを増えてくると管理が面倒。
map
なんとかならんのかと思ったらmap
ディレクティブを使うとなんとかなった。
map $http_user_agent $bot {
default 0;
~*(zmeu|verybadbot) 1;
~MaliciousBot 1;
~*(whatever|you|want) 2;
}
server {
if ($bot = 1) {
return 403;
}
if ($bot = 2) {
return 500;
}
}
とこんな感じで、UserAgentにzmeuやverybadbot(大文字小文字に関係なく)が含まれていると403を返す。UserAgentにMaliciousBotが含まれていると同じく403を返す。UserAgentにwhateverやyouやwantが含まれていると500を返すという設定ができるようだ。
ちなみに~
はNginxにおける正規表現で、~*
でcase-insensitive(大文字と小文字区別しない)、~
だけだとcase-sensitive(大文字と小文字を区別する)になるのだそうな。
言うまでもなく設定ファイル編集後はNginxの再起動か設定のリロードを忘れずに。
$ sudo service nginx restart # またはreload
簡単なテストはcurl
の-A
でUserAgentを変え、-I
でHEADをリクエストすると便利。
$ curl -A "verybadbot" -I http://localhost
HTTP/1.1 403 Forbidden
Server: nginx/1.4.4
Date: Sun, 16 Feb 2014 06:03:29 GMT
Content-Type: text/html
Content-Length: 168
Connection: keep-alive
あるいはHTTPieを使うのもよいでしょう。
$ http HEAD localhost User-Agent:whatever
HTTP/1.1 500 Internal Server Error
Connection: close
Content-Length: 192
Content-Type: text/html
Date: Sun, 16 Feb 2014 06:07:14 GMT
Server: nginx/1.4.4
こういうやり方がNginx的に最適なのどうかは当方知りません。実運用は自己責任でお願いします。