Linuxネットワークコマンド:ip、ss、ping、traceroute、dig、curlで診断する
Linuxの主要なネットワークコマンドは、ipがアドレスとルート、ssが開いているポートと接続、pingとtracerouteが相手ノードへの到達性、digがDNS、curlがWebサービスの応答を確認します。原因を探すときは、インターフェース、ルート、DNS、ポート、アプリケーションの順に層ごとに確かめると効率的です。
Linuxのネットワークコマンドを使えば、日常的なネットワーク診断のほとんどをこなせます。ip はアドレスとルートを表示し、ss は開いているポートと接続を表示します。ping と traceroute はノードへの到達性を確認し、dig はDNSを、curl はWebサービスの応答を調べます。以下では、フラグ付きの一覧と、「ネットワークが動かない」ときに原因を探す順序を紹介します。
一覧表:Linuxネットワークコマンドの早見表
| 目的 | コマンド |
|---|---|
| すべてのインターフェースのIPアドレス | ip -br addr |
| インターフェースの状態(UP/DOWN) | ip -br link |
| ルーティングテーブル | ip route |
| あるアドレスへのパケットがどのゲートウェイを通るか | ip route get 8.8.8.8 |
| 隣接ノード(ARPテーブル) | ip neigh |
| 待ち受け中のポートとプロセス | sudo ss -tulpn |
| 確立されているTCP接続 | ss -tn state established |
| ノードへの到達性を確認 | ping -c 4 example.com |
| ノードまでのパスを表示 | traceroute example.com、mtr example.com |
| 名前をアドレスに変換 | dig +short example.com |
| 特定のDNSサーバーに問い合わせ | dig @1.1.1.1 example.com |
| HTTPの応答を確認 | curl -I https://example.com |
| 接続とTLSの詳細 | curl -v https://example.com |
| TCPポートが開いているか | nc -zv host 443 |
| ホスト名 | hostnamectl、hostname -I |
ip:アドレス、インターフェース、ルート
ip コマンド(iproute2パッケージ)は、古い ifconfig と route に取って代わりました。サブコマンドは短縮できます。ip a は ip addr、ip r は ip route と同じ意味です。-br を付けると短い形式で表示され、-c を付けると色が付きます。
$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 192.168.1.25/24 fe80::a00:27ff:fe4e:66a1/64
docker0 DOWN 172.17.0.1/16
インターフェースに必要なネットワークのアドレスがない、または状態が DOWN の場合、この層に問題があると分かります。それ以上の調査は不要です。
IPアドレスを追加してインターフェースを起動する
sudo ip link set eth0 up
sudo ip addr add 192.168.1.50/24 dev eth0
sudo ip addr del 192.168.1.50/24 dev eth0
ip で行った変更は、再起動するまで有効です。恒久的な設定はシステムの設定ファイルで行います。Ubuntuではnetplan、FedoraやRHELではNetworkManager(nmcli)、サーバーでは systemd-networkd を使います。
ルートとデフォルトゲートウェイ
$ ip route
default via 192.168.1.1 dev eth0 proto dhcp metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.25
$ ip route get 10.20.0.5
10.20.0.5 via 192.168.1.1 dev eth0 src 192.168.1.25 uid 1000
default via の行は、より具体的なルートに一致しなかったトラフィックの送り先となるゲートウェイです。この行がなければ、ローカルネットワークは動いていてもインターネットには出られません。ルートを追加するには sudo ip route add 10.20.0.0/16 via 192.168.1.254 を実行します。
ss:開いているポートと待ち受けプロセス
ss は netstat の後継で、より高速に動作します。最もよく使う組み合わせは ss -tulpn です。
| フラグ | 意味 |
|---|---|
-t / -u | TCP / UDP |
-l | 待ち受け中のソケットのみ |
-p | プロセスを表示(他のユーザーのプロセスはsudoが必要) |
-n | ポートやアドレスを名前に変換しない |
-a | 確立済みの接続を含むすべてのソケット |
-s | 概要の統計 |
$ sudo ss -tulpn
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=812,fd=6))
tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=640,fd=3))
tcp LISTEN 0 151 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=901,fd=21))
アドレスに注目してください。0.0.0.0 は、サービスがすべてのインターフェースからの接続を受け付けていることを示します。127.0.0.1 は、ローカルからの接続だけを受け付けることを示します。データベースに別のマシンから接続できない原因として、これがよくあります。
ポートを使っているプロセスを調べる
sudo ss -ltnp 'sport = :8080'
sudo ss -tn dst 10.0.0.7 # 特定のアドレスへの接続
ss -tan state time-wait | wc -l # TIME-WAIT状態のソケット数
ping:ノードに到達できるか
ping はICMPのecho要求を送信し、応答時間とパケットロスを表示します。Linuxでは停止するまで実行され続けるため、-c フラグで送信数を指定します。
$ ping -c 4 8.8.8.8
64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=12.4 ms
...
--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 12.1/12.5/13.0/0.3 ms
便利なフラグには、-i 0.2(送信間隔)、-W 2(応答のタイムアウト)、-4 / -6(プロトコルのバージョン)、-s 1472 -M do(フラグメント化せずにMTUを確認)があります。多くのサーバーやクラウドはICMPをブロックしています。pingに応答がないからといって、必ずしもノードが停止しているとは限りません。
traceroute と mtr:パケットがどこで失われるか
traceroute は、宛先までの経路上のノードを表示します。個々のホップで「*」が表示されるのは正常です。中継ルーターが応答を返さない場合があるためです。注意すべきなのは、ある地点を過ぎてから「*」がずっと続く場合です。
traceroute -n example.com # 名前解決なし。高速
sudo traceroute -T -p 443 example.com # UDPの代わりにTCPを使う。ファイアウォールを通過しやすい
tracepath example.com # rootなしで実行可能。MTUも表示
mtr は ping と traceroute を組み合わせたツールで、各ホップのロス率をリアルタイムで更新します。レポートを出力するには mtr -rwc 50 example.com を実行します。
dig:DNSの確認
dig は dnsutils パッケージ(RHELではbind-utils)に含まれ、DNSを確認する主要なツールです。短い形式では応答だけが表示されます。
$ dig +short example.com
93.184.215.14
$ dig example.com MX +short
$ dig @8.8.8.8 example.com A # 特定のサーバーに問い合わせ
$ dig -x 8.8.8.8 +short # 逆引き(PTR)
$ dig +trace example.com # ルートサーバーから順にたどる
詳細な出力では status を確認します。NOERROR はレコードが見つかったことを、NXDOMAIN はドメインが存在しないことを、SERVFAIL はサーバーが応答できなかったことを示します(DNSSECの問題や権威サーバーの停止が原因のことがよくあります)。dig @8.8.8.8 は応答するのに通常の dig が応答しない場合は、ローカルのリゾルバーに問題があります。/etc/resolv.conf と resolvectl status を確認してください。
dig は /etc/hosts を参照しない点に注意してください。アプリケーションと同じ方法で名前解決を確認するには getent hosts example.com を使います。
curl:HTTPとAPIの確認
curl は、サービスが応答しているか、そして実際に何を返しているかを確認します。
| コマンド | 動作 |
|---|---|
curl -I URL | ヘッダーのみ取得(HEADリクエスト) |
curl -v URL | 詳細表示:DNS、接続、TLS、ヘッダー |
curl -L URL | リダイレクトをたどる |
curl -o file URL | ファイルに保存 |
curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' URL | JSONを送信 |
curl -k URL | 証明書を検証しない(デバッグ専用) |
curl --resolve site.example:443:10.0.0.5 https://site.example | DNSを使わず特定のサーバーに接続 |
curl -s -o /dev/null -w '%{http_code} %{time_total}\n' URL | 応答コードと所要時間 |
$ curl -s -o /dev/null -w '%{http_code} %{time_connect} %{time_total}\n' https://example.com
200 0.041 0.187
curlのエラーメッセージから、問題のある層を推測できます。Could not resolve host はDNSの問題、Connection refused はポートが閉じているか待ち受けプロセスがないこと、Connection timed out はファイアウォールがパケットを遮断しているか経路がないこと、SSL certificate problem は証明書の問題を意味します。
切り分けの手順:ネットワークが動かないとき
- インターフェースとアドレス:
ip -br addrで、インターフェースがUPでアドレスが割り当てられているか確認します。 - ゲートウェイ:
ip routeでdefault viaがあるか確認し、ping -c 3 <ゲートウェイ>を実行します。 - IPアドレスによる外部通信:
ping -c 3 1.1.1.1。成功すればルーティングは正常です。 - DNS:
dig +short example.com。IPアドレスへのpingは成功するのに結果が空またはエラーになる場合、問題はリゾルバーにあります。 - ポート:
nc -zv host 443またはcurl -v。サーバーではss -tulpnを実行し、サービスが待ち受けているか、どのアドレスで待ち受けているかを確認します。 - ファイアウォール:
sudo nft list ruleset、sudo iptables -L -n、sudo ufw status。 - アプリケーション:
curl -Iとサービスのログ(journalctl -u nginx)。
下の層から順に確認し、手順を飛ばさないでください。そうすれば、数分で問題の層を特定でき、やみくもにサービスを再起動する必要がなくなります。
古いコマンドと新しいコマンド
| 古いコマンド(net-tools) | 新しい代替 |
|---|---|
ifconfig | ip addr、ip link |
route -n | ip route |
arp -n | ip neigh |
netstat -tulpn | ss -tulpn |
nslookup | dig |
最近のディストリビューションでは、net-toolsがインストールされていないことがよくあります。新しいコマンドに慣れておくとよいでしょう。
まとめ
日常の診断には、ip、ss、ping、traceroute、dig、curl の6つのLinuxネットワークコマンドで十分です。アドレス、ルート、DNS、ポート、アプリケーションの順に層ごとに確認すれば、障害を素早く見つけられます。ネットワークコマンドと典型的な障害の切り分けは、Linuxコースで実際の例を使って解説しています。
よくある質問
なぜ ifconfig コマンドがシステムにないのですか?
ifconfig は古いnet-toolsパッケージに含まれており、最近のディストリビューションでは標準ではインストールされません。ip addr を使うか、net-toolsを手動でインストールしてください。
外部のIPアドレスをコンソールから調べるにはどうすればよいですか?
curl ifconfig.me または curl -4 icanhazip.com を実行します。外部のサービスが、インターネットへの出口となるアドレスを返します。ip addr が表示するのは通常、インターフェースの内部アドレスです。
ping とポートの確認はどう違いますか?
ping はICMPでノードへの到達性を確認しますが、特定のサービスについては何も分かりません。サーバーが特定のポートで接続を受け付けているかは、nc -zv ホスト ポート または curl で確認します。
ネットワークインターフェースの速度や負荷を確認するにはどうすればよいですか?
ip -s link でバイト数とエラーのカウンターを確認できます。リアルタイムの負荷は iftop、nload、bmon で確認します。2台のマシン間の帯域幅は iperf3 で測定します。
DNSサーバーを一時的に変更するにはどうすればよいですか?
systemd-resolved を使っている場合は sudo resolvectl dns eth0 1.1.1.1 を実行します。一回だけ確認するなら、問い合わせにサーバーを指定する方が簡単です:dig @1.1.1.1 example.com。