コンテンツにスキップ

アクセスを拒否する

accessハンドラは、locationのcontentの前に、nginxのaccessフェーズで動きます。そこで動くスクリプトは、403のようなステータスでリクエストを終えるか、ステータスを設定せずに戻ってリクエストを先へ進めます。詳しくはmruby_access_handlerにあります。このガイドでは、ファイルに載せたクライアントを、accessハンドラで拒否します。

accessハンドラは、変数$deny_listが指すファイルを読み、クライアントのアドレスがファイルの行のどれかと同じなら403を返します。location/listed/が指すリストには、テストのクライアントのアドレスである127.0.0.1があるので、リクエストは403になります。nginxは、error_page 403 @deniedに従って、その403にボディを付けます。location/open/が指すリストには、そのアドレスがありません。

test/conf/conf.d/74-guide-access.conf
server {
listen 18162;
default_type text/plain;
error_page 403 @denied;
# The list of this location holds 127.0.0.1, the address of the case.
location /listed/ {
set $deny_list build/nginx/html/guide_access_listed.txt;
mruby_access_handler build/nginx/html/guide_access.rb;
mruby_content_handler_code 'Nginx.rputs "welcome\n"';
}
# The list of this location does not hold it.
location /open/ {
set $deny_list build/nginx/html/guide_access_open.txt;
mruby_access_handler build/nginx/html/guide_access.rb;
mruby_content_handler_code 'Nginx.rputs "welcome\n"';
}
location @denied {
return 403 "your address is on the deny list\n";
}
}
test/html/guide_access.rb
r = Nginx::Request.new
path = r.var.deny_list
listed = File.exist?(path) && File.read(path).split("\n").include?(r.var.remote_addr)
Nginx.return Nginx::HTTP_FORBIDDEN if listed
test/html/guide_access.request:ケースが送るリクエスト
GET /listed/report HTTP/1.1
Host: 127.0.0.1:18162
Connection: close
test/html/guide_access.response:ケースが比べるレスポンス
HTTP/1.1 403 Forbidden
Content-Type: text/plain
your address is on the deny list

CIが動くたびに、ケースのtest/t/cases/guides.rbがこのリクエストを送ります。ケースは、ステータス行、ここに載せたヘッダ、ボディ全体を比べます。5個のファイルを最後に変えたのは、2026-10-29のコミット32219e53です。

ケースはGET /open/reportも送って、ボディがwelcomeの200を期待します。

  • スクリプトはリクエストのたびにリストのファイルを読むので、ディスクが答えるまでワーカーをブロックします。ワーカーごとに1回だけ読むには、mruby_init_worker_codeでリストを定数に読み込み、ファイルを変えたらnginxをリロードしてください。詳しくはワーカーがリクエストをまたいで保つものにあります。
  • r.var.remote_addrの値は、TCPの接続相手のアドレスです。ロードバランサの後ろでは、nginxのrealipモジュールがロードバランサの送るヘッダからアドレスを設定しない限り、そのロードバランサのアドレスになります。
  • Nginx.return Nginx::HTTP_FORBIDDENはステータス403でリクエストを終えます。Nginx.returnを呼ばずに戻るスクリプトでは、nginxはaccessフェーズの次のハンドラを実行し、その後contentへ進みます。