tracerouteで * (アスタリスク)になる理由
背景
「ネットワークがつながらない!」といったトラブルシューティングをしていると、
traceroute
の結果が、以下のように経路の途中で*
になる事象によく遭遇します。
今回はIPヘッダやパケットを見比べながら、なぜ*
になるのかを見ていきます。
$ traceroute 8.8.8.8 traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 52 byte packets 1 192.168.43.1 (192.168.43.1) 823.037 ms * 3.936 ms 2 * * * 3 osk004bb01.iij.net (202.32.116.5) 476.654 ms 132.676 ms 120.725 ms 4 osk004ix50.iij.net (58.138.107.218) 119.609 ms osk004ix50.iij.net (58.138.107.166) 133.204 ms osk004ix51.iij.net (58.138.107.222) 117.566 ms 5 72.14.210.182 (72.14.210.182) 126.614 ms 210.130.133.86 (210.130.133.86) 115.229 ms 118.843 ms 6 108.170.243.36 (108.170.243.36) 119.670 ms 108.170.243.68 (108.170.243.68) 134.219 ms 108.170.243.132 (108.170.243.132) 135.462 ms 7 209.85.255.163 (209.85.255.163) 141.621 ms 216.239.41.199 (216.239.41.199) 132.251 ms 138.545 ms 8 66.249.95.77 (66.249.95.77) 165.501 ms 108.170.235.231 (108.170.235.231) 155.299 ms 66.249.95.77 (66.249.95.77) 172.740 ms 9 216.239.43.101 (216.239.43.101) 153.654 ms 72.14.235.77 (72.14.235.77) 175.888 ms 64.233.175.209 (64.233.175.209) 156.037 ms 10 * * * 11 * * * 12 * * * 13 * * * 14 * * * 15 * * * 16 * * * 17 * * * 18 google-public-dns-a.google.com (8.8.8.8) 159.839 ms 156.416 ms 166.939 ms
※プロバイダによっては*
にならない場合もあるようです。
今回はDMMのSIMカードからテザリングしています。
ちなみに8.8.8.8
はGoogleのパブリックDNSのIPアドレスです。覚えやすいですね。
前提知識
IPヘッダのProtocolナンバー
RFC791でIPヘッダのフォーマットは以下のように定められています。
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
上記のProtocolフィールドが1
となるものがICMPとなります。
※ProtocolナンバーはRFC790
で規定されています。
TCP、UDP(User Datagram)もそれぞれ6
、17
がアサインされています。
ping実行時のパケットをWiresharkで見てみると以下のようにICMP(1)
となっていることがわかります。
tracerouteの仕組み
traceroute
は、冒頭のコマンド結果のように、宛先までのホップ情報を教えてくれる便利なコマンドです。
traceroute
は上記のIPヘッダにあるTime to Live(TTL)
を利用して実装されています。
TTLはパケットの寿命みたいなものです。誤ったルーティングが設定されたネットワークでは、度々ループが発生します。この時、ネットワークに入ってきたパケットがいつまでもループし続けると、ネットワークの帯域を逼迫させ、通信ができなくなります。それを避けるための方法として、ルータはパケットをフォワードする際にTTLを1ずつデクリメントします。TTLが0になったパケットを受信したルータは、そのパケットをフォワードせず、破棄します。これによってネットワークが輻輳まみれになることを防ぎます。
そしてTTLが0になったときtraceroute
の発行元に対して、TTLが0になったことを通知(Time Exceeded Message)します。
※これらはRFC792で以下のように規定されています。
If the gateway processing a datagram finds the time to live field is zero it must discard the datagram. The gateway may also notify the source host via the time exceeded message.
この通知には破棄したルータのIPアドレスが含まれています。
traceroute
ではTTLを1つずつインクリメントし、応答があったTime Exceeded Messageに含まれるIPアドレスを表示することで実装されています。
本題
前置きが長くなりましたが、いよいよ本題に入っていきます。
traceroute
は、WindowsではICMPを用いていますが、LinuxではUDPでポート番号33434 〜33534が使われます。traceroute
をFWで通す要件がある場合は、実装する際に注意が必要です。
今回はICMPのTTLをマニュアルで設定することで、traceroute
の仕組みを擬似的に再現し、*
の正体を探ります。
そのためtraceroute
に-I
オプションを付けてICMPでのtraceroute
結果を得ておきます。
$ traceroute -I 8.8.8.8 traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 72 byte packets 1 * * * 2 * * * 3 osk009nasgw111.iij.net (202.32.116.105) 132.515 ms 122.689 ms 119.731 ms 4 osk004bb01.iij.net (202.32.116.5) 117.981 ms 114.951 ms 121.114 ms 5 osk004ix51.iij.net (58.138.107.222) 123.171 ms 118.085 ms 122.172 ms 6 72.14.210.182 (72.14.210.182) 117.047 ms 122.246 ms 123.139 ms 7 108.170.243.66 (108.170.243.66) 117.916 ms 498.344 ms 149.948 ms 8 209.85.255.163 (209.85.255.163) 116.059 ms 132.291 ms 121.649 ms 9 72.14.233.211 (72.14.233.211) 159.789 ms 163.511 ms 173.399 ms 10 72.14.235.77 (72.14.235.77) 154.462 ms 153.933 ms 170.539 ms 11 * * * 12 * * * 13 * * * 14 * * * 15 * * * 16 * * * 17 * * * 18 * * * 19 google-public-dns-a.google.com (8.8.8.8) 168.872 ms 150.776 ms 161.775 ms
この時の通信の様子をWiresharkで見てみると以下のようになります。 TTLを1から順に増やしつつ、それぞれ3回送っていることがわかります。
勘の良い方はすでにお気づきかと思いますが、
traceroute
の結果が*
ではないものはTime Exceeded Messageを返しています。
逆に言えば、*
になっている箇所は応答がありません。
さらに詳しく見るためにTTLを設定したpingを打ってみましょう。
-m
オプションでpingのTTLを設定できます。
長いですが、以下結果です。
192.168.43.11
は自ホストのアドレスです。
$ ping -m 1 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 2 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 3 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 36 bytes from osk009nasgw111.iij.net (202.32.116.105): Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 5400 248e 0 0000 01 01 9958 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 4 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 76 bytes from osk004bb01.iij.net (202.32.116.5): Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 5400 80d2 0 0000 01 01 3d14 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 5 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 36 bytes from osk004ix51.iij.net (58.138.107.222): Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 5400 1fb3 0 0000 01 01 9e33 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 6 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 36 bytes from 72.14.210.182: Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 00 5400 3fb3 0 0000 01 01 7e33 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 7 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 36 bytes from 108.170.243.66: Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 80 5400 acc6 0 0000 01 01 10a0 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 8 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 148 bytes from 209.85.255.163: Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 80 5400 5d6e 0 0000 01 01 5ff8 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 9 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 148 bytes from 72.14.233.211: Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 80 5400 13e9 0 0000 02 01 a87d 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 10 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 36 bytes from 72.14.235.77: Time to live exceeded Vr HL TOS Len ID Flg off TTL Pro cks Src Dst 4 5 80 5400 6b01 0 0000 01 01 5265 192.168.43.11 8.8.8.8 --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 11 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 12 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 13 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 14 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 15 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 16 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 17 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 18 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 1 packets transmitted, 0 packets received, 100.0% packet loss
$ ping -m 19 -c 1 8.8.8.8 PING 8.8.8.8 (8.8.8.8): 56 data bytes 64 bytes from 8.8.8.8: icmp_seq=0 ttl=46 time=166.696 ms --- 8.8.8.8 ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 166.696/166.696/166.696/0.000 ms
確かにtraceroute
の結果が*
ではないものはTime Exceeded Messageを返していることがわかります。
しかもその応答をTTL=0
となったホップが返しているので、送信元アドレス(=tracerouteで表示するアドレス)もわかりました。
逆に*
になっている箇所はpacket loss
で応答なしのため、表示することができず、代替手段として*
を表示するしかないようですね。
またTTL=19
の最終の宛先では、通常のping応答と同様のメッセージが返ってきているので、これを自分でtraceroute
を実装するとしたら、「応答があったこと」を条件にループ止めるなどで実装できそうですね。
結論
traceroute
の結果、経路の途中で*
になるのは、そのホップが応答を返さないとき(フォワードのみする)。