◀ 2.

リバースプロキシとは SSL終端・負荷分散・バックエンド隠蔽 | ネットワーク入門

▶

設定を読む前に:TLS終端・Hostと転送ヘッダーの信頼・障害時の継続は別々に確認します。旧コードは比較用に保持し、直前の訂正と新しい隔離例を区別しています。

入口TLS、転送ヘッダー、後段通信を別々に確認するリバースプロキシの境界

この記事の要点
  • リバースプロキシは「サーバ側」に立つ代理サーバで、外部からの要求をいったん受け取り、後ろのバックエンドサーバへ振り分ける
  • クライアントから見ると 1 台のサーバに見えるが、実際には複数のバックエンドが裏に隠れている (バックエンド隠蔽)
  • TLS終端とバックエンド区間の通信保護は別。内部が平文HTTPなら、その区間の盗聴・改ざんへの対策が必要
  • 複数バックエンドへ要求を分散する負荷分散、応答のキャッシュ、WAF (Web アプリケーションファイアウォール) などの機能を集約できる
  • 代表的な実装は nginx と Apache HTTP Server。クラウドの ALB なども実体はリバースプロキシ

概要

リバースプロキシ (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・到達制限が異なる環境へ、試験結果をそのまま適用しないでください。

関連リンク

子ページ

子ページはありません

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

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