コンテンツにスキップ

リバースプロキシ

リバースプロキシは、クライアントの入口としてリクエストを受け、背後のアプリケーションサーバーへ転送する構成である。


client
-> nginx
-> backend application

クライアントから見ると、接続先は nginx である。バックエンドアプリケーションは、nginx からのリクエストを受ける。

nginx を前段に置くと、TLS 終端、HTTP から HTTPS へのリダイレクト、静的ファイル配信、アクセス制御、ログ集約などを nginx 側に寄せられる。


proxy_pass は、リクエストを別のサーバーへ渡すディレクティブである。

location / {
proxy_pass http://127.0.0.1:3000;
}

この例では、nginx が受けたリクエストを同じホストの port 3000 で動くアプリケーションへ渡す。


バックエンドは、直接クライアントから接続されたわけではない。そのため、元のクライアント情報や scheme をヘッダーで渡すことが多い。

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;
ヘッダー 意味
Host クライアントが要求したホスト名
X-Real-IP nginx から見たクライアント IP
X-Forwarded-For 経由したプロキシを含むクライアント IP 情報
X-Forwarded-Proto クライアントから nginx までの scheme

バックエンドが URL 生成、ログ、アクセス制御を行う場合、これらのヘッダーの扱いが重要になる。


proxy_pass は、末尾の / や URI の有無でバックエンドへ渡すパスが変わる。

location /app/ {
proxy_pass http://127.0.0.1:3000/;
}

この形では、/app/users へのリクエストは、バックエンドへ /users として渡される。

location /app/ {
proxy_pass http://127.0.0.1:3000;
}

この形では、元の URI がそのまま渡される。/app/users はバックエンドでも /app/users として扱われる。

ここは nginx の設定で混乱しやすい点である。アプリケーションがどの base path で動く前提なのかを先に決める。


バックエンドを名前でまとめたい場合は、upstream を使う。

upstream app_backend {
server 127.0.0.1:3000;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://app_backend;
}
}

バックエンドが複数ある場合や、設定の見通しを良くしたい場合に使う。