応用編: nginxで認証結果をキャッシュしたい〜認証処理の負荷を下げたい〜

2026年01月14日 水曜日


【この記事を書いた人】
ヒラマツ

セキュリティ本部 セキュリティ情報統括室に所属 システム開発者。2000年問題で「2038年問題は定年で対応しなくていい!」とフラグを...。

「応用編: nginxで認証結果をキャッシュしたい〜認証処理の負荷を下げたい〜」のイメージ

認証をnginx用にちょっと弄れる機能〜認証だってrewriteしたい〜から派生した記事です。
応用編なので、ngx_http_auth_request_moduleの認証モジュールが動作している前提の話になります。

ngx_auth_mod開発者のヒラマツです。

ここでは負荷対策として、認証モジュールの認証結果をnginxでキャッシュしたい方に、その設定確認手順を解説します。

サイトの利用頻度が増えれば、認証システムや認証DBの負荷も増えます。その結果、サイトの反応が悪くなったり、認証システムや認証DBが障害を起こしてしまうこともあります。

負荷増大のイメージ

このようなことを回避するために認証システムや認証DBへの負荷対策として、nginxのキャッシュ機能が使えます。具体的には、以下の図のような構成で、認証モジュールの認証結果がnginxでキャッシュできます。

キャッシュのイメージ

このように認証モジュールの認証結果をnginxでキャッシュすれば、連続で行われがちな同じ認証処理にキャッシュが利用されます。
つまり、認証システムや認証DBへの無駄な負荷を回避できるので、過剰な負荷のリスクが軽減できます。

負荷回避のイメージ


設定確認手順の概略

解説では以下のような構成を想定しています。実際に利用する環境に合わせて読み替えてください。

設定例の構成図

設定確認手順は以下の順で説明します。

  • 0. テスト環境の用意
  • 1. nginxにキャッシュ設定を追加
  • 2. キャッシュの作成・削除を確認
  • 3. 実環境への適用
  • 4. 応用

認証結果のキャッシュで設定ミスすると認証が誤動作して、情報漏えいにつながる可能性があるので、慎重に設定してください。

0. テスト環境の用意

仮想マシンなどの仮想環境などで、設定ミスしても情報漏えいしないように、設定作成用にテスト環境を用意します。

1. nginxにキャッシュ設定を追加

構成図1

1.1 キャッシュ保存先の定義

以下のようにキャッシュの保存先を定義します。

proxy_cache_path /var/cache/nginx/cont levels=2:2 keys_zone=zone_cont:1m max_size=1g inactive=24h;
proxy_cache_path /var/cache/nginx/auth levels=2 keys_zone=zone_auth:1m max_size=1g inactive=1m;
proxy_temp_path  /var/cache/nginx_tmp;

以下の点に注意してください。

  • 認証用(zone_auth)とコンテンツ用(zone_cont)は別ディレクトリに分離する。
  • 認証用はinactive(保存期間)を短め(例:1分)に設定し、不要に残さないようにする。
  • コンテンツ用はキャッシュサイズが大きくなるため、inactiveも効率を考えて長めに設定する。
  • キャッシュ設定の変更後は、キャッシュディレクトリを削除してからnginxを再起動する必要がある。

1.2 locationにキャッシュ領域を割り当て

以下のようにlocationへ、用意したキャッシュ領域を適切に割り当てます。

location locationの用途 キャッシュ領域
location = /auth 認証用内部URL zone_auth
location / 通常のコンテンツ zone_cont
server {
    ...

    location = /auth {
        auth_request off;
        proxy_intercept_errors off;
        proxy_cache zone_auth;
        proxy_cache_key $remote_user;
        #proxy_cache_key "$request_uri $remote_user";
        proxy_cache_lock on;

        proxy_pass http://127.0.0.1:9200;
        proxy_http_version 1.1;
        proxy_cache_revalidate on;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";

        ...

        internal;
    }

    location / {
        auth_request /auth;
        proxy_cache zone_cont;
        proxy_cache_key $request_uri;

        ...
    }

    ...
}

設定できたら、認証処理の動作を確認してください。

1.3 認証用キャッシュキーを設定

この例では、認証用キャッシュにproxy_cache_key $remote_user;というキャッシュキーの設定をしています。
不適切なキャッシュキーは誤動作を起こしたり、キャッシュ効率を低下させるので、サイトの認証方法に合った設定が必要です。

シンプルケース

ページ毎に認可設定しない場合は、proxy_cache_key $remote_user;の設定が効果的です。
この設定をページ毎に認証条件が変えられるサイトで利用すると、認証ミスが起きるので注意が必要です。

URLパスで認証条件が変わるケース

ページ毎(URLパス毎)に認証条件が変わる場合、proxy_cache_key "$request_uri $remote_user";のように設定します。
比較的安全な設定ですが、URLパス毎に認証用のキャッシュが作られるのでキャッシュ効率はあまり良くありません。

階層単位で認可条件が決まるケース(例: /group1/以下は同一条件)

ngx_http_rewrite_moduleifsetなどで、nginxの変数を作って、キャッシュキーを設定します。
以下は、ifsetを使った、URLパスの1階層目単位で認可設定するサイト用での設定例です。

set $auth_path_id "/";
if ($request_uri ~ "^(/[^/]+)/") {
    set $auth_path_id $1;
}

...

location = /auth {
    proxy_cache_key "$remote_user:$auth_path_id";
    ...
}

$auth_path_idに設定された1階層目パスで認証結果が共有されるので、キャッシュ効率は良くなります。ifで指定した正規表現を工夫すれば柔軟な設定も可能です。

1.4 コンテンツ用のキャッシュキー

コンテンツキャッシュ用のキーはサイトに合わせて適切に設定をしてください。
上記の例では分かりやすさ重視でproxy_cache_key $request_uri;と簡単な設定をしています。しかし、nginxのデフォルトはproxy_cache_key $scheme$proxy_host$request_uri;と意外と複雑だったりします。
このように利用状況に合わせる必要があるので、nginxのproxy_cache_keyのドキュメントを参照し、適切に設定してください。

1.5 認証用キャッシュの検証を設定

proxy_cache_revalidate on;の設定をすると、ETagなどでHTTPキャッシュの検証されるようになります。
HTTPキャッシュの検証が成功すると古いキャッシュが再利用されて、キャッシュの効率が上がります。

ngx_auth_modはETagヘッダーに対応しているので、この設定に効果があります。

1.6 認証用キャッシュを排他制御

proxy_cache_lock on;で認証用キャッシュの排他制御を設定すると、同一キーのキャッシュ生成中は、後続リクエストが待たされます。

重複した認証処理が抑制されるので、以下の図のように処理が軽くなります。

並列認証の対策イメージ

2. キャッシュの作成・削除を確認

構成図2

設定だけではキャッシュ動作が判断できません。実際にキャッシュファイルが作成・削除されるか確認します。

2.1 ファイル作成の確認

以下のようなコマンドでキャッシュファイルが作られることを確認します。

sudo watch -- 'find /var/cache/nginx/auth/ -type f'

このコマンドは、/var/cache/nginx/auth/配下のファイル一覧をリアルタイム表示してくれます。認証が行われると新しいファイルが出てくるはずなので、確認してください。

2.2 キャッシュキーの確認

キャッシュキーのファイル内部にKEY: というプレフィックス付きで保存されています(ソースコードより)。

そこで、以下のようなコマンドでリアルタイム表示してくれるので確認します。もし、想定と違う動作をしていたら、設定を見直してください。

sudo watch -- 'grep -ra -m 1 "^KEY: " /var/cache/nginx/auth/'

例えば、proxy_cache_key $remote_user;と設定した場合、キャッシュがない状態からuserアカウントで認証すると、このコマンドは以下の2行を出力します。

/var/cache/nginx/auth/7e/d41d8cd98f00b204e9800998ecf8427e:KEY: 
/var/cache/nginx/auth/ee/ee11cbb19052e40b07aac0ca060c23ee:KEY: user

この2行は、以下のような2つのキャッシュとそのキー情報を表示しています。

  • (ブラウザが自動で行う)認証入力無しでの最初の接続で作られるキャッシュ
  • userアカウントを入力した接続で作られるキャッシュ

このような内容が表示されるので内容に問題ないか確認してください。

2.3 キャッシュファイルの削除の確認

proxy_cache_pathinactiveの設定で、想定通りにキャッシュファイルが消えるか確認します。

生成の確認と同じように、以下のコマンドでキャッシュファイルが一覧から消えることを確認します。

sudo watch find /var/cache/nginx/auth/ -type f

inactive=1mと設定した場合、アクセスがなければ1分ほどでファイルは消えます。

2.4 コマンドの終了

確認が終わったら、watchコマンドは忘れずに終了してください。

3. 実環境への適用

テストで問題がなければ、実サーバに同じ設定を展開します。適用後もテストと同様の手順でキャッシュ動作を確認してください。

実環境での認証情報のキャッシュは情報漏えいのリスクを伴います。設定に不安がある場合は、速やかにnginxを停止し、設定を確認してください。

4. 応用

利用負荷によってキャッシュの最適な構成は変わります。でも、nginxの柔軟性を利用すれば、利用状況に合わせたより高度なキャッシュ構成も可能です。

例えば、ngx_rewrite_and_authで認可処理を分離する場合、以下の図のような、認証の処理効率を上げるための認証専用キャッシュを追加した多段な構成も選択肢になります。

認証認可を分離した複雑なキャッシュ構造の例

nginxの設定の柔軟さを活用すると、ngx_auth_modとの組み合わせで、このように複雑なキャッシュ構成も可能になります。
キャッシュ動作の確認方法は構成で変わらないので、丁寧に確認しつつ、利用に合った構成を設計してみてください。


設定手順の説明は以上です。

うまく認証をキャッシュして、心の負荷も軽い認証ライフを!

ヒラマツ

2026年01月14日 水曜日

セキュリティ本部 セキュリティ情報統括室に所属 システム開発者。2000年問題で「2038年問題は定年で対応しなくていい!」とフラグを...。

Related
関連記事