設定を読む前に:TLS終端・Hostと転送ヘッダーの信頼・障害時の継続は別々に確認します。旧コードは比較用に保持し、直前の訂正と新しい隔離例を区別しています。
| この記事の要点 |
|
概要
リバースプロキシ (reverse proxy) とは、サーバ側に立ち、Web サーバ群 (バックエンド) の代理として外部からの要求を受け付ける中継サーバです。クライアントはリバースプロキシのアドレスへアクセスし、リバースプロキシが裏側のアプリケーションサーバへ要求を転送して、その応答を返します。利用者からは「1 台の Web サーバ」に見えますが、実際にはその後ろに複数のサーバが隠れていることが多く、これをバックエンド隠蔽と呼びます。親項目の 負荷分散・プロキシ・CDN を参照してください。
フォワードプロキシが「クライアントの代理」であるのに対し、リバースプロキシは「サーバの代理」です。立つ位置が逆 (reverse) なのでこの名があります。導入の要否は構成と目的によります。nginx・Apache HTTP Server・HAProxy、クラウドのロードバランサ (ALB 等) はいずれもリバースプロキシの一種です。
仕組み
外部からの要求はまずリバースプロキシに届きます。リバースプロキシは要求の内容 (ホスト名・パス・ヘッダ) を見て、どのバックエンドへ渡すかを決定し、自分が改めてバックエンドへ接続して応答を受け取り、クライアントへ返します。この中継点に各種機能を集約できるのが強みです。
- SSL/TLS 終端 (SSL 終端): HTTPS の暗号化・復号をリバースプロキシでまとめて処理する。入口の証明書管理を集約できるが、バックエンドへの平文通信が安全になるわけではない。再暗号化する場合はバックエンド証明書も管理する。詳細は HTTPS を参照。
- 負荷分散: 同じ役割のバックエンドを複数並べ、要求を振り分けて 1 台あたりの負荷を下げる。詳しくは ロードバランサ を参照。
- キャッシュ: 静的ファイルや変化の少ない応答を保存し、バックエンドに行かずに即座に返す。
- WAF / セキュリティ: WAFは別の機能・module・ルールが必要。バックエンド隠蔽だけでは認証や脆弱性対策にならず、直接到達をネットワークでも制限する。
- ルーティング: パスやホスト名ごとに別のバックエンド (API サーバ・静的配信・管理画面など) へ振り分ける。
クライアントの本来の IP はバックエンドからは「プロキシの IP」に見えてしまうため、元の IP は X-Forwarded-For ヘッダなどで引き継ぎます。具体的な設定は nginxリバースプロキシ設定 を参照してください。
設定・実用例
次の2ブロックは旧説明を保持した参考例です。証明書・Host制限・転送ヘッダーの信頼境界を揃えた完成設定ではありません。訂正後の隔離例は後の「入口の信頼境界を試す」に掲載します。
保存した旧例への注意:旧nginx例の訂正:proxy_pass http://127.0.0.1:3000 は平文で、別ホストへ置き換えるだけでは安全ではありません。$proxy_add_x_forwarded_for は外部の自己申告値も残します。$host は許可Hostの検証ではなく、$scheme はこのnginxへの接続方式です。この例を多段プロキシへそのままコピーしないでください。
server {
listen 443 ssl;
server_name www.example.com;
# SSL 終端 (証明書はここで一括管理)
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
# バックエンドへ転送
proxy_pass http://127.0.0.1:3000;
# クライアントの本来の情報を引き継ぐ
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;
}
}
Apache の場合は mod_proxy を用い、同様の転送を ProxyPass で記述します。
保存した旧例への注意:旧Apache例の訂正:ProxyPreserveHost On は受信Hostを保持する指定で、Hostの許可検査ではありません。ProxyPassの転送先は平文HTTPです。TLS終端だけで後段の通信や転送ヘッダーの信頼は確保されません。mod_ssl等と有効な証明書も必要で、Apache実機は今回未検証です。
# Apache (mod_proxy / mod_proxy_http)
<VirtualHost *:443>
ServerName www.example.com
SSLEngine on
SSLCertificateFile /etc/ssl/example.crt
SSLCertificateKeyFile /etc/ssl/example.key
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>
主な用途
- SSL 終端の集約: 証明書管理と暗号処理を 1 か所にまとめ、バックエンドを単純化する。
- 負荷分散: 複数のアプリサーバへ要求を分散する。停止時の継続には検知・残存容量・入口や共有データの冗長化も必要。
- バックエンド隠蔽: 公開窓口を集約する。ただし直通経路や応答の情報漏れは別途対策し、隠すだけで安全とは判定しない。
- キャッシュ・圧縮: 静的応答をキャッシュし、gzip 圧縮などをまとめて行ってバックエンドを軽くする。
- パスベースルーティング:
/apiはアプリ、/staticは静的配信、というように振り分ける。
主なリバースプロキシ実装の比較
| 実装 | 特徴 | 得意分野 |
|---|---|---|
| nginx | 軽量・高同時接続・設定が簡潔 | 静的配信 + リバプロ + L7 LB |
| Apache (mod_proxy) | 機能豊富・モジュール拡張が容易 | 既存 Apache 資産との統合 |
| HAProxy | 高性能な L4/L7 ロードバランサ | 大規模な負荷分散・TCP 中継 |
| クラウド LB (ALB 等) | マネージドで自動スケール | クラウド上のスケーラブル構成 |
注意点
- クライアント IP の引き継ぎ漏れ:
X-Forwarded-Forを設定しないと、バックエンドのアクセスログがすべてプロキシの IP になる。アプリ側も信頼するヘッダを正しく設定する必要がある。 - 単一障害点: 全要求が通る要のため、リバースプロキシ自体を冗長化しないと全体が止まる。
- X-Forwarded-For の偽装: 外部から直接届く環境では
X-Forwarded-Forをクライアントが詐称できる。信頼できるプロキシの値だけ採用する設計にする。 - SSL 終端後の内部通信: プロキシ〜バックエンド間が平文だと、内部ネットワークを盗聴されると危険。ゾーンによっては内部も TLS 化する。
- タイムアウトとバッファ: 長時間処理やストリーミングでは
proxy_read_timeoutやバッファ設定を調整しないと途切れる。
入口の信頼境界を試す
次はloopbackだけで動かすHTTP学習例です。Internet公開用HTTPS設定ではありません。未知Hostはdefault_serverで400にし、許可したHostだけをアプリへ渡します。server_nameを1つ書くだけでは未知Hostの拒否になりません。Hostのポートを含める必要があるアプリでは、公開URLの設計も確認します。
# http context; isolated HTTP laboratory, not an Internet-facing TLS server.
upstream lab_app {
server 127.0.0.1:18081;
}
server {
listen 127.0.0.1:18080 default_server;
server_name _;
return 400;
}
server {
listen 127.0.0.1:18080;
server_name app.example.test;
location /api/ {
proxy_pass http://lab_app;
proxy_http_version 1.1;
proxy_set_header Host app.example.test;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host app.example.test;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Prefix "";
proxy_set_header Forwarded "";
proxy_connect_timeout 1s;
proxy_read_timeout 2s;
proxy_next_upstream off;
}
location / { return 404; }
}
IPだけでなくX-Forwarded-Host / Port / Prefixの偽装も考慮します。このHTTP検体はHostを固定し、Portを実際の入口、Protoを接続方式から生成し、PrefixとForwardedは破棄します。アプリもこの受渡し規約だけを採用してください。前段TLS終端・公開ポート・path変換が異なる構成で、同じ値を無条件に設定しません。
この一段入口ではX-Forwarded-Forを$remote_addrで上書きし、競合するForwardedを削除します。アプリ側もこの入口だけを信頼し、直接アクセスを拒否する設計が必要です。ヘッダーの値そのものは認証ではありません。X-Real-IPとX-Forwarded-Protoも、どの層が生成するかを決めます。
前段にCDN/LBがある場合、この例の$remote_addrは前段IP、$schemeは前段からnginxまでの方式になります。外部のX-Forwarded-Protoを無条件に採用せず、前段の送信元を到達制限した専用入口と値の検証を設計します。real_ipを使うならset_real_ip_fromに実際に信頼する中継元だけを指定し、real_ip_recursiveとアプリ側のtrusted proxiesを整合させます。0.0.0.0/0を信頼先にしません。
TLSを終端した後の選択
同じホスト内のloopback HTTPでも他プロセスからの到達を別途考えます。別ホスト・共有ネットワークへ運ぶ場合は到達制限とTLS、必要なら相互TLSを検討します。後段HTTPSのテンプレートは次のとおりです。DNS・CA・証明書を実環境に合わせる必要があり、隔離HTTP試験ではTLSを検証していません。
# location context, deployment template, NOT executed by the HTTP fixture.
# Supply actual DNS, CA chain and a backend certificate for backend.example.test.
proxy_pass https://backend.example.test;
proxy_ssl_server_name on;
proxy_ssl_name backend.example.test;
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/nginx/trust/backend-ca.pem;
proxy_ssl_verify_depth 2;
proxy_set_header Host backend.example.test;
proxy_next_upstream off;
https://を指定するだけでは十分ではありません。nginxのproxy_ssl_verifyは既定でoffです。SNI・検証名・信頼するCAを明示し、証明書不一致時に検証を無効化して回避しません。キャッシュやWAFも入口を置くだけで有効になるわけではありません。
公式資料と検証範囲
2026年10月26日確認:nginxの転送・URI・ヘッダー・TLS検証・タイムアウトと再送、upstreamの失敗判定とbackup、受動/能動監視、商用health_check module、Hostとdefault server、信頼する中継元、reloadとworker交代、ApacheのHost保持。
新しいHTTP例はPC上の外部ネットワークなし・loopbackの専用nginxで検査するためのものです。公開TLS・実CDN・Apache・NGINX Plus・実アプリの認証や本番の無停止性は検証対象外です。設定・証明書・導入版・module・到達制限が異なる環境へ、試験結果をそのまま適用しないでください。
関連リンク
子ページはありません
- フォワードプロキシ
- リバースプロキシ
- ロードバランサ
- nginxリバースプロキシ設定
- HAProxy
- CDN
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09