リバースプロキシは、クライアントとWebサーバーの間に置き、リクエストを受け取って背後のサーバー群へ転送する中継サーバーです。同じ「プロキシ」でもフォワードプロキシとは代理する対象が逆で、負荷分散・SSL/TLS終端・キャッシュ・IP秘匿といった役割を1台に集約できます。この記事では、リクエストの流れとフォワードプロキシとの違い、担う4つの機能、Dockerとnginxで実際に動かすまでの設定と確認手順、そしてロードバランサーやAPIゲートウェイとの使い分け・採用しない判断までを、実装者の視点で整理します。設定例はnginx 1.30系(2026年9月時点のstable)で確認できる書き方に揃えました。
まとめ:リバースプロキシの役割と導入判断の要点
リバースプロキシは、公開サーバーの手前に立ち、受け取ったHTTP/HTTPSリクエストを内部のアプリケーションサーバーへ振り分ける役割を担います。クライアントから見える窓口を1つにまとめ、その裏で複数サーバーへの分散、証明書の一元管理、静的コンテンツのキャッシュ、内部IPの秘匿をまとめて処理できる点が導入の動機になります。
フォワードプロキシが「クライアント側の代理」であるのに対し、リバースプロキシは「サーバー側の代理」です。この一点を押さえると、社内からの外部アクセス制御はフォワード、外部からの受け口の集約はリバース、と用途が明確に分かれます。
実装ではnginxやApache、HAProxy、EnvoyといったソフトウェアやAWS ALBなどのマネージドサービスが選択肢になります。Windows Server上で組む場合は、IISにApplication Request Routingを追加する構成も候補の一つ。HAProxyをリバースプロキシ兼ロードバランサーとして使う際の仕組みと設定は、HAProxyとは?L4/L7ロードバランサーの仕組みと設定・nginxとの違いを実装目線で解説で扱っています。単一ドメインの受け口統一とSSL終端だけならリバースプロキシ1台で足り、L7の細かなルーティングや認証・レート制限まで求めるならAPIゲートウェイ、L4を含む大規模分散ならロードバランサーへ広げる、という順で判断すると過剰投資を避けられます。
先に1点、設定を書き写す前に確認したい変更があります。nginxの変更履歴によると2026年3月24日リリースの1.29.7で、proxy_http_version の既定値が1.1になり、upstreamの keepalive も既定で有効になりました。ネット上に残る「必ず1.1を明示する」という手順は、この版以降では不要な記述になっています。可用性を織り込んだ本番構成を外部と組む場合は、AWS/GCP/Azureのインフラ構築支援で前段の冗長化を含む設計から相談できます。
リバースプロキシの動作原理とフォワードプロキシとの根本的な違い
「プロキシ」は代理を意味し、通信を誰かの代わりに中継する仕組みを指します。違いは、その代理が守る相手がクライアント側かサーバー側かにあります。まず押さえるべきはリクエストの流れです。
クライアントから背後のアプリサーバーへリクエストを転送する流れ
ユーザーのブラウザは、公開ドメイン(例:example.com)へアクセスすると、名前解決の結果としてリバースプロキシのIPアドレスに到達します。ブラウザはその先に何台のサーバーがあるかを知りません。
リバースプロキシはリクエストのHostヘッダやパスを見て、あらかじめ定義したルールに従い背後のアプリケーションサーバー(例:127.0.0.1:8080)へ転送します。応答を受け取ったら、それをクライアントへ返します。この間、クライアントとの接続はプロキシが終端し、背後サーバーとは別の接続を張り直すため、通信は前段と後段の2区間に分かれる構造です。この分離があるからこそ、後段の構成を自由に組み替えられます。
フォワードプロキシとリバースプロキシの設置場所と代理対象の違い
フォワードプロキシは社内ネットワークなどクライアント側に置き、利用者の代わりに外部サイトへアクセスします。守るのは発信元であるクライアントで、外部から見えるのはプロキシのIPになります。企業のWebフィルタリングや社外接続の記録がこの用途です。実装ソフトとしてはSquidが広く使われており、squid.confでのアクセス制御設計を別記事で整理しています。フォワードプロキシ側の詳細はプロキシサーバーとは何かを整理した解説記事で扱っているため、社内アクセス制御の観点はそちらを参照してください。
リバースプロキシは公開サーバー側に置き、サービス提供者の代わりにリクエストを受けます。守るのは背後のサーバー群で、外部から内部構成が見えません。両者を1枚の表で対比します。
| 観点 | フォワードプロキシ | リバースプロキシ |
|---|---|---|
| 設置場所 | クライアント側(社内LAN等) | サーバー側(公開側) |
| 代理する対象 | 利用者(発信元) | サービス提供者(受信側) |
| 隠す情報 | クライアントのIP | 背後サーバーの構成・IP |
| 代表的な用途 | 社外アクセス制御・記録 | 負荷分散・SSL終端・受け口集約 |
| クライアントの認識 | プロキシ経由を設定で認識 | 直接サーバーに見え意識しない |
設定の観点でも差が出ます。フォワードプロキシは利用者側でプロキシ設定を行う必要があり、リバースプロキシは利用者側の設定が要りません。窓口のドメインを引けば透過的に経由する仕組みです。
リバースプロキシが担う負荷分散・SSL終端・キャッシュ・秘匿の4機能
リバースプロキシを入れる実利は、複数の機能を前段1か所に集約できる点にあります。ここでは実務で効きやすい順に4つを扱います。すべてを同時に使う必要はなく、要件に応じて取捨選択する前提です。
複数のアプリサーバーへの負荷分散とヘルスチェックによる可用性確保
受けたリクエストを複数のアプリケーションサーバーへ振り分けると、1台あたりの処理量が下がり、水平スケールが可能になります。振り分け方式はラウンドロビン、最少接続数、IPハッシュなどが基本で、nginxなら upstream ブロックで定義します。
ここで実装前に押さえたい制約があります。nginx公式のupstreamモジュールのドキュメントによると、周期的にバックエンドを叩くアクティブな health_check は商用サブスクリプションの機能です。OSS版で使えるのは、転送に失敗した回数を数えて一時的に振り分け対象から外すパッシブ方式で、既定値は失敗1回・除外時間10秒(max_fails=1 fail_timeout=10s)となっています。「nginxでヘルスチェックを設定する」と書かれた記事の多くはこのパッシブ方式を指しており、無応答を能動的に検知したい要件なら商用版か別の専用機が必要になります。振り分けアルゴリズムや冗長化の設計を突き詰める段階では、専用機であるロードバランサーの仕組みと振り分け方式を実装目線で解説した記事で扱う内容と重なる領域です。役割の境界は後半の判断章で整理します。
SSL/TLS終端による証明書の一元管理と後段通信の平文化の判断
クライアントとのHTTPS接続をリバースプロキシで終端すると、TLSの復号を前段に集約できます。証明書の配置・更新をプロキシ1か所で済ませられるため、背後にアプリケーションサーバーが10台あっても証明書を10か所に配る手間が消えます。
終端後、後段への通信は平文HTTPにするか、内部でも再暗号化するかを選びます。同一ホスト内や閉じた内部ネットワークなら平文で負荷を下げ、ゼロトラスト方針なら内部も暗号化する、という判断の分かれ目です。証明書の有効期間も設計に影響します。Let’s EncryptのFAQでは既定の証明書が90日間で、60日ごとの更新を推奨すると案内されています。加えて、2025年2月20日に最初の1枚が発行された短期証明書をオプトインで選ぶと有効期間は6日間になり、更新の推奨間隔は3日ごとまで縮まる設定です。更新の失敗がサービス断に直結する頻度になるため、自動更新の仕組みを前段1か所へまとめられる利点は以前より効きます。
静的コンテンツのキャッシュと圧縮による背後サーバーの負荷削減効果
画像やCSS、JavaScriptなど更新頻度の低いレスポンスをリバースプロキシでキャッシュすると、背後のアプリケーションサーバーへ届く前に応答を返せます。動的処理を走らせずに済むぶん、サーバーのCPU負荷と応答時間を下げられます。
gzipやBrotliによる圧縮も前段でまとめて処理でき、転送量の削減につながります。キャッシュはヒットすれば効果が大きい一方、更新の反映遅延という副作用を伴うため、キャッシュ対象と保持時間(Cache-Control)の設計が実務の勘所になります。
背後サーバーのIP秘匿とWAF連携による受け口のセキュリティ強化
背後サーバーのIPアドレスやポート構成が外部から見えないため、攻撃者が直接サーバーを狙う経路を減らせます。公開する接点をプロキシ1台に絞ることで、監視やアクセス制御の対象も一元化できます。
前段にWAF(Web Application Firewall)を組み合わせると、SQLインジェクションや不正パスへのアクセスを受け口で遮断できます。受け口を1か所にまとめる設計は、ログ集約とインシデント調査の面でも運用を軽くします。ただし、この1台が単一障害点になり得る点は、後述の冗長化で補う前提です。
nginxをインストールしてリバースプロキシを動かすまでの手順
ここからは手を動かす章です。リバースプロキシの代表的な実装であるnginxを使い、検証環境を立てて設定を書き、curlで転送とヘッダの受け渡しを確認するところまで通します。設定ファイルの記述量は少なく、最小構成なら十数行で動きます。
Dockerで検証環境を用意してnginxの設定ファイルを置く手順
本番サーバーを触る前に、手元で振り分けの挙動を見られる環境を作ります。nginxの公開ダウンロードページでは2026年9月時点でstableが1.30.4系、mainlineが1.31.5系と案内されているため、コンテナイメージもstable系のタグを指定しました。バックエンドには受け取ったリクエストヘッダをそのまま応答に含めるコンテナを2台並べ、どちらへ振られたかとヘッダが渡っているかを目で確認できる形にします。
# compose.yaml — nginx(stable系)1台とバックエンド2台の検証環境
services:
proxy:
image: nginx:1.30-alpine
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- app1
- app2
app1:
image: traefik/whoami
app2:
image: traefik/whoami
同じディレクトリに nginx.conf を置き、コンテナ内の既定の設定ディレクトリへ読み取り専用でマウントする形にしました。設定を書き換えたら docker compose exec proxy nginx -s reload で反映でき、コンテナを作り直す必要はありません。
proxy_passとX-Forwarded系ヘッダを渡す最小のserver設定
公開ポートで受けたリクエストを、背後のアプリへ転送する最小構成を書きます。server ブロックで listen と server_name を宣言し、その内側の location ブロックですべてのパスを受ける形です。転送先は proxy_pass にhttpスキームでバックエンドを指定します。nginx公式のproxyモジュールのドキュメントによると proxy_read_timeout と proxy_connect_timeout の既定値はいずれも60秒、proxy_buffering の既定は有効です。
# nginx.conf — 8080で受けてapp1・app2へ振り分ける最小構成
upstream backend {
least_conn;
server app1:80 max_fails=1 fail_timeout=10s;
server app2:80 max_fails=1 fail_timeout=10s;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://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_connect_timeout 5s;
proxy_read_timeout 60s;
}
}
ここでの勘所は proxy_set_header です。プロキシが接続を張り直す構造上、これを省くと背後のアプリには送信元がすべてプロキシのIPに見え、本来のクライアントIPやアクセスプロトコルを取得できません。公式ドキュメントの既定値は Host $proxy_host であり、転送先のホスト名に書き換わる挙動です。元のホスト名を保つには Host $host を明示する必要があります。X-Real-IP と X-Forwarded-For で発信元IPを、X-Forwarded-Proto で元のプロトコルを渡し、アプリ側でこれらを信頼する設定にして初めて、正しいログとリダイレクト判定が成立します。
curlで転送とX-Forwarded-Forの受け渡しを確認する手順
設定を書いたら、必ず転送の実物を確認します。バックエンドが受け取ったヘッダを応答に含めるため、curlの結果を読めばヘッダが渡っているかが判別できる形です。2回叩いてバックエンドのホスト名が入れ替われば、振り分けも効いていると読めます。
$ docker compose up -d
$ curl -s http://localhost:8080/
# 出力例(バックエンドが受け取ったヘッダがそのまま返る)
Hostname: 3f9c1a2b4d5e
X-Forwarded-For: 172.18.0.1
X-Forwarded-Proto: http
X-Real-Ip: 172.18.0.1
$ curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8080/
200
$ docker compose exec proxy nginx -t # 設定の文法確認
$ docker compose logs proxy | tail -5 # 転送先の記録を見る
ここで X-Forwarded-For が空だった場合は proxy_set_header の記述漏れ、502が返る場合は proxy_pass の宛先名かバックエンドの起動状態を疑います。504が返るときはバックエンドの処理時間が既定の60秒を超えているサインなので、次章のタイムアウト調整へ進んでください。
nginx 1.29.7で変わったproxyの既定値と設定の書き直し方
リバースプロキシの設定例は、ネット上に何年も前の記述が残っています。2026年に入ってから既定値が変わったため、そのまま写すと不要な行が混ざる状態です。ここでは版差のある3点を、公式ドキュメントの記述に当てて整理します。
proxy_http_versionとkeepaliveの既定が変わった影響
変更履歴によると1.29.7では、upstreamの keepalive が既定で有効になり、proxyモジュールも既定でkeepaliveに対応し、proxy_http_version の既定値が1.1へ、Connection プロキシヘッダは既定で送らない挙動へ変わりました。公式のupstreamモジュールのドキュメントでも keepalive の既定は32接続と記載されています。
実務への影響は2つあります。第一に、従来の定番だった proxy_http_version 1.1; と proxy_set_header Connection ""; の2行は、1.29.7以降のnginxでは書かなくても同じ挙動になります。第二に、既存の設定にこの2行が残っていても害はないため、慌てて消す必要はありません。判断としては、新規に書く設定では省き、古い設定を読むときは「この2行は版差の名残」と理解しておけば足ります。ただし1.29.7より前の版が動いている環境では依然として必要なので、nginx -v で版を確かめてから省くかどうかを決めてください。
タイムアウト・バッファリング・WebSocket転送の調整ポイント
既定設定のまま本番に出すと、応答の遅いAPIで504 Gateway Timeoutが出ることがあります。proxy_read_timeout を処理時間に合わせて延ばし、大きなレスポンスでは proxy_buffering の挙動も確認しておきたいところです。バッファリングが有効なままだと、進捗を逐次返すストリーミング応答がまとめて届く形になるため、そうした用途の location では明示的に無効化します。
チャットや通知などWebSocketを使うアプリを背後に置く場合は、Upgrade と Connection ヘッダを明示的に転送しないと接続が確立しません。nginx公式のWebSocketプロキシのドキュメントでは、これらがホップバイホップヘッダであるため明示的に設定する必要があると説明され、map ブロックでUpgrade要求の有無に応じてConnectionの値を切り替える例が示されています。この転送漏れは、リバースプロキシ導入時に最も踏みやすい失敗の一つです。
# WebSocketを通す設定(1.29.7以降はproxy_http_versionの明示が不要)
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
location /chat/ {
proxy_pass http://backend;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s; # 無通信60秒で切れる既定を延ばす
}
}
}
X-Forwarded-ForとForwardedヘッダのどちらで受けるかの判断
発信元IPを後段へ渡すヘッダには2系統あります。MDNのX-Forwarded-Forの解説では、これがデファクトの標準ヘッダであり、標準化された代替が Forwarded であると位置づけられています。その Forwarded を定義しているのがIETFのRFC 7239で、for・by・proto・hostのパラメータを1つのヘッダにまとめる書式です。実装の対応状況は依然としてX-Forwarded系が広いため、新規に組む前段でも当面はX-Forwarded系を主に据える判断が現実的でしょう。
多段になる構成では、受け取った値をどこまで信じるかの設計が要ります。前段にCDNやクラウドのロードバランサーがあると、アプリが見る接続元は常にその前段のIPです。nginxで実クライアントIPへ戻すには realip モジュールを使いますが、公式ドキュメントにあるとおりこのモジュールは既定でビルドされず、--with-http_realip_module を指定した版が必要です。real_ip_header の既定は X-Real-IP、real_ip_recursive の既定は無効で、無効のままだとヘッダの最後のアドレスが採用されます。
# 前段にALBやCDNがある場合に実クライアントIPへ戻す(realipモジュール)
set_real_ip_from 10.0.0.0/16; # 信頼する前段のレンジだけを列挙する
real_ip_header X-Forwarded-For;
real_ip_recursive on; # 末尾から遡り信頼外の最初のIPを採用
信頼するレンジを絞らずに set_real_ip_from を広く書くと、外部から偽装したX-Forwarded-Forを信じてしまい、IP制限や監査ログの前提が崩れます。前段が自社管理のプロキシやマネージドLBのレンジに限られることを確認したうえで列挙してください。
ロードバランサー・APIゲートウェイとの使い分けと採用判断の基準
リバースプロキシは負荷分散もルーティングもこなすため、ロードバランサーやAPIゲートウェイと機能が重なります。境界を役割で整理し、どこまでをリバースプロキシで担うかの判断基準を示します。
ロードバランサーとの機能の重なりとL4/L7での役割分担の境界
ロードバランサーは「複数サーバーへの振り分け」に特化した装置で、L4(TCP/UDP)レベルの分散を含めて高スループットで捌くことに強みがあります。リバースプロキシはL7(HTTP)で内容を見た振り分けやSSL終端、キャッシュまで担う点が違いです。
小〜中規模で「HTTPの受け口統一+数台への分散」が要件なら、nginx1台がリバースプロキシ兼ロードバランサーを兼ねられます。トラフィックが増え、L4分散や専用機の可用性が要る段階で専用のロードバランサーへ切り出すのが過剰投資を避ける定石です。両者の内部の仕組みの違いはロードバランサーの種類と振り分け方式の記事で詳しく比較しています。
APIゲートウェイを選ぶべき場面とリバースプロキシとの機能差
APIゲートウェイは、リバースプロキシの転送機能を土台にしつつ、認証・認可、レート制限、APIキー管理、リクエスト変換といったAPI運用に特化した機能を上乗せした製品です。マイクロサービスの前段で複数APIを束ね、共通の認証やスロットリングをかけたい場合はこちらが向きます。
単にWebサイトの受け口を集約してSSL終端したいだけなら、APIゲートウェイは過剰です。境界と選定基準はAPIゲートウェイとリバースプロキシ/サービスメッシュの違いを解説した記事で判断材料を整理しています。認証やレート制限が要件に入った時点でAPIゲートウェイを検討する、という線引きが実務的です。
リバースプロキシを単段で導入しない方がよい場面と冗長化の必要性
すべての構成に前段プロキシが要るわけではありません。静的サイトを1台で配信するだけ、あるいはCDNが既にSSL終端と負荷分散を担っている構成では、自前のリバースプロキシは運用対象を増やすだけで見合いません。まず要件を数えることを勧めます。
導入する場合も、単段で組むと前段が単一障害点になります。プロキシを1台だけ立て、その裏でアプリを冗長化しても、プロキシが落ちれば全滅します。本番では前段自体を2台以上で冗長化するか、マネージドサービスに寄せる設計が前提です。要件が「受け口統一とSSL終端」に収まるうちは、リバースプロキシ1系統で始め、認証・大規模分散が必要になった段階で専用製品へ広げるのが堅実です。
よくある質問
導入検討時に問い合わせの多い論点を、実装の判断基準とあわせて5つ挙げます。
リバースプロキシとロードバランサーは何が違いますか?
リバースプロキシはL7で内容を見た転送やSSL終端・キャッシュまで担う汎用の中継、ロードバランサーはL4を含む振り分けに特化した専用機、という役割の違いです。小規模ではnginx1台が両方を兼ねられ、L4分散や高可用が要る規模で専用のロードバランサーへ切り出します。機能が重なるため、要件の規模で使い分けるのが実務的な判断になります。
フォワードプロキシとリバースプロキシはどちらを使うべきですか?
目的で決まります。社内から外部への接続を制御・記録したいならフォワードプロキシ、外部からの受け口を集約して負荷分散やSSL終端を行いたいならリバースプロキシです。守る対象がクライアント側かサーバー側かで用途は明確に分かれ、両方を同時に使う構成もあります。
nginxでリバースプロキシを組むと処理は遅くなりませんか?
1区間の中継が挟まるぶんのわずかな遅延は生じますが、キャッシュや圧縮、SSL終端の集約による効果がそれを上回る場面が多くあります。1.29.7以降は背後への接続がkeepaliveで再利用される既定になったため、接続確立のコストも下がりました。proxy_read_timeout やバッファリングを要件に合わせて調整すれば、体感の遅延はほぼ問題になりません。
リバースプロキシはセキュリティ対策として有効ですか?
背後サーバーのIPと構成を隠し、公開接点を1か所に絞れるため、直接攻撃の経路を減らす効果があります。前段にWAFを組み合わせれば不正リクエストを受け口で遮断できます。ただしプロキシ自体が攻撃対象になるため、脆弱性対応と冗長化を怠らないことが前提です。X-Forwarded-Forを信じる範囲を絞る設定も併せて必要になります。
クラウドのロードバランサーがあればリバースプロキシは不要ですか?
AWS ALBなどのL7ロードバランサーはリバースプロキシに近い機能を持ち、SSL終端やパスベースのルーティングを担えます。AWS公式のX-Forwardedヘッダの解説にあるとおり、ALB自身がX-Forwarded-ForやX-Forwarded-Protoを付けて後段へ渡すため、発信元の判別も成立します。要件がそれで収まるなら自前のプロキシは不要でしょう。細かなヘッダ書き換えや独自のキャッシュ制御など、マネージド側で表現しきれない要件がある場合に自前のリバースプロキシを併用します。
関連記事
- ロードバランサーとは?仕組み・種類・振り分け方式を実装目線で解説【2026年版】:リバースプロキシの負荷分散機能と役割が重なる専用機。振り分けアルゴリズムと冗長化設計を深掘りする際に読み合わせると使い分けが明確になります
- APIゲートウェイとは?役割・機能とリバースプロキシ/サービスメッシュとの違い・導入判断を解説:認証・レート制限までリバースプロキシに上乗せする製品。API運用が要件に入った場面の選定基準を扱います
- プロキシサーバーとは?仕組み・役割と種類、VPNとの違いをわかりやすく整理:フォワードプロキシ側の詳細と、VPNとの違い。クライアント側の代理の観点を補完します
- HAProxyとは?L4/L7ロードバランサーの仕組みと設定・nginxとの違いを実装目線で解説:同じ前段をHAProxyで組む場合の設定と、nginxとの得意分野の違いを比較できます
- IISでApplication Request Routingを使うリバースプロキシ構成の手順:Windows Server上で前段を組む場合の選択肢。nginx以外の実装を検討する際に読み合わせられます