この章では、TCP/IP ネットワークの一般的な障害追跡の方法と、そのために使用できるいくつかのツールについて説明します。この種のツールには、ping、ifconfig、netstat、route などがあります。
ネットワーク上での問題を示す最初の徴候は、1 つまたはいくつかのホストでの通信の消滅です。あるホストを初めてネットワークに追加したときに、そのホストがまったく作動状態にならない場合は、構成ファイルのどれかか、またはネットワークインタフェースに問題があることが考えられます。1 つのホストに突然問題が生じた場合は、ネットワークインタフェースに原因があると考えられます。ネットワーク上のホスト相互間の通信はできるが、他のネットワークとの通信ができないという場合は、ルータに問題があるか、または他のネットワークに問題があることが考えられます。
ifconfig プログラムを使用すればネットワークインタフェースに関する情報を入手でき、netstat を使用すればルーティングテーブルとプロトコル統計が表示できます。サードパーティのネットワーク診断プログラムから、さまざまの障害追跡ユーティリティが提供されています。詳細は、サードパーティのマニュアルを参照してください。
比較的はっきりしにくいのは、ネットワーク上でのパフォーマンス低下の原因です。たとえば、ping のようなツールを使用することで、ホストでのパケットの消失など、問題の原因を突き止めることができます。
ネットワークに障害が生じた場合は、以下のような処置によって、ソフトウェア関連の問題を診断し修正することができます。
RARP を実行している場合は、 ethers データベース内のイーサネットアドレスを検査して、個々のエントリが適正で現行のものであるかどうかを確認します。
telnet によりローカルホストに接続してみます。
ネットワークデーモン inetd が実行中であることを確かめます。そのためには、スーパーユーザとしてログインし、次のように入力します。
# ps -ef | grep inetd
inetd デーモンが実行中であれば、次の例に示すような出力が表示されます。
root 57 1 0 Apr 04 ? 3:19 /usr/sbin/inetd -s root 4218 4198 0 17:57:23 pts/3 0:00 grep inetd |
ping コマンドは、特定のホストとの IP 接続が存在しているかどうかを確認するために使用します。基本構文は次のとおりです。
/usr/sbin/ping host [timeout]
上記において、host は問題のマシンのホスト名です。オプションの timeout 引数は、ping がそのマシンに到達しようと試みる秒数を示し、デフォルトは 20 秒です。詳しい構文とオプションについては、ping(1M) のマニュアルページに説明があります。
ping を実行すると、ICMP プロトコルは、指定されたホストにデータグラムを送って、応答を求めます (ICMP は、TCP/IP ネットワーク上のエラー処理を担当するプロトコルです。詳細は、「ICMP プロトコル」を参照してください)。
次のように入力したとします。
$ ping elvis |
ホスト elvis が作動状態にあれば、次のメッセージが表示されます。
elvis is alive |
これは、elvis が ICMP の要求に応答したことを示します。しかし、elvis がダウン状態にあるかまたは ICMP パケットを受け取れなかった場合は、ping から次の応答が戻されます。
no answer from elvis |
マシンが作動状態にあるのにパケットが失われている疑いがある場合は、ping の s オプションを使用して、問題を追求することができます。たとえば次のように入力します。
$ ping -s elvis |
ping は、ユーザが割り込み文字を送るかまたはタイムアウトが生じるまで、elvis にパケットを送り続けます。画面上に現れる応答は次のようなものとなります。
PING elvis: 56 data bytes 64 bytes from 129.144.50.21: icmp_seq=0. time=80. ms 64 bytes from 129.144.50.21: icmp_seq=1. time=0. ms 64 bytes from 129.144.50.21: icmp_seq=2. time=0. ms 64 bytes from 129.144.50.21: icmp_seq=3. time=0. ms . . . ----elvis PING Statistics---- 4 packets transmitted, 4 packets received, 0% packet loss round-trip (ms) min/avg/max = 0/20/80 |
パケットロスの統計値は、ホストがパケットを失ったかどうかを示します。
ping が失敗した場合は、ifconfig と netstat が報告するネットワーク状態を調べます。これについては、次の 「ifconfig コマンド」と、「netstat コマンド」を参照してくだい。
ifconfig コマンドは、指定したインタフェースの構成に関する情報を表示します (詳細は、ifconfig(1M) のマニュアルページを参照してください)。ifconfig の構文は次のとおりです。
ifconfig interface-name [protocol_family]
特定のインタフェース、たとえば le0 に関する情報を表示したい場合は、次のように入力します。
$ ifconfig le0 |
le0 インタフェースの場合は、出力は次のようなものになります。
le0: flags=863<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 129.144.44.140 netmask ffffff00 broadcast 129.144.44.255 ether 8:0:20:8:el:fd |
上記の flags セクションは、インタフェースが "up" として構成されていて、ブロードキャストの能力があり、"trailer" リンクレベルのカプセル化を使用していないことを示しています。mtu フィールドは、このインタフェースの最大転送速度が 1500 であることを示しています。2 行目には、使用しているホストの IP アドレス、現在使用されているネットマスク、そして、インタフェースの IP ブロードキャストアドレスの情報が含まれています。3 行目は、ホストのマシンアドレス (この場合はイーサネット) です。
ifconfig の便利なオプションの 1 つに -a があります。これを使用すると、ネットワーク上のすべてのインタフェースに関する情報が提供されます。たとえば、ifconfig -a と入力したとします。
le0: flags=49<UP,LOOPBACK,RUNNING> mtu 8232 inet 127.144.44.140 netmask ff000000 le0:flags=863<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 129.144.44.140 netmask ffffff00 broadcast 129.144.44.255 ether 8:0:20:8:el:fd |
出力が、実行されていないインタフェースがあることを示している場合は、そのインタフェースに問題があることが考えられます。その場合は、ifconfig(1M) のマニュアルページを参照してください。
netstat コマンドは、ネットワーク状態とプロトコル統計を表示します。TCP と UDP のエンドポイントの状態 (テーブル形式)、ルーティングテーブルの情報、そしてインタフェースの情報を表示できます。
netstat は、選択したコマンド行オプションに応じて、さまざまな種類のデータを表示します。この表示は、特にシステム管理に役立ちます。このコマンドの構文は次のとおりです。
netstat [-m] [-n] [-s] [-i | -r] [-f address_family]
ネットワーク状態の判別のために最もよく使われるオプションは、 s、r、i です。オプションの説明については、netstat(1M) のマニュアルページを参照してください。
netstat -s オプションは、UDP、TCP、ICMP、IP プロトコルについて、プロトコル別の統計を表示します。結果は、下に示す出力例のように表示されます (出力の一部は省略してあります)。この情報には、プロトコルに問題のある箇所が示されることがあります。たとえば、ICMP からの統計情報には、このプロトコルがどこにエラーを検出したかを示すことがあります。
UDP udpInDatagrams = 39228 udpOutDatagrams = 2455 udpInErrors = 0 TCP tcpRtoAlgorithm = 4 tcpMaxConn = -1 tcpRtoMax = 60000 tcpPassiveOpens = 2 tcpActiveOpens = 4 tcpEstabResets = 1 tcpAttemptFails = 3 tcpOutSegs = 315 tcpCurrEstab = 1 tcpOutDataBytes = 10547 tcpOutDataSegs = 288 tcpRetransBytes = 8376 tcpRetransSegs = 29 tcpOutAckDelayed = 23 tcpOutAck = 27 tcpOutWinUpdate = 2 tcpOutUrg = 2 tcpOutControl = 8 tcpOutWinProbe = 0 tcpOutFastRetrans = 1 tcpOutRsts = 0 tcpInSegs = 563 tcpInAckBytes = 10549 tcpInAckSegs = 289 tcpInAckUnsent = 0 tcpInDupAck = 27 tcpInInorderBytes = 673 tcpInInorderSegs = 254 tcpInInorderBytes = 673 tcpInUnorderSegs = 0 tcpInUnorderBytes = 0 tcpInDupSegs = 0 tcpInDupBytes = 0 tcpInPartDupSegs = 0 tcpInPartDupBytes = 0 tcpInPastWinSegs = 0 tcpInPastWinBytes = 0 tcpInWinProbe = 0 tcpInWinUpdate = 237 tcpInClosed = 0 tcpRttNoUpdate = 21 tcpRttUpdate = 266 tcpTimRetrans = 26 tcpTimRetransDrop = 0 tcpTimKeepalive = 0 tcpTimKeepaliveProbe= 0 tcpTimKeepaliveDrop = 0 IP ipForwarding = 2 ipDefaultTTL = 255 ipInReceives = 4518 ipInHdrErrors = 0 ipInAddrErrors = 0 ipInCksumErrs = 0 ipForwDatagrams = 0 ipForwProhibits = 0 ipInUnknownProtos = 0 ipInDiscards = 0 ipInDelivers = 4486 ipOutRequests = 2805 ipOutDiscards = 5 ipOutNoRoutes = 0 ipReasmTimeout = 60 ipReasmReqds = 2 ipReasmOKs = 2 ipReasmReqds = 2 ipReasmDuplicates = 0 ipReasmFails = 0 ipFragOKs = 20 ipReasmPartDups = 0 ipFragCreates = 116 ipFragFails = 0 tcpInErrs = 0 ipRoutingDiscards = 0 udpInCksumErrs = 0 udpNoPorts = 33 rawipInOverflows = 0 udpInOverflows = 6 ICMP icmpInMsgs = 0 icmpInErrors = 0 icmpInCksumErrs = 0 icmpInUnknowns = 0 icmpInDestUnreachs = 0 icmpInTimeExcds = 0 icmpInParmProbs = 0 icmpInSrcQuenchs = 0 icmpInRedirects = 0 icmpInBadRedirects = 0 icmpInEchos = 0 icmpInEchoReps = 0 icmpInTimestamps = 0 icmpInTimestampReps = 0 icmpInAddrMasks = 0 icmpInAddrMaskReps = 0 icmpInFragNeeded = 0 icmpOutMsgs = 7 icmpOutDestUnreachs = 1 icmpOutErrors = 0 icmpOutDrops = 5 icmpOutTimeExcds = 0 icmpOutParmProbs = 0 icmpOutSrcQuenchs = 6 icmpOutRedirects = 0 icmpOutEchos = 0 icmpOutEchoReps = 0 icmpOutTimestamps = 0 icmpOutTimestampReps= 0 icmpOutAddrMasks = 0 icmpOutAddrMaskReps = 0 icmpOutFragNeeded = 0 icmpInOverflows = 0 IGMP: 0 messages received 0 messages received with too few bytes 0 messages received with bad checksum 0 membership queries received 0 membership queries received with invalid field(s) 0 membership reports received 0 membership reports received with invalid field(s) 0 membership reports received for groups to which we belong 0 membership reports sent
netstat の i オプションは、このコマンドを実行したマシンで構成されているネットワークインタフェースの状態を示します。次に示すのは、netstat i により生成される表示の例です。
Name Mtu Net/Dest Address Ipkts Ierrs Opkts Oerrs Collis Queue le0 1500 b5-spd-2f-cm tatra 14093893 8492 10174659 1119 2314178 0 lo0 8232 loopback localhost 92997622 5442 12451748 0 775125 0
この表示から、各ネットワークについてマシンが送信し受信したとみなしているパケットの数が分かります。たとえば、サーバについて表示される入力パケットカウント (Ipkts) はクライアントがブートを試みるたびに増加しているのに、出力パケットカウント (Opkts) が変化しないことがあります。これは、サーバがクライアントからのブート要求パケットを見ているが、それを応答すべきものとして認識していないことを示しています。この原因としては、hosts データベースまたは ethers データベース内に誤ったアドレスがあることが考えられます。
逆に、入力パケットカウントが長時間にわたり変化しないとすれば、それは、マシンがまったくパケットを見ていないことを意味します。この原因としては、上記の場合と違って、ハードウェアの問題の可能性が高くなります。
netstat の -r オプションは、IP ルーティングテーブルを表示します。次に示すのは、マシン tenere で実行した netstat -r の結果の表示サンプルです。
Routing tables Destination Gateway Flags Refcnt Use Interface temp8milptp elvis UGH 0 0 irmcpeb1-ptp0 elvis UGH 0 0 route93-ptp0 speed UGH 0 0 mtvb9-ptp0 speed UGH 0 0 . mtnside speed UG 1 567 ray-net speed UG 0 0 mtnside-eng speed UG 0 36 mtnside-eng speed UG 0 558 mtnside-eng tenere U 33 190248 le0
最初の列は宛先ネットワークを、そして 2 番目の列はパケットを転送するルータを示しています。U フラグは送信経路が up 状態であること、G フラグは送信経路がゲートウェイへのものであることを示します。H フラグは、宛先がネットワークではなく、完全指定のホストアドレスであることを示します。
Refcnt 列は 1 送信経路当たりの有効ユーザの数、Use 列は 1 送信経路当たりの送信パケット数を示します。最後の Interface 列は、送信経路で使用されているネットワークインタフェースを示します。
ルーティングデーモンについて誤動作の疑いがある場合は、すべてのパケット転送も含めてそのデーモンの動作をログに記録することができます。ルーティングデーモンの動作のログファイルを作成するには、routed デーモンを起動するときにファイル名を指定します。たとえば次のように入力します。
# /usr/sbin/in.routed /var/routerlog |
ビジー状態のネットワークでは、ほとんど絶え間なく出力が生じることがあります。
snoop を使用すると、ネットワークパケットを取得して内容を表示できます。取得したパケットについては、そのまま表示することも、ファイルに保存することも可能です。snoop が中間ファイルに書き込む場合、トレースのビジー状態でパケットロスはほとんど発生しません。その後、snoop 自体はファイルの解釈に使用されます。詳細は、snoop(1M) のマニュアルページを参照してください。
snoop コマンドは必ず root(#) になって実行します。プロミスキュアス (promiscuous) モードでデフォルトのインタフェースとやりとりするパケットを取得できます。最高レベルのプロトコルに関連するデータのみが一覧形式で表示されます。たとえば NFS パケットでは、NFS 情報のみが表示されます。RPC、UDP、IP、および Ethernet のフレーム情報は抑止されますが、verbose (詳細表示) オプションのいずれかを選択してあれば表示できます。
snoop が取得するファイル形式は、RFC 1761 で説明しています。アクセスするには、ウェブブラウザで URL に http://ds.internic.net/rfc/rfc1761.txt を指定します。
snoop server client rpc rstatd は、クライアント/サーバ間の RPC トラフィックをすべて収集し、rstatd に対するフィルタをかけます。
netstat -i と入力し、システムに接続されたインタフェースを検索します。
通常、snoop では最初の非ループバックデバイス (le0) が使用されます。
root になって snoop と入力します。
Ctrl -C でプロセスを停止します。
# snoop Using device /dev/le (promiscuous mode) maupiti -> atlantic-82 NFS C GETATTR FH=0343 atlantic-82 -> maupiti NFS R GETATTR OK maupiti -> atlantic-82 NFS C GETATTR FH=D360 atlantic-82 -> maupiti NFS R GETATTR OK maupiti -> atlantic-82 NFS C GETATTR FH=1A18 atlantic-82 -> maupiti NFS R GETATTR OK maupiti -> (broadcast) ARP C Who is 129.146.82.36, npmpk17a-82 ?
結果を解釈します。
上の例の場合、クライアント maupiti からサーバ atlantic-82 への転送には NFS ファイルハンドル 0343 が使用され、atlantic-82 は OK と応答しています。who is 129.146.82.36? と問い合わせる ARP 要求が maupiti から伝送されるまで、会話は継続します。
この例は、snoop の形式を説明しています。次の手順では、snoop にフィルタをかけてファイルにパケットを取り込みます。
取り込んだファイルを解釈する際には、RFC 1761 に記述された説明を使用します。アクセスするには、ウェブブラウザで URL に http://ds.internic.net/rfc/rfc1761.txt を指定します。
root になって snoop -o filename の形式で入力します。たとえば、次のようになります。
# snoop -o /tmp/cap Using device /dev/le (promiscuous mode) 30 snoop: 30 packets captured |
これによって、ファイル /tmp/cap に 30 ものパケットが取り込まれました。ディスク容量が足りる場所であれば、ファイルはどこにでも格納できます。取り込んだパケットの数はコマンド行に表示され、Ctrl-C を押せばいつでも終了できます。
snoop によってホストマシン上のネットワーク負荷が顕著になることで、結果に誤差が生じる場合があります。実際の状況を確認するには、第 3 のシステムから snoop を実行してください (次の節を参照)。
snoop -i filename の形式で入力し、ファイルを検査します。
# snoop -i /tmp/cap 1 0.00000 frmpk17b-082 -> 224.0.0.2 IP D=224.0.0.2 S=129.146.82.1 LEN=32, ID=0 2 0.56104 scout -> (broadcast) ARP C Who is 129.146.82.63, grail ? 3 0.16742 atlantic-82 -> (broadcast) ARP C Who is 129.146.82.76, honeybea ? 4 0.77247 scout -> (broadcast) ARP C Who is 129.146.82.63, grail ? 5 0.80532 frmpk17b-082 -> (broadcast) ARP C Who is 129.146.82.92, holmes ? 6 0.13462 scout -> (broadcast) ARP C Who is 129.146.82.63, grail ? 7 0.94003 scout -> (broadcast) ARP C Who is 129.146.82.63, grail ? 8 0.93992 scout -> (broadcast) ARP C Who is 129.146.82.63, grail ? 9 0.60887 towel -> (broadcast) ARP C Who is 129.146.82.35, udmpk17b-82 ? 10 0.86691 nimpk17a-82 -> 129.146.82.255 RIP R (1 destinations)
ARP、IP、RIP その他の詳細な分析と推奨されるパラメタについては、特定のプロトコルのマニュアルを参照してください。RFC の確認には、ウェブを検索することをお奨めします。
クライアントかサーバに接続されたハブを外した snoop システムを確立します。
第 3 のシステム (snoop システム) はすべてのトラフィックを監視するので、snoop のトレースには実際の状況が反映されます。
root になって snoop をオプション付きで入力し、ファイルに保存します。
結果の検査と解釈を行います。
snoop 取り込みファイルの詳細については、RFC 1761 に記述された説明を使用します。アクセスするには、ウェブブラウザで URL に http://ds.internic.net/rfc/rfc1761.txt を指定します。
頻繁かつ定期的に snoop を使用して、システムが正常に動作する感覚をつかんでください。最近の白書や RFC を参照したり、NFS や YP といった特定分野の専門家からアドバイスを受けるのも、パケットの分析に役立ちます。snoop とそのオプションの使用法についての詳細は、snoop(1M) のマニュアルページを参照してください。