Carpe Diem

備忘録。https://github.com/jun06t

ネットワークの疎通を確認する方法

概要

インスタンスのヘルスチェックに失敗したり、リクエストが届かなかったりするケースの調査のためにネットワークの疎通を確認する機会は多々あります。
今回はその中でよく使うコマンドをまとめてみました。

環境

  • Ubutnu 16.04

コマンド

ping

pingはICMPのエコー要求/応答機能を使った診断コマンドです。

疎通確認

$ ping google.com
PING google.com (216.58.200.206): 56 data bytes
64 bytes from 216.58.200.206: icmp_seq=0 ttl=54 time=2.329 ms
64 bytes from 216.58.200.206: icmp_seq=1 ttl=54 time=2.744 ms

ちなみにICMPはL3のプロトコルなのでポートは関係ありません

確認できないケース

pingはICMPを使っているため、途中経路でICMPを許可していない場合は疎通が確認できません。
例えばAWSはデフォルトではICMPが使えません。

$ ping my-aws-instance.co.jp
PING dev-api-1a-01.in.awa.io (10.74.200.200): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
Request timeout for icmp_seq 2
Request timeout for icmp_seq 3
Request timeout for icmp_seq 4

nc(netcat)

Linuxでポートの疎通確認を行う際によく使います。tcpudpどちらも対応しています。

疎通確認(tcp

$ nc -vz google.com 80
Connection to google.com 80 port [tcp/http] succeeded!

確認できないケース(tcp

$ nc -vz google.com 81
nc: connect to google.com port 81 (tcp) failed: Connection timed out
nc: connect to google.com port 81 (tcp) failed: Network is unreachable

疎通確認(udp

$ nc -u -vz localhost 12345
Connection to localhost 12345 port [udp/*] succeeded!

確認できないケース(udp

$ nc -u -vz localhost 12344
$

確認できない時は何も表示されず、すぐにコマンドが完了します。

Listenerを用意する

ncコマンドはサーバとして使うこともできます。疎通先でサーバとして起動し、クライアントから確認することでネットワーク自体が繋がっているか確認するケースもあります。

TCP

受信側
$ nc -l 12345
送信側
$ echo "This is a test" | nc 受信側IP 12345

UDP

受信側
$ nc -l -u 12345
送信側
$ echo "This is a test" | nc -u 受信側IP 12345

traceroute

どんな経路を辿っているか知りたい時に使います。ICMP/UDP/TCPを使うことができます。

疎通確認(デフォルト)

$ traceroute google.com
traceroute to google.com (172.217.27.78), 30 hops max, 60 byte packets
 1  ip-10-74-0-62.ap-northeast-1.compute.internal (10.74.0.62)  0.538 ms  0.546 ms  0.653 ms
 2  ec2-175-41-192-148.ap-northeast-1.compute.amazonaws.com (175.41.192.148)  14.272 ms  14.391 ms  14.286 ms
 3  100.64.2.76 (100.64.2.76)  15.782 ms  14.920 ms 100.64.3.12 (100.64.3.12)  21.983 ms
 4  100.64.0.197 (100.64.0.197)  21.806 ms 100.64.3.5 (100.64.3.5)  21.828 ms 100.64.0.1 (100.64.0.1)  13.379 ms
 5  100.64.17.41 (100.64.17.41)  2.131 ms 100.64.16.139 (100.64.16.139)  2.198 ms 100.64.17.55 (100.64.17.55)  2.590 ms
 6  52.95.30.211 (52.95.30.211)  3.430 ms 52.95.30.207 (52.95.30.207)  3.136 ms 52.95.30.215 (52.95.30.215)  3.109 ms
 7  52.95.30.133 (52.95.30.133)  1280.570 ms 52.95.30.129 (52.95.30.129)  1438.451 ms 52.95.30.131 (52.95.30.131)  1431.678 ms
 8  52.95.30.140 (52.95.30.140)  4.290 ms 52.95.30.138 (52.95.30.138)  2.476 ms 54.239.53.201 (54.239.53.201)  29.006 ms
 9  52.95.219.191 (52.95.219.191)  2.054 ms 52.95.216.117 (52.95.216.117)  2.208 ms 52.95.219.191 (52.95.219.191)  2.172 ms
10  * 108.170.242.97 (108.170.242.97)  2.334 ms  2.226 ms
11  108.170.236.5 (108.170.236.5)  1.837 ms  1.712 ms  1.919 ms
12  nrt12s15-in-f14.1e100.net (172.217.27.78)  1.878 ms  1.904 ms  1.750 ms

Linuxの場合、デフォルトの挙動ではプロトコルUDPを使います。 TTLを1つずつ増やし、宛先に辿り着くまではICMP Time Exceededが届き、宛先に辿り着くとICMP Destination Unreachable(Port Unreachable)が返ってくる、ということで疎通を確認する仕組みになっています。TTLは30まで増えます。
ポートが開いていない前提でリクエストを投げており、最初のポートは33434で、1つずつインクリメントされます。

疎通確認(tcp)

-Tオプションを付けます。デフォルトで使うポートは80ですが、今回は-pオプションで443に設定しています。

$ sudo traceroute -T -p 443 google.com 
traceroute to google.com (216.58.197.174), 30 hops max, 60 byte packets
 1  ip-10-74-0-62.ap-northeast-1.compute.internal (10.74.0.62)  0.416 ms  0.412 ms  0.440 ms
 2  * * *
 3  * * *
 4  * * *
 5  100.64.16.1 (100.64.16.1)  1.109 ms 100.64.16.55 (100.64.16.55)  1.109 ms 100.64.17.173 (100.64.17.173)  1.195 ms
 6  52.95.30.211 (52.95.30.211)  2.320 ms 52.95.30.207 (52.95.30.207)  2.171 ms 52.95.30.219 (52.95.30.219)  2.493 ms
 7  52.95.30.121 (52.95.30.121)  12.426 ms 52.95.30.123 (52.95.30.123)  6.051 ms 52.95.30.133 (52.95.30.133)  4.191 ms
 8  52.95.30.140 (52.95.30.140)  3.748 ms 52.95.30.138 (52.95.30.138)  3.220 ms 52.95.30.136 (52.95.30.136)  4.617 ms
 9  52.95.216.117 (52.95.216.117)  4.357 ms 52.95.219.191 (52.95.219.191)  4.356 ms  4.132 ms
10  108.170.242.97 (108.170.242.97)  4.191 ms *  2.664 ms
11  216.239.62.29 (216.239.62.29)  2.647 ms  2.070 ms 216.239.62.27 (216.239.62.27)  1.956 ms
12  nrt12s02-in-f14.1e100.net (216.58.197.174)  1.879 ms  1.787 ms  1.751 ms

注意としてポートが指定される場合、デフォルトの仕様と違ってそのポートが開いていなければ失敗になります

疎通確認(udp)

-Uオプションを付けます。デフォルトで使うポートは53です。分かりやすくするため、今回は-pオプションで明示的にしています。

$ traceroute -U -p 53 google.com
traceroute to google.com (172.217.27.78), 30 hops max, 60 byte packets
 1  ip-10-74-0-62.ap-northeast-1.compute.internal (10.74.0.62)  0.326 ms  0.364 ms  0.395 ms
 2  * * *
 3  * * *
 4  * * *
 5  100.64.17.141 (100.64.17.141)  1.096 ms 100.64.16.169 (100.64.16.169)  1.107 ms 100.64.17.3 (100.64.17.3)  1.166 ms
 6  52.95.30.219 (52.95.30.219)  2.362 ms 52.95.30.215 (52.95.30.215)  1.728 ms  2.675 ms
 7  52.95.30.127 (52.95.30.127)  5.924 ms 52.95.30.125 (52.95.30.125)  8.832 ms 52.95.30.133 (52.95.30.133)  6.000 ms
 8  52.95.30.144 (52.95.30.144)  2.837 ms 54.239.53.195 (54.239.53.195)  3.216 ms 52.95.30.142 (52.95.30.142)  1.775 ms
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  * * *
15  * * *
16  * * *
17  * * *
18  * * *
19  * * *
20  * * *
21  * * *
22  * * *
23  * * *
24  * * *
25  * * *
26  * * *
27  * * *
28  * * *
29  * * *
30  * * *

こちらもポートが指定されたケースで、開いていないので失敗になります。

疎通確認(icmp)

ICMPでも可能です。AWS上だとICMPを許可していないと使えないと思います。

$ traceroute -I google.com
traceroute to google.com (172.217.25.206), 64 hops max, 72 byte packets
 1  172.30.0.253 (172.30.0.253)  4.140 ms  4.021 ms  5.834 ms
 2  202.214.112.140 (202.214.112.140)  3.394 ms  4.248 ms  3.370 ms
 3  210.130.147.161 (210.130.147.161)  1.977 ms  2.622 ms  2.607 ms
 4  tky008bb01.iij.net (58.138.105.53)  2.787 ms  5.736 ms  3.154 ms
 5  tky008ix51.iij.net (58.138.104.134)  2.163 ms  12.774 ms  2.055 ms
 6  72.14.204.226 (72.14.204.226)  2.717 ms  3.066 ms  2.630 ms
 7  * * *
 8  216.239.62.24 (216.239.62.24)  11.798 ms  12.883 ms  33.652 ms
 9  108.170.233.15 (108.170.233.15)  4.184 ms  5.674 ms  6.224 ms
10  nrt12s13-in-f206.1e100.net (172.217.25.206)  3.768 ms  8.624 ms  3.645 ms

tcptraceroute

OSによってはtracerouteの-Tオプションが無く、tcpで検証できないこともあります。
その場合tcptracerouteというコマンドを別途使います。

疎通確認

$ sudo tcptraceroute google.com 443
Password:
Selected device en0, address 172.30.1.13, port 57921 for outgoing packets
Tracing the path to google.com (172.217.25.206) on TCP port 443 (https), 30 hops max
 1  172.30.0.253  3.535 ms  2.833 ms  2.432 ms
 2  202.214.112.140  3.288 ms  3.130 ms  2.895 ms
 3  210.130.147.161  1.685 ms  1.616 ms  1.643 ms
 4  tky008bb01.iij.net (58.138.105.49)  4.511 ms  2.223 ms  2.299 ms
 5  tky008ix50.iij.net (58.138.104.86)  1.733 ms  2.700 ms  2.778 ms
 6  210.130.133.78  3.372 ms  2.462 ms  2.622 ms
 7  108.170.226.179  2.233 ms  4.170 ms  2.561 ms
 8  108.170.233.17  2.926 ms  7.669 ms  6.372 ms
 9  nrt12s13-in-f206.1e100.net (172.217.25.206) [open]  2.883 ms  2.751 ms  3.863 ms

ソース