Linux 講座 / ネットワーク接続の問題を階層別に診断する

Linuxの接続問題は、インターフェースとアドレスから始めて、経路、名前解決、ポートへの接続、アプリケーション応答の順に確認すると原因を絞りやすくなります。pingの成功や失敗だけでインターネット・ウェブサービス全体の状態を判断しないでください。

アドレスとデフォルトルートを解釈する際は、IPアドレス・DNS・ポートの役割を参照してください。SSHでのみ失敗する場合は、SSH接続とファイル転送のポート・キー・ホストの確認も必要です。

システム設定実習の基準は Ubuntu 26.04 LTS と Rocky Linux 9 系の一般インストール VM です。コンテナ・WSL・別のリリースでは、サービスやパッケージの構成が異なる場合があります。仮想マシン実習環境の作成で、コンソールの復旧とバージョン確認を最初に準備してください。

障害の範囲と比較条件から記録する

どのコンピュータからどのアドレス・ポートにいつから接続できなくなったのかを記録します。すべてのサイトか、特定の1サイトか、同じネットワークの他のデバイスも失敗するのか、IPバージョンやVPN・プロキシが異なるのかを比較してください。直前に変更した設定と実際のエラー文を一緒に残すと推測を減らせます。運用サーバーではネットワークを再起動する前にコンソールや別の管理経路を確保します。

インターフェース・アドレス・ルートを確認する

ip -brief link
ip -brief address
ip route
ip -6 route

UPは、インターフェースが管理上で有効になっているという情報であり、宛先まで通信できることを保証するものではありません。LOWER_UPのようなリンク情報、予想したアドレスの存在、宛先に適した経路をあわせて確認してください。仮想マシンの場合、仮想NICが接続されているか、NAT・ブリッジのどちらのモードが意図したものであるかをホストの仮想化設定も確認してください。インターフェース名をeth0と断定しないでください。

実際の宛先アドレスを特定した後にip route get 実際のIPv4アドレスを実行すると、選択されるインターフェース・次ホップ・送信元アドレスを見ることができます。「Network is unreachable」は名前解決エラーとは異なり、まず経路の問題を示唆します。経路が表示されても、次ホップやその先の機器が応答することを意味するわけではありません。

pingは到達性の一つの手がかりとして使用する

ping -c 3 127.0.0.1
ping -c 3 example.com

最初のコマンドはループバックにICMP Echoを送り、二番目は名前解決後に宛先に送ります。宛先や中間機器がICMPをブロックしている場合、ウェブアクセスが正常でもpingは失敗することがあります。逆に、pingが成功しても、そのウェブポート、証明書、HTTP応答の正常性を確認することはできません。外部の宛先に繰り返しトラフィックを送るよりも、許可された実習対象で少数回だけ確認してください。

名前解決の失敗と接続の失敗を分けること

getent ahosts example.com
curl -I -v --connect-timeout 5 --max-time 15 https://example.com/
printf "exit=%s\n" "$?"

getent 結果がない場合は、まず名前サービスの設定を確認します。curl の詳細な出力では、アドレス選択、接続、TLSハンドシェイク(暗号化通信を始めるための確認)、応答の順序を確認します。終了コード 6 は一般的にホスト名の解決失敗、7 は接続失敗、28 はタイムアウトを示します。コード 60 は証明書検証の問題で、ファイアウォールを開く、または DNS を変更することで解決できない場合があります。-k で検証を無効にすることを解決策として使用しないでください。

基本的な curl は HTTP 404 や 500 の応答を受信しても、転送自体が成功すれば終了ステータス 0 を返すことがあります。HTTP エラーを失敗として扱うには、サポートされている curl で --fail-with-body または --fail の使用を検討し、応答コードと終了ステータスを別々に読みます。詳細な出力にはクッキー・ヘッダー・内部アドレスが含まれる可能性があるため、共有前に隠してください。-IはHEADリクエストを送ります。HEADだけが拒否されるサーバーもあるため、応答を受け取れなかった場合は-Iを外したGETやブラウザーでも確認し、すぐにサービス停止と断定しないでください。

サーバー側の待ち受けアドレスとポートを確認する

ss -lnt
ss -lnu
sudo ss -lntp

127.0.0.1:8080でのみ待ち受けると、同じサーバーからのみ直接アクセスできます。0.0.0.0:8080はすべてのIPv4インターフェースを対象とし、[::]:8080のIPv4同時受信可否はソケットとシステム設定によって異なります。プロセス情報は権限によって制限されます。UDPはTCPのLISTENと意味が同じではないため、UDPリストだけでリクエスト応答を保証することはできません。

観察結果に合わせた変更を1つだけ適用する

観察 まず確認
ローカル接続も失敗 サービスの実行・設定・待ち受けポート
ローカル成功、リモート失敗 バインドアドレス・ホストファイアウォール・クラウドセキュリティルール
接続はできるが証明書エラー サーバー名・証明書チェーン・時刻
HTTP エラー応答 ウェブサーバー・アプリケーションログとリクエスト経路

変更前に元の値を記録して、1つの項目だけを変更して同じクライアント・アドレス・ポートで再試行します。効果がなければ元の値に戻した後、別の仮説を確認してください。こうすることで、複数の変更の中で何が原因だったかを見落とさず、問題解決の過程で新たな障害を作る可能性も減らせます。

外部サイトに依存せずに HTTP エラーを区別するには、実習用 VM に python3 と curl があるか確認します。なければ配布版のパッケージマネージャーでインストールします。新しいターミナルで下記サーバーを実行したままにします。18080 ポート使用中にエラーが出た場合は、他の空いているポートを選び、2つのコマンドの番号を一緒に変更してください。

lab=$(mktemp -d "$HOME/linux-http-check.XXXXXX") &&
python3 -m http.server 18080 --bind 127.0.0.1 --directory "$lab"

サーバーが正常に起動した後、同じVMの別のターミナルで以下を実行します。HTTP 404が表示され、curlの終了ステータスは22になります。これはこのリクエストでTCP接続とHTTP応答は届いたものの、ファイルが存在しないことを意味します。サーバーターミナルでCtrl+Cで終了した後、再度リクエストすると、待ち受けサーバーがなければ通常接続失敗でcurlのステータスは7になり、接続試行がタイムアウトまで待機する環境ではステータス28になることもあります。ステータス値はすぐに確認し、新しいサーバーが同じポートを使用していないかも確認してください。

curl --fail --show-error --connect-timeout 2 --max-time 5 http://127.0.0.1:18080/missing-file
printf "exit=%s\n" "$?"

公式ドキュメント