ウェブエンジニア問題集
第7章

プロキシ — リバース・フォワードの違いと開発環境での活用

17
この章の目次開く

Web開発をしていると「プロキシ」という言葉にさまざまな場面で出会います。本番環境ではNginxやCloudflareがリバースプロキシとして動き、開発環境ではNext.jsのrewritesやViteのproxyでCORSを回避し、デバッグではCharlesやmitmproxyで通信を覗きます。

この章では、プロキシの基本概念から実務での使いどころまでを整理します。

プロキシの前提になるIP、ポート、DNS、TLSの切り分けは、CS基礎のネットワーク章 で扱っています。リバースプロキシの設定がうまく動かないときは、ネットワークの切り分け と合わせて読むと原因を分けやすくなります。

学習者学習者

「プロキシ」って言葉はよく聞くけど、フォワードとリバースの違いがよく分からない。開発中に出てくるプロキシ設定とも関係あるの?


プロキシとは何か

プロキシ(Proxy)は「代理」という意味で、クライアントとサーバーの間に立って通信を中継するサーバーのことです。直接通信せず、間にプロキシを挟むことで、キャッシュ・セキュリティ・負荷分散などさまざまな機能を実現できます。

プロキシには大きく分けて フォワードプロキシリバースプロキシ の2種類があります。


「使う側」と「なる側」— プロキシ設定の2つの視点

プロキシの設定は、さまざまなレイヤーに登場します。しかし、すべてが同じことをしているわけではありません。大きく分けると 「プロキシを経由する設定」「プロキシとして動く設定」 の2種類があります。

視点やっていること設定場所の例
経由する(使う側)「このプロキシサーバーを通してリクエストを送れ」とクライアントに指示するHTTP_PROXY環境変数、axios proxyオプション、npm/git config
として動く(なる側)リクエストを受け取って、別のサーバーに転送する処理を自分が行うNginx proxy_pass、Vite server.proxyhttp-proxy-middleware

具体例で見る違い

axios の proxy オプション(使う側):

// axiosに「このプロキシ経由で送れ」と指示している
// axios自体はプロキシではない
const client = axios.create({
  proxy: { host: 'proxy.example.com', port: 8080 },
});
js

Vite の server.proxy(なる側):

// Viteの開発サーバー自体がプロキシとして動く
// ブラウザ → Vite → バックエンドAPI の中継役になる
export default defineConfig({
  server: {
    proxy: { '/api': { target: 'http://localhost:8080' } },
  },
});
ts

Nginx の proxy_pass(なる側):

# Nginx自体がプロキシとして動く
# クライアント → Nginx → アプリサーバー の中継役になる
location / {
    proxy_pass http://localhost:3000;
}
nginx

どれも「proxy」という名前が付いていますが、axiosは「経由先を指定している」だけで、ViteやNginxは「自分がプロキシになっている」という根本的な違いがあります。

レイヤーの全体像

実務ではこれらが組み合わさって動きます。

【本番環境の例】
ブラウザ → Cloudflare(なる側: CDN/WAF)→ Nginx(なる側: SSL終端/LB)→ Express

【開発環境の例】
ブラウザ → Vite dev server(なる側: /apiを転送)→ Express API

【企業ネットワークの例】
npm install → HTTP_PROXY環境変数(使う側)→ 社内プロキシ(なる側)→ npmレジストリ

フォワードプロキシ

分岐で悩んでいる男性のイラスト

フォワードプロキシは クライアント側 に設置され、クライアントの代わりにサーバーへリクエストを送ります。サーバーからはプロキシのIPアドレスしか見えないため、クライアントの身元を隠す効果があります。

主な用途

用途具体例
アクセス制御企業ネットワークで特定サイトへのアクセスを制限する
キャッシュ同じコンテンツへの繰り返しリクエストをプロキシが返す
匿名化クライアントのIPアドレスをサーバーに対して隠す
ログ・監査社内からの通信を記録してセキュリティ監査に使う

仕組み

1. クライアント → フォワードプロキシ: 「example.comにアクセスしたい」
2. フォワードプロキシ → example.com: 「プロキシのIPから」リクエスト送信
3. example.com → フォワードプロキシ: レスポンスを返す
4. フォワードプロキシ → クライアント: レスポンスを転送

企業のオフィスネットワークやVPNを使った接続では、フォワードプロキシが透過的に動いていることがあります。「社内ネットワークだと特定のサイトにアクセスできない」という状況は、多くの場合フォワードプロキシによるフィルタリングです。


リバースプロキシ

リバースプロキシは サーバー側 に設置され、クライアントからのリクエストを受け取って背後のアプリケーションサーバーに振り分けます。クライアントからはリバースプロキシしか見えず、背後のサーバー構成を隠蔽できます。

計画を立てている男性のイラスト

主な役割

役割説明
ロードバランシング複数のアプリサーバーにリクエストを分散する
SSL終端HTTPS通信の暗号化/復号をプロキシが一括で担当する
キャッシュ静的ファイルやAPIレスポンスをキャッシュして配信を高速化する
セキュリティアプリサーバーのIPアドレスや内部構成を隠す
圧縮レスポンスのgzip/brotli圧縮をプロキシ側で行う

実務でよく使われるリバースプロキシ

Nginx — Webサーバーでありプロキシサーバーでもある

学習者学習者

NginxってWebサーバーなの?プロキシサーバーなの?Apacheとは何が違うの?

Nginxは Webサーバーとリバースプロキシの両方の機能を持つ ソフトウェアです。「どっちなの?」ではなく「どっちもできる」が正解です。

Apacheとの違いを整理すると、こうなります。

項目ApacheNginx
生まれた目的Webサーバー(静的ファイル配信)Webサーバー + リバースプロキシ
プロキシ機能mod_proxyモジュールを後から追加最初から組み込み
処理モデルリクエストごとにプロセス/スレッド生成イベント駆動(少ないリソースで大量接続)
得意な場面.htaccessによる柔軟な設定大量の同時接続、リバースプロキシ

Apacheが「Webサーバーにプロキシ機能を後付けした」のに対して、Nginxは「最初からプロキシを前提に設計された」という違いがあります。そのため、現代のWebアプリではNginxをリバースプロキシとして使うのが主流になっています。

# /etc/nginx/conf.d/app.conf
server {
    listen 80;
    server_name api.example.com;
 
    # リバースプロキシとしての設定 — アプリサーバーに転送
    location / {
        proxy_pass http://localhost: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;
    }
 
    # Webサーバーとしての設定 — 静的ファイルを直接配信
    location /static/ {
        root /var/www;
        expires 30d;
    }
}
nginx

上の設定を見ると、/ へのリクエストは proxy_pass でアプリサーバーに転送(リバースプロキシの仕事)し、/static/ へのリクエストはファイルを直接返しています(Webサーバーの仕事)。1つのNginxが両方の役割を同時にこなしているわけです。

proxy_set_headerで付与しているX-Forwarded-ForX-Real-IPは、アプリサーバーが「本来のクライアントIPアドレス」を知るためのヘッダーです。04章で扱ったHTTPヘッダーの実践的な使い方です。

Nginxクイズに挑戦するリバースプロキシ・設定ファイル・ロードバランシングなど、Nginxの基礎知識をクイズで確認しよう

Cloudflare

Cloudflareはグローバルに分散したリバースプロキシ(CDN)です。DNS設定を変えるだけで導入でき、以下の機能を提供します。

  • DDoS防御: 大量のリクエストを世界中のエッジサーバーで吸収する
  • CDNキャッシュ: 静的アセットをユーザーに近いサーバーから配信する
  • SSL証明書: 無料のSSL証明書を自動発行・更新する
  • WAF(Web Application Firewall): SQLインジェクションやXSSなどの攻撃パターンをブロックする

AWSのALB / GCPのCloud Load Balancing

クラウド環境では、マネージドなロードバランサーがリバースプロキシの役割を果たします。複数のコンテナやインスタンスにリクエストを分散し、ヘルスチェックで異常なサーバーを自動的に除外します。


開発環境でのプロキシ

学習者学習者

開発中に fetch('/api/users') したらCORSエラーが出た。プロキシで解決できるって聞いたけど、どう設定するの?

開発中に最もよくプロキシを使うのは、CORS(Cross-Origin Resource Sharing)の回避 です。フロントエンドの開発サーバー(localhost:3000)からバックエンドAPI(localhost:8080)にリクエストを送ると、オリジンが異なるためブラウザにブロックされます。開発サーバーのプロキシ機能を使えば、同一オリジンからのリクエストに見せかけることができます。

Next.js の rewrites

Next.jsではnext.config.js(またはnext.config.ts)のrewritesでプロキシを設定できます。

// next.config.js
module.exports = {
  async rewrites() {
    return [
      {
        source: '/api/:path*',
        destination: 'http://localhost:8080/api/:path*',
      },
    ];
  },
};
js

ブラウザからは /api/users にアクセスしているように見えますが、裏では http://localhost:8080/api/users に転送されています。本番環境ではバックエンドが同一オリジンにある、またはCORSが適切に設定されていれば、この設定は不要になります。

Vite の proxy

Vite(React、Vue、Svelteなど)ではvite.config.tsserver.proxyで設定します。

// vite.config.ts
import { defineConfig } from 'vite';
 
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
      },
    },
  },
});
ts

changeOrigin: trueを指定すると、バックエンドに送るリクエストのHostヘッダーをターゲットのホスト名に書き換えます。バックエンドがHostヘッダーを検証している場合に必要です。

Create React App(webpack-dev-server)

CRA(webpack-dev-server)ではpackage.jsonproxyフィールドを追加するだけです。

{
  "proxy": "http://localhost:8080"
}
json

シンプルですが、パスごとの細かい制御が必要な場合はhttp-proxy-middlewaresetupProxy.jsを書きます。


HTTPクライアントのプロキシ設定

PCを使う女性のイラスト

Node.jsやブラウザ以外のHTTPクライアントからプロキシを経由する場面もあります。

環境変数による設定

多くのHTTPクライアントライブラリはHTTP_PROXY/HTTPS_PROXY環境変数を自動で認識します。

# 環境変数を設定
export HTTPS_PROXY=http://proxy.example.com:8080
 
# curlは自動で経由する
curl https://api.example.com/data
 
# wgetも同様
wget https://api.example.com/data
bash

axiosでのプロキシ設定

axiosではproxyオプションで明示的に設定できます。

import axios from 'axios';
 
const client = axios.create({
  proxy: {
    host: 'proxy.example.com',
    port: 8080,
    auth: {
      username: 'user',
      password: 'pass',
    },
  },
});
 
const response = await client.get('https://api.example.com/data');
js

Node.jsのfetchとプロキシ

Node.js組み込みのfetchは環境変数によるプロキシを自動で認識しません。プロキシを経由させたい場合はundiciProxyAgentを使います。

import { ProxyAgent } from 'undici';
 
const response = await fetch('https://api.example.com/data', {
  dispatcher: new ProxyAgent('http://proxy.example.com:8080'),
});
js

デバッグ用プロキシツール

PCで作業する女性のイラスト

HTTPプロキシを使って通信内容を可視化・改変できるツールがあります。APIの挙動を調査したり、レスポンスをモックしたりするのに便利です。

Charles Proxy

GUIベースのHTTPプロキシツールで、macOS/Windows/Linuxに対応しています。

機能説明
リクエスト/レスポンスの閲覧JSON・XML・画像などを見やすく表示する
ブレークポイント特定のリクエストを途中で止めて内容を編集できる
Map Remoteリクエストを別のサーバーに転送する
Map Localレスポンスをローカルファイルに差し替える
リライトヘッダーやボディを自動で書き換える
スロットリング回線速度を制限して低速ネットワークをシミュレーションする

HTTPS通信を覗くには、Charlesが生成するCA証明書をデバイスにインストールする必要があります。

mitmproxy

オープンソースのコマンドラインHTTPプロキシです。スクリプトによる自動化が得意です。

# インストール(macOS)
brew install mitmproxy
 
# 起動(デフォルトで8080ポートでリッスン)
mitmproxy
 
# Web UIで確認したい場合
mitmweb
bash

Pythonスクリプトでリクエスト/レスポンスを加工できるのが特徴です。

# addon.py — レスポンスにカスタムヘッダーを追加する例
from mitmproxy import http
 
def response(flow: http.HTTPFlow):
    flow.response.headers["X-Debug"] = "mitmproxy"
python
mitmproxy -s addon.py
bash

DevToolsとの使い分け

ツール用途
DevTools Networkブラウザからの通信を手軽に確認する(追加設定不要)
Charles / mitmproxyモバイルアプリの通信、レスポンスの改変、ブレークポイントなど高度なデバッグ
WiresharkTCP/UDPレベルのパケット解析(HTTP以外も含む)

ブラウザの通信だけを見るならDevToolsで十分です。モバイルアプリの通信や、レスポンスを改変してフロントエンドの挙動を検証したい場合に、Charles / mitmproxyの出番になります。


プロキシ関連のトラブルシューティング

学習者学習者

npm install が全然通らない…。プロキシが原因かもしれないけど、どこから調べればいいの?

よくあるトラブルと対処法です。

症状原因対処
ECONNREFUSEDプロキシサーバーに接続できないプロキシのホスト・ポートが正しいか確認する
UNABLE_TO_VERIFY_LEAF_SIGNATUREHTTPS通信でプロキシのCA証明書が信頼されていないCA証明書をインストールする、またはNode.jsのNODE_EXTRA_CA_CERTSに指定する
ローカルサーバーに繋がらないローカルへのリクエストもプロキシ経由になっているNO_PROXY=localhost,127.0.0.1を設定する
npm install が遅い/失敗するnpmがプロキシ設定を認識していないnpm config set proxyを設定する

まとめ

プロキシはクライアントとサーバーの間に立って通信を中継する仕組みです。フォワードプロキシはクライアント側に立ってアクセス制御や匿名化を行い、リバースプロキシはサーバー側に立って負荷分散やSSL終端を担当します。

開発環境では、CORSを回避するためにNext.jsのrewritesやViteのproxyを使うのが一般的です。企業のプロキシ環境ではHTTP_PROXY/HTTPS_PROXY環境変数の設定が必要になることを覚えておきましょう。

デバッグではDevToolsが基本ですが、モバイルアプリの通信やレスポンスの改変にはCharlesやmitmproxyが役立ちます。

ステップアップしている男性のイラスト

次の章では、認証と認可の仕組み — セッション、JWT、OAuth 2.0の基本を扱います。