Nginxの「Connection Refused」エラーの修正:実践的なトラブルシューティングガイド
Nginxの背後で実行されているサービスにアクセスしようとしたときに「Connection Refused」(接続拒否)エラーに遭遇することは、一般的ですが厄介な経験です。ネットワークの遅延やパケット損失を示唆する「Timeout」エラーとは異なり、「Connection Refused」エラーは決定的です。これは、指定されたポートとIPアドレスでアクティブに応答しているアプリケーションがなかったために、オペレーティングシステムが接続試行を即座に拒否したことを意味します。
この即時拒否は、問題がいくつかの重要な領域にあることを特定します。サービスがダウンしている、ファイアウォールがローカルでトラフィックをブロックしている、または設定が非存在のポートにトラフィックを誘導している、のいずれかです。本ガイドでは、「Connection Refused」エラーを診断および解決するための体系的な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/など)にアクセスすると「Connection Refused」が発生する場合、問題は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. バックエンドのリッスンポートの確認: Nginxのproxy_passディレクティブで指定されているIP/ポートでアプリケーションがリッスンしていることを確認するために、バックエンドをホストしているサーバーでss -tulnを使用します。
3. バックエンド接続性の直接テスト
Nginxから切り離して問題を特定するために、curlまたはtelnetを使用してNginxサーバーからバックエンドへの接続をテストします。
proxy_passがhttp://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を使用している場合、バインドが制限的であれば接続は失敗します。
主要なトラブルシューティング手順の概要
- システムチェック: Nginxは実行されていますか(
systemctl status nginx)? - ポートチェック: Nginxは正しいIP/ポートでリッスンしていますか(
ss -tuln)? - ファイアウォールチェック: ホストファイアウォール(UFW、iptables)で着信ポートは開いていますか?
- 設定チェック:
nginx -tは合格し、listenディレクティブは正しいですか? - プロキシチェック(該当する場合): アップストリームサービスは実行されており、
proxy_passで定義された正確なIP/ポートでリッスンしていますか?curlを使用して接続性を直接テストしてください。
この体系的なプロセスに従うことで、「Connection Refused」エラーが、サービス停止、制限的なファイアウォール、または誤設定されたプロキシ設定によるものかどうかを迅速に特定し、ダウンタイムを最小限に抑え、効率的にアクセスを復旧させることができます。