network 障害対応の実践 - ping/traceroute/digを使った切り分け

network 障害対応の実践 - ping/traceroute/digを使った切り分け

この記事で解決できること

「サイトにつながらない」「特定のサーバーにだけ到達できない」——ネットワーク障害は原因の切り分けが9割だ。ping / traceroute / dig の3コマンドで、到達性 → 経路 → DNS の順に確認すれば、障害箇所を確実に特定できる。

切り分けの型(実務で使う3ステップ)

  1. ping で到達性を確認する
  2. traceroute でどこで詰まっているかを確認する
  3. dig で DNS 解決を確認する

前提(対象環境)

  • OS:Ubuntu / RHEL 系 Linux
  • CLI 操作が可能な環境

1. ping — 到達性を確認するには?

ping はパケットが相手ホストまで届くかを確認する最初の手段だ。IP アドレスで疎通を確認することで、DNS の問題と経路の問題を分離できる。

$ ping -c 4 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=8.45 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=118 time=7.92 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=118 time=8.21 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=118 time=8.10 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 7.920/8.170/8.450/0.196 ms

ping の結果の読み方

結果 意味
応答あり(0% packet loss) 物理接続・ルーティングは正常
100% packet loss ルーティング問題またはファイアウォールによるブロック
Request timeout 相手が ICMP を拒否、または経路に問題あり

外部と内部を分けて確認する

# ステップ1: ローカルゲートウェイに疎通できるか
$ ping -c 4 192.168.1.1

# ステップ2: ISP の DNS サーバーに疎通できるか(インターネット接続確認)
$ ping -c 4 8.8.8.8

# ステップ3: ホスト名で疎通できるか(DNS 解決も含めた確認)
$ ping -c 4 google.com

ステップ2は通るがステップ3が失敗する場合は DNS の問題だ。

-c 4 で送信回数を指定する。無指定だと Ctrl+C まで無限に送信し続けるため、スクリプトや確認作業では必ず -c を付ける。

2. traceroute — 経路のどこで止まっているか?

到達できない場合、traceroute でどのルーター(ホップ)で詰まっているかを特定する。

$ traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 60 byte packets
 1  192.168.1.1 (192.168.1.1)  1.234 ms  1.145 ms  1.089 ms
 2  10.0.0.1 (10.0.0.1)  8.456 ms  8.512 ms  8.398 ms
 3  * * *
 4  203.0.113.1 (203.0.113.1)  15.234 ms  15.198 ms  15.321 ms
 5  8.8.8.8 (8.8.8.8)  22.567 ms  22.489 ms  22.601 ms

* * * はどういう意味か?

* * * はそのルーターが ICMP の Time Exceeded を返さないことを示す。必ずしも障害ではない。問題なく先のホップに到達できていれば、そのルーターが単に ICMP を拒否しているだけだ。

途中のホップから * * * が続いて先に進まない場合は、そのルーター以降でパケットが落とされている可能性が高い。

traceroute がない場合

Ubuntu では標準未搭載の場合がある。

$ sudo apt install traceroute

mtr は経路を継続的に監視でき、各ホップのパケットロス率もリアルタイムで表示するため実務でよく使われる。

$ sudo apt install mtr
$ mtr 8.8.8.8

3. dig — DNS 解決を確認するには?

IP で疎通できるがホスト名で届かない場合は DNS の問題だ。dig で名前解決の詳細を確認する。

基本的な使い方

# A レコード(IPv4 アドレス)を確認する
$ dig google.com A

# 結果だけを簡略表示する
$ dig +short google.com
142.250.196.46
# 特定の DNS サーバーに直接問い合わせる(DNS サーバー自体の問題を切り分ける)
$ dig @8.8.8.8 google.com A

dig の出力の読み方

$ dig google.com A
; <<>> DiG 9.18.18 <<>> google.com A
;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             83      IN      A       142.250.196.46

;; Query time: 12 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
  • ANSWER SECTION に値があれば DNS 解決は成功
  • NXDOMAIN が返ってきた場合、そのドメインは存在しない(またはスペルミス)
  • SERVFAIL は DNS サーバーが応答を返せなかった状態を示す

DNS レコードの種類と確認方法

レコード 用途 コマンド例
A IPv4 アドレス dig example.com A
AAAA IPv6 アドレス dig example.com AAAA
MX メールサーバー dig example.com MX
CNAME 別名 dig example.com CNAME
NS ネームサーバー dig example.com NS
PTR 逆引き dig -x 8.8.8.8

4. 切り分けフロー — 実務で使うパターン

障害切り分けは「どの層で起きているか」を絞り込む作業だ。以下の順序で確認する。

ステップ1: IP アドレスで ping が通るか

$ ping -c 4 8.8.8.8

通らない場合は L3 経路の問題。traceroute で詰まっている箇所を探す。

ステップ2: ホスト名で ping が通るか

$ ping -c 4 google.com

IP は通るがホスト名が通らない場合は DNS の問題。dig で確認する。

ステップ3: dig で名前解決できるか

$ dig @8.8.8.8 google.com

設定中の DNS サーバーでは解決できないが 8.8.8.8 では解決できる場合、/etc/resolv.conf の DNS 設定に問題がある。

よくある障害パターンと対処

パターン1: ゲートウェイには疎通できるが外に出られない

$ ping -c 4 192.168.1.1   # OK
$ ping -c 4 8.8.8.8       # NG

ルーター設定または ISP の問題。traceroute でどこまで届くか確認する。

パターン2: IP では到達できるがホスト名で解決できない

$ ping -c 4 8.8.8.8          # OK
$ ping -c 4 google.com       # NG

DNS の問題。まず /etc/resolv.conf で設定を確認し、別の DNS サーバーで試す。

$ cat /etc/resolv.conf
$ dig @8.8.8.8 google.com
$ dig @1.1.1.1 google.com

パターン3: 特定のポートのみつながらない

$ ping -c 4 example.com     # OK(ICMP は通る)
$ curl -v https://example.com  # NG(443 番ポートが通らない)

ファイアウォールの問題。ufw / firewalld / iptables を確認する。

$ sudo ufw status

ping が通っても HTTP/HTTPS が通らない場合がある。ICMP とアプリケーション層のプロトコルは別物。ポートレベルの疎通は nc(netcat)や curl -v で確認する。

5. systemd-resolved が干渉する場合

Ubuntu 18.04 以降では systemd-resolved が DNS クエリを仲介する。dig で問い合わせ先が 127.0.0.53 の場合は systemd-resolved 経由だ。

# 現在の DNS 設定を確認する
$ resolvectl status

# 外部 DNS に直接問い合わせて比較する
$ dig @8.8.8.8 google.com

外部 DNS では解決できて 127.0.0.53 では解決できない場合、systemd-resolved の設定または /etc/resolv.conf のシンボリックリンクに問題がある。

# /etc/resolv.conf の状態を確認する
$ ls -la /etc/resolv.conf

/etc/resolv.confstub-resolv.conf(systemd-resolved が管理)へのシンボリックリンクになっていることが正常な状態だ。

次に読む