4.

nginx リバースプロキシ設定 proxy_pass/upstream の書き方 | ネットワーク入門

編集
この記事の要点
  • nginx をリバースプロキシにする中心ディレクティブは proxy_pass で、location で受けた要求を後ろのバックエンドへ転送する
  • 複数バックエンドへ分散する場合は upstream ブロックでサーバ群をまとめ、proxy_pass で upstream 名を指定する
  • proxy_set_header でクライアントの本来の情報 (Host / X-Real-IP / X-Forwarded-For / X-Forwarded-Proto) をバックエンドへ引き継ぐ
  • location でパスごとに転送先を変えられる。/api はアプリ、/ は静的配信、のような振り分けが定番
  • listen 443 ssl + ssl_certificate で SSL 終端し、バックエンドへは平文 HTTP で渡す構成が一般的

概要

本記事では、リバースプロキシ の代表実装である nginx を、実際にリバースプロキシとして設定する方法を具体的なディレクティブとともに解説します。中心となるのは proxy_passupstreamlocationproxy_set_header の 4 つです。これらを組み合わせると、SSL 終端・負荷分散・パスベースルーティングを 1 つの設定ファイルで実現できます。設定ファイルの基礎は conf(.conf) も参照してください。親項目は 負荷分散・プロキシ・CDN です。

仕組み

nginx の設定は http ブロックの中に server ブロックを置き、その中に location ブロックを並べる入れ子構造です。リバースプロキシに関わる主要ディレクティブは次のとおりです。

  • proxy_pass: その location にマッチした要求の転送先 (バックエンドの URL や upstream 名) を指定する。リバースプロキシの心臓部。
  • upstream: 複数のバックエンドサーバを 1 つのグループ名にまとめる。分散アルゴリズム (least_conn / ip_hash 等) もここで指定する。
  • location: パス (URL) ごとに処理を分ける。/api/ で別のバックエンドへ送るといった振り分けに使う。
  • proxy_set_header: バックエンドへ転送する際にヘッダを追加・上書きする。クライアントの元 IP やホスト名を伝えるために必須。

とくに proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; は、転送のたびにクライアントの IP を追記していくため、バックエンドが本来のアクセス元を把握できます。X-Forwarded-Proto $scheme は、クライアントが HTTP/HTTPS どちらで来たかをバックエンドへ伝えます。HTTPS の基礎は HTTPS を参照してください。

設定・実用例

HTTPS で受け、/api/ はアプリ群へ負荷分散、それ以外はローカルの静的ファイルを返す、実用的な構成例です。HTTP (80) は HTTPS へリダイレクトします。

# 複数のアプリサーバをまとめる
upstream api_backend {
    least_conn;
    server 10.0.0.21:8000;
    server 10.0.0.22:8000;
    server 10.0.0.23:8000 backup;   # 通常は使わない予備機
}

# HTTP は HTTPS へリダイレクト
server {
    listen 80;
    server_name www.example.com;
    return 301 https://$host$request_uri;
}

# HTTPS で受けて SSL 終端
server {
    listen 443 ssl;
    server_name www.example.com;

    ssl_certificate     /etc/nginx/ssl/example.crt;
    ssl_certificate_key /etc/nginx/ssl/example.key;

    # /api/ への要求はアプリ群へ転送
    location /api/ {
        proxy_pass http://api_backend;

        # クライアントの本来の情報を引き継ぐ (定番セット)
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_read_timeout 60s;
    }

    # それ以外は静的ファイルを直接配信
    location / {
        root  /var/www/html;
        index index.html;
    }
}

設定変更後は構文チェックしてから再読み込みします。サービスを止めずに反映できます。

# 構文チェック
sudo nginx -t

# 問題なければ無停止で再読み込み
sudo nginx -s reload
# もしくは
sudo systemctl reload nginx

主な用途

  • SSL 終端 + 平文転送: 証明書を nginx に集約し、バックエンドは HTTP で単純運用する。
  • 負荷分散: upstream に複数台並べ、proxy_pass でグループへ振り分ける。
  • パスベースルーティング: /api はアプリ、/static は静的配信、と location で分ける。
  • WebSocket 中継: Upgrade/Connection ヘッダを設定して双方向通信を通す。
  • キャッシュ前段: proxy_cache でバックエンドの応答をキャッシュし負荷を下げる。

主要ディレクティブの整理

ディレクティブ役割記述例
proxy_pass転送先の指定proxy_pass http://api_backend;
upstreamバックエンド群の定義upstream api_backend { ... }
locationパスごとの振り分けlocation /api/ { ... }
proxy_set_headerヘッダの付与/上書きproxy_set_header Host $host;
ssl_certificateSSL 終端の証明書ssl_certificate /path/crt;

注意点

  • proxy_pass の末尾スラッシュ: proxy_pass http://backend/;/ 有無で location のパス処理が変わる。意図しないパス書き換えに注意。
  • Host ヘッダの引き継ぎ: proxy_set_header Host $host; を忘れると、バックエンドが想定したホスト名で動作せず 404 やリダイレクトループになることがある。
  • X-Forwarded-For の信頼: 外部から直接届く位置のヘッダはクライアントが詐称できる。アプリ側は信頼するプロキシの値だけ採用する。
  • タイムアウト: 長時間処理やストリーミングでは proxy_read_timeout を延ばさないと途中で切れる。
  • reload 前に nginx -t: 構文エラーのまま reload すると反映されない/起動失敗する。必ず nginx -t で検証する。

関連リンク

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. フォワードプロキシ
  2. リバースプロキシ
  3. ロードバランサ
  4. nginxリバースプロキシ設定
  5. HAProxy
  6. CDN

最近更新/作成されたページ