Nginxの「接続拒否」エラーを修正する:実践的なトラブルシューティングガイド

Nginxの接続拒否エラーをトラブルシューティングするには、サービスステータス、リスニングポート、ファイアウォール、設定、アップストリームを確認します。

Nginxの「接続拒否」エラーを修正する:実践的なトラブルシューティングガイド

Nginxの背後で動作するサービスにアクセスしようとしたときに「接続拒否」エラーに遭遇することは、よくあることですが、イライラする経験です。タイムアウトエラーがネットワークの遅延やパケットロスを示唆するのとは異なり、「接続拒否」エラーは明確です。指定されたポートとIPアドレスでアクティブにリッスンしているアプリケーションがなかったため、オペレーティングシステムが即座に接続試行を拒否したことを意味します。

この即時拒否は、問題をいくつかの重要な領域に絞り込みます。サービスがダウンしている、ファイアウォールがローカルでトラフィックをブロックしている、または設定が存在しないポートにトラフィックを誘導している、のいずれかです。このガイドでは、「接続拒否」エラーを診断して解決するための体系的な4段階のアプローチを提供し、サービス接続を迅速に復旧できるようにします。

フェーズ1:Nginxサーバーステータスの確認(プライマリリスナー)

接続拒否の最も基本的な原因は、Nginxサービス自体が実行されていないか、不適切に設定されていることです。

1. Nginxサービスのステータスを確認する

システムのサービス管理ツール(通常はsystemd)を使用して、Nginxがアクティブで実行中であることを確認します。ここでの失敗は、プライマリリスニングポート(通常は80または443)での拒否の直接的な原因です。

sudo systemctl status nginx

期待される出力(成功): Active: active (running) を探します。

実行可能な修正: ステータスが inactive または failed を示している場合は、サービスを起動し、ログで障害の詳細を確認します。

sudo systemctl start nginx
sudo journalctl -xe | grep nginx

2. アクティブなリスニングポートを確認する

ss(ソケット統計)または netstat ツールを使用して、Nginxが実際に期待されるIPアドレスとポート(例:0.0.0.0:80 または 127.0.0.1:8080)にバインドしていることを確認します。

# ssを使用(最新のLinuxディストリビューションで推奨)
sudo ss -tuln | grep 80

# netstatを使用
sudo netstat -tuln | grep 80

Nginxに関連するプロセス(PID)の下に期待されるポート(例::80 または :443)がリストされていない場合、Nginxがバインドに失敗したことを意味します。これはおそらく設定エラー、または別のサービスがそのポートを既に占有しているためです。

ヒント: 別のサービスがポートを占有している場合は、そのサービスを停止するか、Nginxの設定を変更して別の利用可能なポートでリッスンする必要があります。

フェーズ2:ファイアウォールとネットワーク設定

Nginxがローカルで実行されリッスンしている場合、接続拒否はサービス外部で発生している可能性があります。通常は、ファイアウォールルールがインバウンドトラフィックをブロックしていることが原因です。

1. ローカルサーバーのファイアウォールを確認する

Nginxがリッスンしているポート(例:80、443)が、ホストのファイアウォール(UFW、firewalld、またはiptables)で明示的に許可されていることを確認します。

UFWの例(Ubuntu/Debian)

sudo ufw status verbose
# 閉じている場合、ポートを許可する:
sudo ufw allow 'Nginx Full'
# または具体的に:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

Firewalldの例(CentOS/RHEL)

sudo firewall-cmd --list-all
# 閉じている場合、サービスを追加する:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

2. クラウドプロバイダーのセキュリティグループを確認する

サーバーがクラウド環境(AWS EC2、Azure VM、GCP Compute Engine)でホストされている場合、接続拒否は仮想ネットワークのセキュリティレイヤーから発生している可能性があります。

  • AWSセキュリティグループ(SG): 関連するSGを確認し、インバウンドルールがソースIPアドレス(通常はパブリックアクセス用に 0.0.0.0/0)からのポート80および443のトラフィックを許可していることを確認します。
  • Azureネットワークセキュリティグループ(NSG): インバウンドポートルールを確認します。

フェーズ3:Nginx設定の検証

誤った設定ディレクティブにより、Nginxが利用できないポートやIPでリッスンしようとし、起動に失敗して接続拒否が発生する可能性があります。

1. listen ディレクティブを確認する

プライマリ設定ファイル(多くの場合 /etc/nginx/nginx.conf)および関連するサーバーブロック(通常は /etc/nginx/conf.d/ または /etc/nginx/sites-enabled/ 内)を検査します。listen ディレクティブが正しいことを確認します。

正しく設定されたlistenブロックの例:

server {
    listen 80;
    listen [::]:80;
    server_name example.com;
    # ... その他のディレクティブ
}

Nginxが 127.0.0.1(localhost)のみでリッスンするように設定されているが、パブリックIPを使用してアクセスしようとしている場合、接続は拒否されます。

2. 設定の構文チェックを実行する

Nginxを再起動する前に、常に設定の構文を検証します。解析エラーがあるとサービスが起動できなくなり、拒否が発生します。

sudo nginx -t

テストが失敗した場合は、特定されたエラーを修正し、テストを再実行してから、Nginxをリロードまたは再起動します。

sudo systemctl reload nginx

フェーズ4:リバースプロキシ(アップストリーム)の問題のトラブルシューティング

Nginxがポート80/443で正常に実行されているが、特定のパス(/api/)にアクセスすると「接続拒否」が発生する場合、問題はNginxとバックエンドサービス(アップストリーム)の間にあります。

このシナリオでは、Nginxは最初の接続を受け入れましたが、リクエストをプロキシしようとしたときに、バックエンドへの接続が拒否されました。エラーログでこれを確認できます。

1. Nginxエラーログを確認する

失敗した接続を試みた直後に、Nginxエラーログ(通常は /var/log/nginx/error.log)を確認します。proxy_pass ディレクティブに関連するメッセージ、特に接続エラーについて言及しているものを探します。

tail -f /var/log/nginx/error.log

次のようなエントリが表示される場合があります:

[error] connect() failed (111: Connection refused) while connecting to upstream

2. バックエンドサービスのステータスを確認する

これはプロキシシナリオで最も一般的な修正です。バックエンドアプリケーション(例:Node.js、Python Gunicorn、Apache)がダウンしているか、Nginxが期待する場所でリッスンしていません。

実行可能な手順:

a. バックエンドサービスのステータスを確認する: バックエンドアプリケーションが実行中であることを確認します。

b. バックエンドのリスニングポートを確認する: バックエンドをホストしているサーバーで ss -tuln を使用して、アプリケーションがNginxの proxy_pass ディレクティブで指定されたIP/ポートでリッスンしていることを確認します。

3. バックエンド接続を直接テストする

Nginxサーバーからバックエンドへの接続を curl または telnet を使用してテストし、問題をNginxから切り離します。

proxy_passhttp://127.0.0.1:8080 に設定されていると仮定します:

# Nginxサーバーからバックエンドポートへの接続をテスト
curl -v http://127.0.0.1:8080

# またはtelnetを使用
telnet 127.0.0.1 8080
  • curl または telnet が失敗した場合: バックエンドサービスが間違いなく問題です(リッスンしていないか、内部ファイアウォールが127.0.0.1アクセスをブロックしています)。
  • curl または telnet が成功した場合: 問題は proxy_pass ディレクティブの微妙なエラーである可能性があります(例:セミコロンの欠落、ホスト名解決の誤り、プロトコルの不一致(HTTP vs HTTPS))。

一般的な proxy_pass の間違い

proxy_pass のIPアドレスが、バックエンドが実際にバインドされている場所と一致していることを確認します。バックエンドが特定のIP(例:192.168.1.10:8080)にバインドしているが、Nginxが localhost:8080 を使用している場合、バインドが制限的であれば接続は失敗します。

主要なトラブルシューティング手順の最終確認

  1. システムチェック: Nginxは実行中ですか(systemctl status nginx)?
  2. ポートチェック: Nginxは正しいIP/ポートでリッスンしていますか(ss -tuln)?
  3. ファイアウォールチェック: インバウンドポートはホストファイアウォール(UFW、iptables)で開いていますか?
  4. 設定チェック: nginx -t は成功し、listen ディレクティブは正しいですか?
  5. プロキシチェック(該当する場合): アップストリームサービスは実行中で、proxy_pass で定義された正確なIP/ポートでリッスンしていますか?curl を使用して直接接続をテストします。

リスナー、ポート、ファイアウォール、設定、アップストリームの順にチェックを進めてください。そのパスにより、接続が拒否されている正確な場所に集中できます。