Nginxリバースプロキシ入門|SSL対応の基本設定

Nginxリバースプロキシ入門|SSL対応の基本設定
Webサーバーの負荷分散やセキュリティ強化に必須のNginxリバースプロキシを、SSL/TLS対応を含めて完全にマスターしましょう。本記事では、ローカルネットワーク内のサービスを外部公開する際の実践的な設定手順を、具体的なコマンドと共に解説します。NginxのインストールからSSL証明書の取得、リバースプロキシの基本設定、さらには動的なルーティングやキャッシュ設定まで、実務で即戦力となる内容を網羅しています。
目次
- Nginxリバースプロキシの概要とメリット
- Nginxのインストールと基本設定
- SSL/TLS証明書の取得とNginxへの適用
- リバースプロキシの基本設定と動作確認
- 応用的なリバースプロキシ設定(負荷分散・キャッシュ)
- トラブルシューティングとよくある質問
- まとめと次のステップ
Nginxリバースプロキシの概要とメリット
Nginxリバースプロキシは、クライアントからのリクエストを受け取り、内部のサーバーに転送する役割を果たします。この技術を活用することで、以下のようなメリットを享受できます。
- セキュリティの向上:内部サーバーの直接公開を避け、攻撃対象を最小化
- 負荷分散:複数のバックエンドサーバーにリクエストを分散
- SSL/TLS終端:暗号化通信をNginxで処理し、バックエンドサーバーの負荷を軽減
- 静的コンテンツのキャッシュ:レスポンス速度を向上させる
- URLリライト:外部に公開するURLを柔軟に変更可能
特に、SSL/TLS対応は現代のWebサイトに必須の要素です。Nginxは高いパフォーマンスでSSL/TLS処理を実行できるため、バックエンドサーバーの負荷を大幅に削減できます。
総務省の調査によると、2023年現在、日本国内のWebサイトのうち85%以上がHTTPS化されている(出典: 総務省「通信利用動向調査2023」)。これは、Googleなどの検索エンジンがHTTPSをランキング要因の一つとしていることや、ユーザーのセキュリティ意識の高まりが背景にあります。Nginxリバースプロキシを導入することで、これらの要件を満たしつつ、柔軟なサーバー構成を実現できます。
リバースプロキシとフォワー…
リバースプロキシとフォワードプロキシは、いずれもプロキシサーバーですが、役割が大きく異なります。
| 機能 | リバースプロキシ | フォワードプロキシ |
|---|---|---|
| 設置場所 | サーバー側 | クライアント側 |
| 主な用途 | 負荷分散、セキュリティ、SSL終端 | 匿名性確保、アクセス制限、キャッシュ |
| 代表的な用途例 | Webサーバーの前段に設置し、リクエストを内部サーバーに転送 | 社内ネットワークからインターネットへのアクセスを制御 |
| Nginxの役割 | リバースプロキシとして動作 | フォワードプロキシとして動作(特定の設定が必要) |
本記事では、主にリバースプロキシに焦点を当てて解説します。フォワードプロキシについては、必要に応じて補足します。
Nginxのインストールと基本設定
Nginxリバースプロキシを構築する前に、Nginxをインストールし、基本的な設定を行います。以下の手順は、Ubuntu 22.04 LTSを前提としていますが、他のLinuxディストリビューションでも同様の手順でインストール可能です。
Nginxのインストール
まず、Nginxをインストールします。公式リポジトリからインストールする方法と、Nginx Inc.が提供する公式リポジトリを使用する方法があります。ここでは、公式リポジトリを使用する方法を紹介します。
# 1. 必要なパッケージをインストール
sudo apt update
sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring
2. Nginx公式リポジトリを追加
echo "deb http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
3. GPGキーをインポート
curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg
4. リポジトリを更新し、Nginxをインストール
sudo apt update
sudo apt install -y nginx
インストールが完了したら、Nginxを起動します。
sudo systemctl start nginx
sudo systemctl enable nginx
Nginxが正常に起動しているか確認します。
systemctl status nginx
以下のような出力が表示されれば、Nginxは正常に動作しています。
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2024-02-19 10:00:00 UTC; 1min ago
Docs: http://nginx.org/en/docs/
Main PID: 1234 (nginx)
Tasks: 2 (limit: 1137)
Memory: 3.4M
CGroup: /system.slice/nginx.service
├─1234 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─1235 nginx: worker process
Nginxの基本設定
Nginxの設定ファイルは、主に/etc/nginx/ディレクトリに格納されています。主な設定ファイルは以下の通りです。
nginx.conf:メインの設定ファイルconf.d/:追加の設定ファイルを格納するディレクトリsites-available/:利用可能なサイトの設定ファイルsites-enabled/:有効化されたサイトの設定ファイル(sites-availableからシンボリックリンク)
まず、nginx.confを確認します。
cat /etc/nginx/nginx.conf
デフォルトの設定では、include /etc/nginx/conf.d/*.conf;という行があり、conf.d/ディレクトリ内の.confファイルが読み込まれます。このため、リバースプロキシの設定はconf.d/ディレクトリに配置するのが一般的です。
次に、sites-available/とsites-enabled/を使用する方法もあります。これはApacheの設定に似ており、複数のサイトを管理する際に便利です。ここでは、conf.d/を使用する方法で進めます。
まず、conf.d/ディレクトリに新しい設定ファイルを作成します。
sudo nano /etc/nginx/conf.d/reverse-proxy.conf
以下の内容を記述します。これは、単純なリバースプロキシの設定例です。
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:8080;
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;
}
}
この設定は、example.comに対するリクエストを、localhost:8080に転送します。また、リクエストヘッダーを適切に設定することで、バックエンドサーバーがクライアントの情報を正しく認識できるようにします。
設定を保存したら、Nginxを再読み込みします。
sudo nginx -t # 構文チェック
sudo systemctl reload nginx
nginx -tコマンドは、設定ファイルの構文をチェックします。エラーがなければ、systemctl reload nginxで設定を反映します。
バックエンドサーバーの準備
リバースプロキシを動作させるためには、バックエンドサーバーが必要です。ここでは、簡単なHTTPサーバーを起動して、リバースプロキシが正しく動作するか確認します。
Pythonの簡易HTTPサーバーを使用します。
# 任意のディレクトリで実行
mkdir -p ~/reverse-proxy-test
cd ~/reverse-proxy-test
echo "Hello, Reverse Proxy!" > index.html
Python 3を使用してHTTPサーバーを起動(ポート8080)
python3 -m http.server 8080
別のターミナルで、Nginxの設定で指定したexample.comにアクセスします。ローカル環境では、/etc/hostsファイルに以下の行を追加して、example.comをlocalhostに解決させます。
127.0.0.1 example.com
その後、ブラウザでhttp://example.comにアクセスすると、Hello, Reverse Proxy!というメッセージが表示されます。これにより、Nginxリバースプロキシが正しく動作していることが確認できます。
SSL/TLS証明書の取得とNginxへの適用
現代のWebサイトにとって、SSL/TLS対応は必須です。Nginxリバースプロキシでも、SSL/TLSを有効にすることで、セキュアな通信を実現できます。ここでは、Let’s Encryptを使用して無料のSSL/TLS証明書を取得し、Nginxに適用する方法を解説します。
Let’s Encryptとは
Let’s Encryptは、非営利団体のInternet Security Research Group (ISRG)が運営する、無料で利用できるSSL/TLS証明書を発行する認証局です。2024年現在、世界中で2億件以上の証明書が発行されており、その信頼性は高く評価されています。
Let’s Encryptの証明書は、以下の特徴を持ちます。
- 無料:個人や小規模なサイトでも利用可能
- 自動更新:証明書の有効期限が近づくと自動的に更新される
- 広範な互換性:主要なブラウザやOSでサポートされている
- 90日間有効:セキュリティ向上のため、有効期限が短い
Certbotのインストール
Let’s Encryptの証明書を取得するためには、Certbotというツールを使用します。Certbotは、証明書の取得と更新を自動化するツールです。
Certbotをインストールします。
sudo apt install -y certbot python3-certbot-nginx
このコマンドは、Certbot本体と、Nginx用のプラグインをインストールします。Nginx用のプラグインを使用することで、自動的にNginxの設定を更新できます。
SSL/TLS証明書の取得
Certbotを使用して、SSL/TLS証明書を取得します。ここでは、example.comをドメイン名として使用します。実際の運用では、取得したドメインに置き換えてください。
sudo certbot --nginx -d example.com
Certbotが起動し、以下のような対話型のプロンプトが表示されます。
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): admin@example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
protecting the privacy of individuals like you.
- - - - - - - - - - - - - - - - - - - - - - - - - - "Y" to subscribe, "N" to
decline, "C" to cancel: N
メールアドレスの入力と、利用規約への同意、EFFへのメール配信の可否を選択します。その後、Certbotが自動的にドメインの検証を行い、SSL/TLS証明書を取得します。
証明書の取得が完了すると、以下のようなメッセージが表示されます。
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your cert will expire on 2024-05-18. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Certbotは、自動的にNginxの設定ファイルを更新し、SSL/TLSを有効にします。/etc/nginx/conf.d/reverse-proxy.confファイルを確認すると、以下のような設定が追加されていることがわかります。
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
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:8080;
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;
}
}
この設定により、HTTP(ポート80)へのアクセスはHTTPS(ポート443)にリダイレクトされ、SSL/TLSが有効になります。
SSL/TLSの設定最適化
Let’s Encryptから発行される証明書は、デフォルトでTLS 1.2とTLS 1.3をサポートしています。しかし、セキュリティを向上させるために、より厳格な設定を行うことを推奨します。以下は、NginxのSSL/TLS設定を最適化するための例です。
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;
# SSL/TLS設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;
location / {
proxy_pass http://localhost:8080;
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;
}
}
主な設定項目の説明は以下の通りです。
ssl_protocols:使用するSSL/TLSプロトコルを指定します。TLS 1.2とTLS 1.3のみを許可します。ssl_prefer_server_ciphers:サーバー側の暗号スイートを優先します。ssl_ciphers:使用する暗号スイートを指定します。安全な暗号スイートのみを許可します。ssl_session_timeout:SSLセッションの有効期限を設定します。ssl_session_cache:SSLセッションのキャッシュを有効にします。ssl_stapling:OCSP Staplingを有効にします。これにより、証明書の失効確認が高速化されます。
設定を更新したら、Nginxを再読み込みします。
sudo nginx -t
sudo systemctl reload nginx
SSL/TLS証明書の自動更新
Let’s Encryptの証明書は90日間有効です。このため、証明書の自動更新を設定することが重要です。Certbotには、証明書の自動更新を行うcertbot renewコマンドが用意されています。
自動更新を設定するためには、cronジョブを使用します。以下のコマンドで、毎週月曜日の午前2時に証明書の更新を確認するように設定します。
sudo crontab -e
以下の行を追加します。
0 2 * * 1 /usr/bin/certbot renew --quiet
--quietオプションを使用することで、更新が行われた場合のみログが出力されます。更新が行われた場合は、自動的にNginxが再読み込みされます。
リバースプロキシの基本設定と動作確認
Nginxをリバースプロキシとして動作させるための基本的な設定方法と、動作確認の手順を解説します。ここでは、具体的なバックエンドサーバーとして、Apache HTTP ServerとNode.jsアプリケーションを例に挙げます。
Apache HTTP S…
Apache HTTP Serverをバックエンドサーバーとして使用する場合の設定例を紹介します。Apacheはデフォルトでポート80で動作しますが、Nginxと競合しないようにポートを変更します。
Apacheの設定ファイルを編集します。
sudo nano /etc/apache2/ports.conf
以下の行を変更します。
Listen 8080
次に、Apacheの仮想ホスト設定を編集します。
sudo nano /etc/apache2/sites-available/000-default.conf
以下の内容に書き換えます。
<VirtualHost *:8080>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>
Apacheを再起動します。
sudo systemctl restart apache2
次に、Nginxのリバースプロキシ設定を更新します。
sudo nano /etc/nginx/conf.d/reverse-proxy.conf
以下の内容に書き換えます。
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
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://localhost:8080;
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;
}
}
設定を保存したら、Nginxを再読み込みします。
sudo nginx -t
sudo systemctl reload nginx
ブラウザでhttps://example.comにアクセスすると、Apacheが提供するコンテンツが表示されます。これにより、Nginxリバースプロキシを介してApacheが動作していることが確認できます。
Node.jsアプリケーシ…
Node.jsアプリケーションをバックエンドサーバーとして使用する場合の設定例を紹介します。ここでは、簡単なExpress.jsアプリケーションを例に挙げます。
まず、Node.jsとnpmをインストールします。
sudo apt install -y nodejs npm
次に、Express.jsアプリケーションを作成します。
mkdir -p ~/node-app
cd ~/node-app
npm init -y
npm install express
app.jsファイルを作成します。
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello from Node.js!');
});
app.listen(port, () => {
console.log(`Node.js app listening at http://localhost:${port}`);
});
アプリケーションを起動します。
node app.js
アプリケーションがポート3000で動作していることを確認します。次に、Nginxのリバースプロキシ設定を更新します。
sudo nano /etc/nginx/conf.d/reverse-proxy.conf
以下の内容に書き換えます。
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
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://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;
}
}
設定を保存したら、Nginxを再読み込みします。
sudo nginx -t
sudo systemctl reload nginx
ブラウザでhttps://example.comにアクセスすると、Node.jsアプリケーションが提供するメッセージが表示されます。これにより、Nginxリバースプロキシを介してNode.jsアプリケーションが動作していることが確認できます。
リバースプロキシの動作確認
リバースプロキシが正しく動作しているか確認するためには、以下の方法があります。
- ログの確認:Nginxのアクセスログとエラーログを確認します。
- ヘッダーの確認:ブラウザの開発者ツールを使用して、レスポンスヘッダーを確認します。
- curlコマンドの使用:
curl -v https://example.comを実行し、レスポンスヘッダーを確認します。
例えば、curl -v https://example.comを実行すると、以下のような出力が表示されます。
* Trying 192.168.1.100:443...
* Connected to example.com (192.168.1.100) port 443 (#0)
* ALPN: offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
* subject: CN=example.com
* start date: Jan 1 00:00:00 2024 GMT
* expire date: Mar 31 23:59:59 2024 GMT
* subjectAltName: host "example.com" matched cert's "example.com"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55a1b3a5e2a0)
> GET / HTTP/2
> Host: example.com
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< server: nginx/1.25.3
< date: Mon, 19 Feb 2024 10:00:00 GMT
< content-type: text/html
< content-length: 21
< last-modified: Mon, 19 Feb 2024 09:00:00 GMT
< etag: "65d3a1a0-15"
< x-powered-by: Express
< via: 1.1 example.com
< strict-transport-security: max-age=63072000; includeSubDomains; preload
<
Hello from Node.js!
この出力から、以下の情報を確認できます。
server: nginx/1.25.3:Nginxがリバースプロキシとして動作しているx-powered-by: Express:バックエンドがExpress.jsアプリケーションであるvia: 1.1 example.com:リバースプロキシを経由しているstrict-transport-security:HSTSヘッダーが設定されている
応用的なリバースプロキシ設定(負荷分散・キャッシュ)
基本的なリバースプロキシ設定をマスターしたら、次は応用的な設定に挑戦しましょう。ここでは、負荷分散とキャッシュの
この記事で学んだスキルをさらに深めたい方へ
インフラセキュリティを体系的に学ぶための技術書です。SSL/TLS・ファイアウォール・VPNを網羅しています。
Amazonアソシエイトプログラムを利用しています。
本記事はRoute Bloom編集部が公式ドキュメント・技術仕様書の一次情報をもとに作成しています。ITインフラ・技術情報は急速に変化するため、実装前に最新の公式ドキュメントをご確認ください。情報の正確性には万全を期していますが、最新情報は各公式サイトをご確認ください。
本記事はRoute Bloom編集部が各ベンダー公式ドキュメント・エンジニア監修をもとに作成しています。インフラ・クラウド構築は環境により異なります。本番環境への適用前に必ずテストを実施してください。情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。
本記事はRoute Bloom編集部が各ベンダー・技術標準の公式ドキュメントをもとに作成しています。 インフラ・クラウド技術に関する最終判断は実際の環境・バージョンで検証のうえ実施してください。 情報の正確性には万全を期していますが、最新情報は各公式ドキュメントをご確認ください。
編集ポリシー:この記事は、Route Bloom の編集チームが最新情報を元に執筆・監修しています。情報の正確性を保つために定期的な見直しを行っています。




