#はじめに
「Webサーバーの前に別のサーバーを置く」——一見すると無駄に思えますが、これがリバースプロキシです。
リバースプロキシは、クライアントとWebサーバーの間に位置し、リクエストを中継するサーバーです。セキュリティ、パフォーマンス、柔軟性を向上させる重要なインフラストラクチャコンポーネントです。
この記事を読むと、以下のことができるようになります:
- リバースプロキシの役割を理解できる
- フォワードプロキシとの違いがわかる
- 基本的なnginx設定ができる
#リバースプロキシとは
リバースプロキシとは、クライアントからのリクエストを受け取り、バックエンドサーバーに転送するサーバーです。
[クライアント] → [リバースプロキシ] → [Webサーバー]
↓
クライアントからは
1台のサーバーに見える
クライアントはリバースプロキシとだけ通信し、背後にあるサーバーの存在を意識しません。
#フォワードプロキシとの違い
| フォワードプロキシ | リバースプロキシ | |
|---|---|---|
| 位置 | クライアント側 | サーバー側 |
| 保護対象 | クライアント | サーバー |
| 用途 | アクセス制御、匿名化 | 負荷分散、セキュリティ |
| 設定者 | クライアント | サーバー管理者 |
フォワードプロキシ:
[クライアント] → [プロキシ] → [インターネット] → [サーバー]
↑
クライアントを隠す
リバースプロキシ:
[クライアント] → [インターネット] → [プロキシ] → [サーバー]
↑
サーバーを隠す
#リバースプロキシの役割
#1. 負荷分散(ロードバランシング)
複数のバックエンドサーバーにリクエストを分散します。
┌→ [サーバー1]
[クライアント] → [プロキシ] ─→ [サーバー2]
└→ [サーバー3]
#2. SSLターミネーション
HTTPS接続をプロキシで終端し、バックエンドにはHTTPで転送します。
[クライアント] ──HTTPS──> [プロキシ] ──HTTP──> [バックエンド]
↑
SSL証明書を管理
メリット:
- バックエンドサーバーの負荷軽減
- 証明書管理の一元化
#3. キャッシュ
静的コンテンツをプロキシでキャッシュし、バックエンドへのリクエストを削減します。
1回目: [プロキシ] → [バックエンド]
↓
キャッシュ保存
2回目: [プロキシ] → キャッシュから返却(バックエンドに行かない)
#4. セキュリティ
バックエンドサーバーを外部から隠蔽し、攻撃対象を限定します。
- バックエンドのIPアドレスを隠す
- WAF(Web Application Firewall)機能
- DDoS対策
- リクエストのフィルタリング
#5. 圧縮
レスポンスをgzip/Brotliで圧縮します。
#6. URLの書き換え
リクエストURLを変換してバックエンドに転送します。
/api/v1/users → バックエンド: /users
/static/* → 静的ファイルサーバー
#nginxによる設定例
#基本設定
# /etc/nginx/nginx.conf
http {
server {
listen 80;
server_name 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;
}
}
}
#重要なヘッダー
| ヘッダー | 用途 |
|---|---|
Host | 元のホスト名を伝える |
X-Real-IP | クライアントの実IPアドレス |
X-Forwarded-For | プロキシチェーン全体のIPアドレス |
X-Forwarded-Proto | 元のプロトコル(http/https) |
#SSL設定
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
# ヘッダー設定...
}
}
# HTTPからHTTPSへリダイレクト
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
#静的ファイルの配信
server {
listen 80;
server_name example.com;
# 静的ファイルはnginxが直接配信
location /static/ {
root /var/www;
expires 1y;
add_header Cache-Control "public, immutable";
}
# APIリクエストはバックエンドに転送
location /api/ {
proxy_pass http://localhost:3000;
}
}
#負荷分散
upstream backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
server 192.168.1.12:3000;
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
#キャッシュ設定
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g;
server {
listen 80;
location / {
proxy_cache my_cache;
proxy_cache_valid 200 1h;
proxy_cache_valid 404 1m;
proxy_pass http://localhost:3000;
add_header X-Cache-Status $upstream_cache_status;
}
}
#その他のリバースプロキシ
#Caddy
自動HTTPS、シンプルな設定が特徴です。
# Caddyfile
example.com {
reverse_proxy localhost:3000
}
#Traefik
コンテナ環境向け、動的設定が得意です。
# docker-compose.yml
services:
traefik:
image: traefik:v2.9
command:
- "--providers.docker=true"
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
app:
image: myapp
labels:
- "traefik.http.routers.app.rule=Host(`example.com`)"
#HAProxy
高性能な負荷分散が特徴です。
# haproxy.cfg
frontend http_front
bind *:80
default_backend servers
backend servers
balance roundrobin
server server1 192.168.1.10:3000 check
server server2 192.168.1.11:3000 check
#クラウドサービスのリバースプロキシ
#AWS ALB(Application Load Balancer)
[クライアント] → [ALB] → [EC2/ECS/Lambda]
- パスベースルーティング
- ホストベースルーティング
- SSL終端
#Cloudflare
[クライアント] → [Cloudflare] → [オリジン]
- CDN機能
- DDoS対策
- WAF
#トラブルシューティング
#X-Forwarded-Forの信頼性
プロキシが複数ある場合、X-Forwarded-Forは以下のような形式になります。
X-Forwarded-For: クライアントIP, プロキシ1, プロキシ2
最初の値が必ずしも信頼できるとは限りません(クライアントが偽装可能)。
# 信頼できるプロキシを指定
set_real_ip_from 10.0.0.0/8;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
#WebSocket対応
location /ws/ {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
#タイムアウト設定
location / {
proxy_pass http://localhost:3000;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
#まとめ
- リバースプロキシはクライアントとサーバーの間に位置するサーバー
- 主な役割: 負荷分散、SSLターミネーション、キャッシュ、セキュリティ
- nginx: 最も広く使われるリバースプロキシ
- 重要なヘッダー:
X-Forwarded-For、X-Real-IP、X-Forwarded-Proto - クラウドサービス: ALB、Cloudflareなども同様の機能を提供
#次のステップ
リバースプロキシの基本を理解したところで、次はロードバランサーについてより詳しく学びましょう。複数サーバーへのリクエスト分散方式やヘルスチェックの仕組みを紹介します。