Linuxでのネットワーク接続問題の診断とトラブルシューティング: `ip`、`route`、`dig`、`netcat`などを活用したガイド

Network tutorial - IT technology blog
Network tutorial - IT technology blog

実際に遭遇した問題: 「午前2時、サーバーが外部に接続できない!」

午前2時。あなたはぐっすり眠っていると、PagerDutyが鳴り響きます。Linuxサーバー上の重要なアプリケーションが突然インターネット接続を失いました。アプリケーションのログは、サードパーティAPI呼び出し時のConnection timed outエラーで溢れています。サーバーはソフトウェアパッケージの更新も、NTP時刻の同期もできません。顧客は不満を訴え始め、プレッシャーがあなたにのしかかります。

慌ててサーバーにSSH接続します。私がいつも最初に行うのは、最も基本的な接続の確認です。

ping google.com

結果はping: google.com: 名前またはサービスが不明です。明らかにDNSに問題があるか、さらに悪いことにサーバーが完全にインターネット接続を失っています。次に、パブリックIPアドレスをpingしてみます。

ping 8.8.8.8

今回は、宛先ホストに到達できませんまたは接続: ネットワークに到達できませんと表示されます。サーバーが外部への接続に深刻な問題を抱えていることは明らかです。すべての接続がブロックされているのでしょうか?内部ゲートウェイをpingしてみます。

ping 192.168.1.1 # 実際のゲートウェイアドレスに置き換えてください

幸いなことに、pingは成功しました。これは重要な手がかりです。サーバーは内部ネットワーク内では通信できるが、インターネットには出られない。では、原因は何でしょうか?

原因分析: 最も基本的なことから始める

ネットワーク問題に直面するたびに、私は常にOSIモデルに従い、下位層から上位層へと進みます。このアプローチは、デバッグプロセスを体系化し、可能性を見落とさないのに役立ちます。

1. ネットワーク層 (Network Layer – Layer 3): IP、ゲートウェイ、ルーティング

これは、パケットがサーバーから出ていく旅の出発点です。サーバーが経路を知らないか、IPアドレスが間違っている場合、すべてがすぐに停滞します。

  • サーバーは有効なIPアドレスを持っているか?ネットワークカードは動作中(UP状態)か?
  • サーバーはパケットをどこに送ればよいか(デフォルトゲートウェイ)を知っているか?
  • ルーティングテーブルはパケットの正確な経路を指定しているか?

2. トランスポート層 (Transport Layer – Layer 4): ファイアウォール

パケットが経路を見つけたとしても、サーバー上または中間ネットワークデバイス上のファイアウォール(iptables、firewalldなど)によってブロックされる可能性があります。ファイアウォールは、ポートと送信元/宛先IPアドレスに基づいて、送信(outbound)または受信(inbound)接続をブロックします。

3. アプリケーション層 (Application Layer – Layer 7): ドメイン名解決 (DNS)

パブリックIPアドレスをpingできるのに、ドメイン名(例: google.com)をpingできない場合、主な原因はDNSです。その場合、サーバーはドメイン名をIPアドレスに解決できず、接続エラーにつながります。

解決策と詳細な診断ツール

それでは、各層を1つずつチェックするためのツールを詳しく見ていきましょう。

1. `ip`コマンドでIP設定とインターフェースの状態を確認する

ipコマンドは、Linux上でネットワークを管理するための現代的で強力なツールであり、古いifconfigコマンドに取って代わりつつあります。`ip`を使ってIPアドレス、ネットワークカードの状態、その他多くのパラメータを確認します。

ip a show

このコマンドは、すべてのネットワークインターフェースとそのIP設定を表示します。確認すべき点:

  • メインインターフェース(例: eth0ens33enp0s3)がサーバーのネットワーク範囲内で有効なIPアドレスを持っているか。
  • そのインターフェースの状態がUPであるか。もしDOWNであれば、次のコマンドで有効にする必要があります。
sudo ip link set dev eth0 up # eth0 を実際のインターフェース名に置き換えてください

IPアドレスが失われたり、誤って設定されたりすることがあります。その場合は、IPアドレスを再割り当てしてみることができます(注意: ネットワークサービスが再起動するか、設定ファイルが更新されるまでの一時的な措置です)。

sudo ip addr add 192.168.1.100/24 dev eth0

2. `ip route`でルーティングテーブルを分析する

これは、サーバーがインターネットへの経路を知っているかどうかを特定するために非常に重要なステップです。ip routeコマンド(略してip r)は、システムのルーティングテーブルを表示します。

ip r show

default viaで始まる行を探してください。これがデフォルトゲートウェイです。特定の経路を持たないすべてのパケットはここに転送されます。例:

default via 192.168.1.1 dev eth0 proto dhcp src 192.168.1.100 metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100 metric 100

default viaの行が見つからないか、間違ったアドレスを指している場合、それが原因です。サーバーはパケットを外部に送信する方法をまったく知りません。この問題を一時的に修正するには:

sudo ip r add default via 192.168.1.1 dev eth0 # 実際のゲートウェイとインターフェースに置き換えてください

その後、もう一度ping 8.8.8.8を試してください。成功すれば、問題が特定されたことになります。永続的に設定するには、NetworkManagerの設定または適切なインターフェース設定ファイルを確認する必要があります。

3. `dig`でドメイン名解決を確認する

8.8.8.8をpingできるのに、google.comをpingできない場合、主な原因はDNSです。dig(Domain Information Groper)コマンドは、DNSの問題を診断するための強力なツールです。

dig google.com

;; connection timed out; no servers could be reachedと表示されるか、ANSWER SECTIONが欠落している場合、サーバーがDNSサーバーにクエリを送信できないことを意味します。まず、システムの設定ファイルを確認してください。

cat /etc/resolv.conf

nameserverの行が表示されます。これらのIPアドレスが有効でアクセス可能であることを確認してください。Google DNS(8.8.8.8)のようなパブリックDNSサーバーに直接クエリを送信してみます。

dig @8.8.8.8 google.com

このコマンドが成功した場合、/etc/resolv.confで設定されているDNSサーバーに問題がある(またはサーバーからアクセスできない)ことを意味します。/etc/resolv.confを編集して、一時的にパブリックDNSサーバーを使用できます。

echo 'nameserver 8.8.8.8' | sudo tee /etc/resolv.conf
echo 'nameserver 8.8.4.4' | sudo tee -a /etc/resolv.conf

重要な注意: systemd-resolvedまたはNetworkManagerを使用しているシステムでは、/etc/resolv.confファイルは通常シンボリックリンクであり、再起動時に上書きされます。永続的な変更を行うには、systemd-resolvedまたはNetworkManagerを通じて設定する必要があります。

4. `netcat` (`nc`) でTCP/UDP接続を確認する

IP、ルーティング、DNSがすべて正常でも、アプリケーションが特定のポート上の特定のサービスへの接続エラーを報告する場合があります(例: HTTPS用のポート443、HTTP用のポート80)。ネットワーク接続の状態を確認する際には、netcatはファイアウォールが接続をブロックしているかどうかを確認するための強力なツールです。

サーバーがGoogleのポート443に接続できるかを確認するには:

nc -zv google.com 443

google.com 443ポート [tcp/https] への接続に成功しました!と表示された場合、サーバーからGoogleへのポート443でのTCP接続は完全に安定しています。逆に、接続がタイムアウトしましたまたは接続が拒否されましたと表示された場合、どこかでファイアウォールがブロックしているか、宛先サービスが実行されていない可能性が高いです。

私はよくnetcatを使って2つのサーバー間の双方向接続を確認します。例えば、サーバーAでポートをリッスンします。

nc -lvp 12345

サーバーBでサーバーAに接続します。

nc -zv <IP_Server_A> 12345

接続が成功した場合、サーバーBからメッセージを入力すると、サーバーAに表示されます。これにより、2つのサーバー間のファイアウォールや伝送の問題を除外できます。

5. `traceroute` (または `mtr`) でパケットの経路を特定する

上記の手順でも問題が見つからない場合、またはパケットの経路に問題がある(例: ルーターの故障)と疑われる場合、tracerouteは不可欠なツールです。

traceroute google.com

このコマンドは、パケットが宛先に到達するために通過する各ホップ(ルーター)を表示します。パケットが特定のホップで停止したり、ある地点で異常に高い遅延が発生したりする場合、問題を特定できます。以前、あるサービスが外部APIに時々接続できないことがありました。

結局、ピーク時に中間ルーターで断続的なパケットロスが発生していたことが判明しました。その時、mtr(My Traceroute)が救世主となりました。これはパケットを継続的に送信し、リアルタイムでパケットロスの統計を表示するため、特定の時間帯にのみ発生する問題を簡単に検出できました。

mtr google.com

6. Linux上のファイアウォールを確認する

最後に、サーバー自体のファイアウォールを確認することを忘れないでください。最新のLinuxシステムは通常、firewalldまたはiptablesを使用しています。

firewalldの場合(CentOS/RHEL/Fedora上):

sudo firewall-cmd --list-all

iptablesの場合(Debian/Ubuntuまたは古いシステム上):

sudo iptables -nvL

サーバーがルーターとして機能している場合、送信接続(OUTPUTチェイン)をブロックする可能性のあるルールや、FORWARDに関連するルールを探してください。ファイアウォールが原因だと疑われる場合は、一時的に無効にしてみて(テスト環境でのみ!)確認してください。

sudo systemctl stop firewalld # または iptables.service

確認後、無効にしたままにせず、必ず再度有効にして正しいルールを設定してください!

ネットワーク問題への最善のアプローチ

ネットワークのデバッグは、芸術であり科学でもあります。以下は、私が多くのネットワーク問題に「格闘」した後に得た経験です。

  1. 最も基本的なことから始める: 常にOSIモデルのレイヤー1(物理層)からレイヤー7(アプリケーション層)までチェックを開始してください。IPとルーティングが確実でないうちに、いきなりDNSのチェックに飛びつかないでください。
  2. 排除法を使用する: 実行する各コマンドと得られる各結果で、可能性を1つずつ排除するように努めてください。たとえば、ping 8.8.8.8が成功した場合、レイヤー3と4の基本的な問題を除外できます。
  3. ログを確認する: 常にシステムログを確認してください。journalctl -u NetworkManagerまたはjournalctl -u systemd-networkdは、設定エラーやインターフェースの状態に関する手がかりを提供できます。dmesgもネットワークカードドライバーに関連する問題に非常に役立ちます。
  4. 質問し、検索することをためらわない: あらゆる方法を試しても行き詰まったら、同僚に尋ねたり、Stack Overflowや専門フォーラムで検索したりすることをためらわないでください。誰かが以前に同様の問題に遭遇している可能性が非常に高いです。
  5. 行った手順を記録する: 記録することは、デバッグプロセスを追跡するのに役立つだけでなく、将来のための貴重なドキュメントにもなります。
  6. 落ち着いて行動する: 特に午前2時には。プレッシャーは最も小さな詳細を見落とす原因になる可能性があります。深呼吸をして、体系的に問題に取り組んでください。

Linuxでのネットワーク問題の診断とトラブルシューティングは複雑になることがあります。しかし、適切なツールとアプローチがあれば、問題を特定して解決することは十分に可能です。これらのコマンドが自然な反射になるように、定期的に練習してください!

Share: