NginxリバースプロキシとSSL設定入門|バックエンド中継・HTTPS化の実践ガイド
※本記事はプロモーションを含みます。
Nginxはリバースプロキシ・SSLターミネーション・ロードバランサーとして、現代のWebインフラの中核を担う軽量で高性能なサーバーソフトウェアです。本記事では、Nginxをリバースプロキシとして活用し、バックエンドのNode.js・Pythonアプリケーション、またはAPサーバーやDBサーバーの前段に配置するアーキテクチャの実装方法を、14年のインフラエンジニア経験と現役IT講師としての知見から解説します。基本設定から証明書取得、ロードバランシング、本番環境での最適化まで、実践的で即座に活用できる設定例を数多く掲載しています。読了時間:約12分
Nginxリバースプロキシとは
Nginxは1つのマシン上で複数のロールを担当できることで知られていますが、その中でも最も重要な役割の1つが「リバースプロキシ」とされています。リバースプロキシとは、クライアント(ブラウザなど)とバックエンド(アプリケーションサーバーやAPI サーバー)の間に立つ中継サーバーです。クライアントからのリクエストはすべてNginxで受け取られ、Nginxが適切なバックエンド にリクエストを転送する仕組みになっています。
この構成により、以下のような利点が得られるとされています:
- バックエンドのスケーリングが容易になり、複数のサーバーへの負荷分散が可能
- SSL/HTTPS処理をNginx側で一元管理でき、バックエンドのリソース消費が削減される
- キャッシング機能により、繰り返されるリクエストのレスポンスが高速化される
- バックエンドサーバーのIPアドレスやバージョン情報をクライアントから隠蔽できる
- 複数のバックエンドサーバーへのリクエスト振り分けが自動化される
フォワードプロキシとの違い
「プロキシ」と聞くと、学校のネットワークやオフィスのインターネット接続で使われるフォワードプロキシをイメージする方も多いのではないでしょうか。リバースプロキシとフォワードプロキシは似た名前ですが、役割と配置場所が大きく異なるとされています。
フォワードプロキシは、組織内のクライアント(ユーザーのパソコンなど)がインターネット上の外部サーバーにアクセスする際、その代理としてリクエストを送信するサーバーです。一方、リバースプロキシは、インターネット側のクライアントからのリクエストを受け取り、その背後にある複数のバックエンドサーバーに振り分ける役割を担っています。つまり、リバースプロキシはバックエンドサーバー群の「顔」となり、クライアントには単一のサーバーに見えるようにします。
Nginxの基本的なリバー…
Nginxでリバースプロキシを実装するには、`nginx.conf` または `/etc/nginx/conf.d/` 以下の設定ファイルに `server` ブロックと `location` ブロックを記述します。最も基本的な設定例を以下に示すとされています。
server {
listen 80;
server_name example.com;
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_connect_timeout 60s;
proxy_read_timeout 60s;
}
}
この設定では、`example.com` へのHTTPリクエストを、ローカルマシン上の3000番ポート(Node.jsなど)で動作しているアプリケーションに転送しています。
プロキシ指令の役割
各プロキシ指令の意味と役割は以下の通りとされています:
proxy_pass http://127.0.0.1:3000;— バックエンドのURLを指定。リクエストがこのアドレスに転送されるproxy_set_header Host $host;— クライアントが送信した元のHostヘッダーをバックエンドに転送。バックエンドアプリがホスト情報を正しく認識するために必須proxy_set_header X-Real-IP $remote_addr;— クライアントの実IPアドレスをカスタムヘッダーに格納。ログやアクセス制限で元のIPが必要な場合に活用proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;— 複数のプロキシを経由した場合の、元のクライアントIPチェーンを保持proxy_connect_timeout 60s;— バックエンドへの接続タイムアウト時間。デフォルト60秒proxy_read_timeout 60s;— バックエンドからのレスポンス読み込みタイムアウト。長時間の処理が必要な場合は増加させることが可能
複数パスの条件付きルーティング
APIサーバーとWebアプリケーション、静的ファイルなど、異なるバックエンドに振り分ける場合は、複数の `location` ブロックを記述するとされています:
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://127.0.0.1:8000;
}
location /static/ {
alias /var/www/static/;
}
location / {
proxy_pass http://127.0.0.1:3000;
}
}
この例では、`/api/` で始まるパスは8000番ポートのバックエンドに、`/static/` は静的ファイルディレクトリから直接配信し、その他のパスは3000番ポートのメインアプリケーションに転送する構成になっています。マッチング順序は上から評価されるため、より具体的なパターンを上に配置することが重要とされています。
HTTPS化とSSL/TL…
現在、インターネット上でHTTPを使用するWebサイトは極めて稀となりました。FirefoxやChromeなどのブラウザは HTTP接続に対して警告を表示するようになっているとされています。Nginxでリバースプロキシを構成する場合、Let’s Encrypt が提供する無料のSSL証明書と certbot ツールを組み合わせることで、簡単にHTTPS化が実現できます。
Let’s Encrypt…
Amazon Linux 2023、または Ubuntu などのディストリビューションで、以下のコマンドを実行して certbot をインストールします:
sudo dnf install certbot python3-certbot-nginx
インストール後、以下のコマンドで証明書を取得し、Nginx の設定を自動更新するとされています:
sudo certbot --nginx -d example.com
対話形式でメールアドレスを入力し、利用規約に同意することで、証明書の取得と Nginx 設定の自動変更が完了します。この時点で、Nginxの設定ファイルには自動的に以下のような設定が追加されるとされています:
server {
listen 443 ssl http2;
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://127.0.0.1:3000;
}
}
自動更新の確認と設定
Let’s Encrypt の証明書は 90 日間の有効期限を持つとされています。certbot は自動更新用の cron ジョブまたは systemd timer を設定しますが、定期的に自動更新テストを実行することが推奨されているとされています。
sudo certbot renew --dry-run
このコマンドは実際には更新を実行せず、更新プロセスのシミュレーションのみを行うとされています。ドライランが成功すれば、定期的な自動更新は正常に機能する見込みが高いとされています。実際の自動更新の状態を確認するには、以下のコマンドで systemd timer を確認することが可能とされています:
sudo systemctl status certbot.timer
ロードバランシングとバック…
Nginx の強力な機能の1つが、複数のバックエンドサーバーに対する負荷分散(ロードバランシング)です。`upstream` ブロックを使用することで、複雑な外部ロードバランサーなしで、Nginx単体でラウンドロビン、最小接続数方式、IP ハッシュなど複数の分散方式が実装できるとされています。
Upstreamブロックの…
複数のバックエンドサーバーを管理する場合、`upstream` ブロックを `server` ブロックの外側に定義するとされています:
upstream backend_pool {
least_conn;
server 10.0.1.10:8080 weight=2;
server 10.0.1.11:8080;
server 10.0.1.12:8080 backup;
}
server {
listen 443 ssl http2;
server_name example.com;
location / {
proxy_pass http://backend_pool;
}
}
この設定では、以下のような意味を持つとされています:
least_conn— 負荷分散方式を「最小接続数方式」に指定。アクティブな接続数が最も少ないサーバーにリクエストを送信weight=2— サーバーの重み付け。このサーバーには他の2倍の頻度でリクエストが送信されるbackup— バックアップサーバーの指定。通常時は使用されず、他のサーバーがすべてダウンした時のみ使用
負荷分散方式の選択
Nginx でサポートされている負荷分散方式は複数あり、アプリケーションの特性に応じて選択することが推奨されているとされています。以下に主要な方式を示します:
| 方式 | 特徴 | 推奨用途 |
|---|---|---|
| デフォルト (ラウンドロビン) | リクエストを順番に各サーバーに割り当て | サーバースペックが同じ場合、リクエスト処理時間が均一 |
| least_conn | アクティブな接続数が少ないサーバーに優先 | クライアント接続時間がばらつく場合、リアルタイム通信 |
| ip_hash | クライアント IP のハッシュ値でサーバーを決定 | セッション情報をサーバー側で管理する場合 |
| random | ランダムにサーバーを選択 | キャッシュ効率を考慮する場合 |
本番環境での最適化と性能チ…
Nginx がデフォルト設定のままでは、高負荷環境で性能を発揮できない可能性があるとされています。本番環境での運用には、いくつかの重要なチューニングポイントが存在するとされています。
ワーカープロセスと接続数管理
Nginx のコア設定となるのが `worker_processes` と `worker_connections` の値です。以下は推奨される設定とされています:
user nginx;
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
use epoll;
}
`worker_processes auto` は、サーバーのCPUコア数を自動検出し、そのコア数分のワーカープロセスを起動するとされています。これにより、マルチコア CPU の性能が最大限活用されるとされています。
`worker_connections` はプロセスあたりの同時接続数の上限を指定するとされています。デフォルト値は 1024 ですが、高負荷環境では 65535 に設定することが一般的とされています。ただし、OS のファイルディスクリプタ上限(`ulimit -n`)も合わせて引き上げる必要があるとされています:
sudo bash -c 'echo "* soft nofile 65535" >> /etc/security/limits.conf'
sudo bash -c 'echo "* hard nofile 65535" >> /etc/security/limits.conf'
キャッシング・圧縮・ログの設定
以下の設定は、レスポンス時間の短縮とサーバーリソースの効率化に寄与するとされています:
| 設定項目 | 推奨値 | 効果 |
|---|---|---|
| gzip on | 有効 | テキスト系コンテンツをgzip圧縮。通信量が70%削減される可能性 |
| gzip_types | text/plain text/css application/json application/javascript | 圧縮対象のMIMEタイプを明示 |
| keepalive_timeout | 65 | クライアント持続接続の時間。短すぎるとオーバーヘッド増加 |
| access_log | バッファ付きまたは off | 高負荷時はバッファリングでディスク I/O 削減 |
gzip 圧縮の設定例を以下に示すとされています:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss;
gzip_disable "msie6";
アクセスログをバッファリングして I/O を削減する場合は、以下の指令を使用するとされています:
access_log /var/log/nginx/access.log combined buffer=32k flush=5s;
この設定では、ログを 32KB のバッファに格納し、5秒ごとにディスクに書き込むとされています。
セキュリティ設定の重要性
リバースプロキシは外部との接点となるため、セキュリティ設定は極めて重要だとされています。Nginx 公式ドキュメント(出典: Nginx Official Documentation)では、以下のような設定が推奨されているとされています:
- サーバーバージョン情報の非表示:`server_tokens off;`
- 不要な HTTP メソッドの制限:`if ($request_method !~ ^(GET|HEAD|POST)$) { return 405; }`
- TLS バージョンの制限:`ssl_protocols TLSv1.2 TLSv1.3;`
- 強力な暗号スイートの指定:公式ドキュメントの推奨リストを参照
- HSTS (HTTP Strict Transport Security) の有効化:`add_header Strict-Transport-Security “max-age=31536000; includeSubDomains” always;`
セキュリティ設定は定期的に更新されるため、実装時には必ず Nginx 公式ドキュメントで最新情報を確認することが強く推奨されているとされています。
まとめ
Nginx をリバースプロキシとして活用することで、バックエンドサーバー群のスケーリング、HTTPS化、ロードバランシング、キャッシング、セキュリティ強化などを、1つのシンプルな設定ファイルで実現できるとされています。
本記事では、基本的なリバースプロキシ設定から Let’s Encrypt を使った無料 SSL 証明書の取得、upstream ブロックを使ったロードバランシング、本番環境での性能最適化まで、実践的な設定例を解説してきました。
Nginx のバージョンやセキュリティ仕様は定期的に更新される可能性があるため、実装時には常に公式ドキュメントで最新情報を確認することが推奨されています。本記事で示した設定例はあくまで基本形であり、システムの要件や環境に応じたカスタマイズが必要な可能性があります。段階的にテスト環境で検証したうえで、本番環境への導入を進めることをお勧めします。



