ICMP – ping, traceroute 詳細説明

Contents


ICMPとはネットワークを制御するためのプロトコルです。疎通確認で使用するping, tracerouteは、ICMPを利用した仕組みのひとつです。

このページでは、ICMP, ping, tracerouteに関する深い知識とよくある誤解について説明します。CCIE R&S ラボ試験では、ICMPのport unreachable, time exceeded, packet too bigの意味を正しく理解しないと、設定どころか問題文の意味すら理解できません。

tracert_start_wars_001

ICMPとは

ICMP – protocol number

ICMPは、以下の誤解が巷にあふれています。

  • ICMPはUDPである
  • ICMPはLayer3のプロトコルである

これら主張は大嘘です。知恵袋などの質問サイトを見ると、「pingのポート番号を教えて下さい」等の質問がありますが、ICMPはTCPでもUDPでもありません。このような誤った概念を持たないようにするには、まずはIPのprotocol numberの概念を理解する必要があります。

IP headerの中にはprotocol numberというフィールドが存在し、上位プロトコル(Layer 4)が何であるかを表します。例えば、protocol numberが1ならばICMPを表します。主なprotocol numberは以下の通りです。

protocol numberプロトコル名説明
1ICMPネットワークに関する制御を行ないます。
6TCP再送制御のある信頼性のある通信を実現します。
17UDP再送制御がない代わりに高速でオーバーヘッドの少ない通信を実現します。
88EIGRPCisco独自のルーティングプロトコルです。
89OSPF標準のルーティングプロトコルです。
112VRRPデフォルトゲートウェイの冗長化を行ないます。

実際にICMPを利用しているpingをパケットキャプチャしてみると、protocol numberが1である事が分かります。

以上のことから、ICMPとはLayer 4のプロトコルである事がお分かり頂けたと思います。

ICMP – type & code

ICMP headerの中には、typeと呼ばれるフィールドがあります。このtypeによって、ICMPの役割が異なります。最も有名なのが、pingコマンドが使用するecho request, echo(echo-reply)です。

ICMPのtypeとその役割をまとめると以下の表のようになります。

type名称Cisco ACLの表記説明
0echo replyecho-replyecho requestに対する応答です。
3destination unreachableunreachable到達不能を意味します。
host unreachable, port unreachableなどが存在します。
5redirectredirectより良い経路がある旨を伝えるメッセージです。
8echo requestecho応答を要求します。
11time exceededtime-exceededTTLが0になった旨を伝えるメッセージです。
17mask requestmask-requestサブネットマスクを要求します。
18mask replymask-replymask replyに対する応答です。

ICMP type 3である”destination unreachable”は、さらにcodeと呼ばれるフィールドが存在し、さらに細分されます。CCIEを目指すならば、host unreachable, port unreachableの違いくらいは説明できて当たり前です。

ICMPのtype codeをまとめると以下のようになります。

typecode名称Cisco ACLの表記説明
31host unreachable host-unreachable宛先ホストがルーティングテーブル上に存在しない場合に
返すメッセージです。
33port unreachableport-unreachableLISTENしていないポート宛てのTCP, UDPを
受信した場合に返すメッセージです。
34packet too bigpacket-too-bigMTU sizeを上回り かつ DF bitが付与されている場合、
分割不可能である旨を返すメッセージです。

Ping

ping 概要

pingは到達可能かどうかを調査するためのコマンドです。多くのOSはICMP echo requestを送信し、requestを受け取ったマシンはICMP echo replyを返す事によって、ネットワークの到達可能を確認する事ができます。

ping パケットキャプチャ

それでは、pingの仕様を確認するために、パケットキャプチャを試みてみます。pingの送信側が送るパケット、すなわち、ICMP echo requestは以下のようになります。ICMP type 8と書かれている事が読み取れます。

pingの受信側が送るパケット、すなわち、ICMP echo replyは以下のようになります。ICMP type 8と書かれている事が読み取れます。

Ping 応答許可設定

CCIE R&S ラボ試験とは関係ありませんが、実践ではどのようにすればping応答を返すのかを知っておくのはとても良い事だと思います。よく「pingが通らない、すなわち、ネットワークに問題がある」と誤解する人が多いですが、設定によってはpingを拒否している事があります。

例えば、Windows OSの場合は、デフォルトでpingを拒否しています。Windowsファイアウォールの画面で”エコー要求”を許可する事によって、pingに応答するようになります。

ping_allow_001

Linux環境のiptablesならば、”-p icmp”というのがpingを許可する設定になります。

最近の話題になりますが、AWSもデフォルトではpingに応答しません。デフォルト設定のセキュリティグループはSSHのみを許可しているので、pingに応答するようにしたいならば、以下のように”ALL ICMP”を許可する必要があります。

ping_allow_002

TraceRoute

TraceRoute 概要

TraceRouteは通信経路を調べるコマンドです。TTL(Time to Live)の値を1,2,3と徐々に大きくしながらパケットを送る事によって、通信経路を調べます。

TTL(Time To Live)は、パケットの寿命を表す概念で、ルータを経由する毎に1つずる値が減っていきます。TTLが0になると、寿命が尽きた旨を送信元に知らせるため、ICMPのtime exceededを返します。

このような仕組みを利用するのがTraceRouteです。TTLが1のパケットを送れば、1 hop 離れた機器がICMP time exceededを返します。TTLが2のパケットを送れば、2 hop 離れた機器がICMP time exceededを返します。このような応答を利用して誰がICMP time exceededを返すのかによって通信経路を推測するのが、TraceRouteです。

traceroute パケットキャプチャ

tracerouteの仕様を理解するため、tracerouteコマンド実行時のパケットをキャプチャしてみましょう。tracerouteを送る側のパケットは以下のようになります。UDP port 33434からポート番号を1つずつ大きくしながらパケットを送っている事が読み取れます。

このUDPパケットの詳細を眺めると、TTLが小さい値である事が分かります。

通信経路上の機器が返すパケットを観察します。ICMP type 11であるtime exceededが返されている事が読み取れます。

tracerouteの宛先となる機器が返すパケットを観察します。宛先となる機器はUDP port 33463が送られてきても、そんなportではListenしていません。ですので、宛先となる機器はICMP type 3 code 3であるport unreachableを返します。

traceroute OSによる仕様の違い

tracerouteはOSによって仕様が異なり、UDPを使用する場合とICMPを使用する場合の両方があります。

OS仕様説明
Cisco IOSUDPによるtracerouteを行ないます。
WindowsICMPによるtracerouteを行ないます。
LinuxデフォルトはUDPですが、オプション次第ではICMPも可能です。

traceroute 便利テクニック

前述のパケットキャプチャの通り、tracerouteを許可するには、UDP, ICMP time exceeded, ICMP port unreachableの3つを許可しなければなりません。世の中の全てのネットワークエンジニアが、ここまで細かい仕様を知っているわけではありません。ですので、意図せずファイアウォールでtracerouteが拒否されているというのはよくある話です。

ここで知っておきたい便利なテクニックがICMP tracerouteです。もし、UDP tracerouteが拒否されてデバッグが困難になる場合は、ICMP tracerouteを試みて下さい。UDPはダメでも、ICMPならばうまく行く事はよくあります。Linux環境で、ICMP tracerouteを使用するには、-Iを使用します。

Windows 環境でよくある事ですが、tracerouteの名前解決待ちでイライラする事があるかもしれません。そのような場合は、-dオプションで名前解決を行なわないようにする事ができます。

PMTU Discovery

MTU(Maximum Transmission Unit)とは

MTU (Maximum Transmission Unit)とは、一回の伝送で転送できるパケット長の事です。大きなデータ長のデータを送付する際は、MTU sizeに区切ってパケットが送付されます。Cisco機の場合は、デフォルト設定で1500byteとなっています。

DF bit

DF(Don’t Fragment) bitとは、MTU sizeを超過した場合にFragmentを行うかどうかを決める仕様です。IPヘッダーは以下のようなフォーマットになっており、IPヘッダー内のFlagsフィールド内にDF bitが含まれています。

DF bitがセットされていない場合は、パケットはMTU size以下にフラグメント(分割)されます。パケットの分割/再組立の分だけリソースを消費し、またヘッダーのオーバーヘッドが大きくなるため、伝送効率が落ちます。

一方、DF bitがセットされている場合は、MTU sizeを超過している旨を送信元に伝え、送信元がMTU size以下でパケットを送るようにします。伝送効率が落ちないメリットがあるものの、MTU sizeが超過している旨を送信元に正常に返さない場合は疎通不能になってしまうデメリットがあります。この疎通不能現象は、PMTU Discovery blackholeと呼ばれる現象で、後程、詳しく説明します。

改めてDF bitのメリット・デメリットをまとめ直すと以下のようになります。

DF bitOFFON
伝送効率MTU sizeを超過すると伝送効率が落ちるMTU sizeを超過しても伝送効率が落ちない
PMTU Discovery Blackholeによる疎通不能疎通不能は発生しない疎通不能が発生しうる

クライアントOSは伝送効率を落ちる事を嫌うのか、WindowsもRedhatもデフォルトの挙動はDF bitを付与してパケットを送信します。以下はWindows 7から送信されるパケットをキャプチャした結果で、確かにDF bitが付与されている事が読み取れます。

PMTU Discoveryとは

PMTU Discoveryとは、経路上のMTUサイズを調査する仕組みの事です。Path MTU Discoveryや経路MTU探索と表記される事もあります。

さて、PMTU Discoveryの仕組みについて説明しましょう。ネットワーク機器はMTUサイズを超過するパケットを受信すると、パケットの送信元にMTUサイズを超過する事を伝えます。この時送信されるパケットがICMP type 3 code 4のpacket too bigです。送信元はpacket too bigを受信すると、MTUサイズ以下の大きさでパケットを送信し効率よく伝送するようになります。このようにMTUサイズ以下に調整する仕組みの事を「PMTU Discovery」と呼んでいます。

それでは、ICMP packet too bigのパケットを観察してみましょう。ICMP type 3 code 4である事が分かります。また、パケット内にMTUサイズを保持する事によって、送信元にMTUサイズを伝えている事が分かります。

PMTU Discovery Blackholeとは

先ほど、PMTU DiscoveryはICMP packet too bigによって通知される仕組みである事を説明しました。しかし、セキュリティ上の理由で「全てのICMP」が拒否されていたら、どのような現象になるでしょうか。送信元はICMP packet too bigを受信できないため、タイムアウト待ちの状態になってしまいます。このようなパケットが消えてしまい疎通不能になる現象を「PMTU Discovery Blackhole」と呼びます。

PMTU Discovery Blackholeの原因

情報処理技術者試験のような残念な資格本を読むと「pingを返す事はサーバ情報を教える事になりセキュリティの観点では望ましい事ではない。だからICMPを拒否すべきだ。」のような乱暴な主張があります。このような乱暴な設定を行うから、必要な通信まで拒否してしまう事になります。

ここまで読んで頂いた方ならば、お気づきかと思いますが、ICMPはping, tracerouteのためだけのプロトコルではありません。Internet Control Message Protocolの略称であるように、インターネットを制御するためのプロトコルです。制御情報までフィルタするから、PMTU Discovery Blackholeのような現象が発生してしまいます。

どうしてもpingを拒否したいならば、以下のように必要最小限のプロトコルを拒否すべきです。

または、以下のように経路制御で使う最小限のメッセージ unreachable, time-exceededのみを許可するように設定しても良いでしょう。

ICMP 応答可否の設定

Ciscoのネットワーク機器は、ICMPの応答を返すかどうかを制御する事ができます。いつもよく使う「show ip interface」コマンドを注意深く見ると、ICMP redirects, ICMP unreachables, ICMP mask repliesに関して応答を返すかどうか制御できる事が分かります。

redirect message

より良い経路がある場合は、ICMP redirectと呼ばれるメッセージを返送する事によって、送信元により良い経路を伝える事があります。デフォルトではICMP redirectは有効になっていますが、敢えて無効化したい場合は、以下のように「no ip redirects」コマンドを使用します。

host unreachable

パケットを受信したものの、その宛先がルーティングテーブルに載っておらず到達不能となる場合は、host unreachableと呼ばれるメッセージを返します。個人的には過剰セキュリティと思いますが、「host unreachableを返すのは内部ネットワーク構造を教える事になるので、host unreachableは返すべきではない」という意見も存在します。もし、このような意見を採用し、敢えてhost unreachableを無効化したい場合は、以下のように「no ip unreachables」コマンドを使用します。

mask reply

最近では使用する事は滅多にありませんが、ICMPの中にはサブネットマスクを要求するものもあります。その応答がICMP mask replyです。ICMP mask replyを無効化したい場合は、「no ip mask-reply」コマンドを使用します。

ICMP rate limit

unreachable rate limit

ICMPのunreachableを返す処理は、それなりに負荷のかかる処理です。そのため、DOS攻撃対策として、cisco IOSにはunreachableを返す頻度を制限する流量制限の機能が備わっています。

「ip icmp rate-limit unreachable」コマンドで、unreachableを返す間隔を定義する事がでいます。例えば、10msecと設定すれば、単純計算で1秒間で100回のunreachableを返すという意味になります。コマンドの構文は以下の通りです。

unreachable DF rate limit

先ほどの「ip icmp rate-limit unreachable」コマンドで制限されるのは、全てのunreachableメッセージです。host unreachableもport unreachableもpacket too bigも同じように制御対象になります。

しかし、packet too bigを制限してしまうと、PMTU Discovery Blackholeの原因となってしまうリスクがあります。そこでpacket too bigのみ個別で流量制限を設定する事ができます。設定コマンドは以下の通りです。

例えば、以下のように2種類の閾値を設けると、packet too bigは秒間100回まで(10msec間隔で)応答するものの、それ以外のunreachableは秒間10回まで(100msec間隔で)応答するように設定する事ができます。

以下のような設定例にすれば、packet too bigは流量制限なしで、それ以外のunreachableは秒間10回まで(100msec間隔で)応答するようになります。

ICMPの動作確認

ネットワーク構成図

以下の環境で動作確認を行います。

20150214_icmp_ipv4

初期設定

R1, R2, R3はOSPFによるルーティングを行います。HOST4はルーティングを無効化しデフォルトゲートウェイをR3に向けます。

初期設定全文は以下の通りです。

pingの通信許可設定

検証目的

以下のようなR1からR3へのpingについて、最小限の許可設定を考察し、pingがecho request, echo replyを使っている事に対する理解を深めます。

設定投入

pingの行き方向の通信はecho request (ACL表記は”echo”) を使用します。R2 f0/0に以下のアクセスリストを設定し、pingのみを許可する設定を投入します。

pingの戻り方向の通信はecho replyを使用します。R1 f0/0に以下のアクセスリストを設定し、pingのみを許可する設定を投入します。

動作確認 – 疎通確認

R1からR3へのpingが疎通可能である事を確認します。

ping以外の通信を禁止されている事を確認するために、traceroute, telnetを実行します。traceroute, telnetが疎通不能である事を確認します。

動作確認 – アクセスリストカウンタ上昇の確認

アクセスリストのカウンタを確認し、確かにpingがecho, echo-replyを使用している事を確認します。

設定削除

R1, R2のACLを削除してから、次の動作確認に望みます。

tracerouteの通信許可設定

検証目的

以下のようなR1からR3へのtracerouteについて、最小限の許可設定を考察し、pingがudp, time-exceeded, port-unreachableを使っている事に対する理解を深めます。

設定投入

tracerouteの行き方向の通信はudp 33434-33523を使用します。R2 f0/0に以下のアクセスリストを設定し、tracerouteのみを許可する設定を投入します。

tracerouteの戻り方向の通信はtime-exceeded, port-unreachableを使用します。R1 f0/0に以下のアクセスリストを設定し、tracerouteのみを許可する設定を投入します。

動作確認 – 疎通確認

R1からR3へのtracerouteが疎通可能である事を確認します。

traceroute以外の通信を禁止されている事を確認するために、ping, telnetを実行します。ping, telnetが疎通不能である事を確認します。

動作確認 – アクセスリストカウンタ上昇の確認

アクセスリストのカウンタを確認し、確かにtracerouteがudp, time-exceeded, port-unreachableを使用している事を確認します。

設定削除

R1, R2のACLを削除してから、次の動作確認に望みます。

packet too bigの観察

検証目的

DF(Don’t Fragment) bitがONとなっているパケットがMTUが小さい経路を通過しようとした時に、ルータはフラグメントが必要な旨を返すために、packet too bigを返します。Cisco IOSのping表示からpacket too bigが返される様子を観察します。

Cisco IOSを用いてPMTU Discoveryを再現されるのは困難であるため、PMTU Discoveryの確認は省略します。

設定投入

R2からR3への経路について、MTU sizeを小さめに設定します。R2に以下の設定を投入します。

MTU sizeを超過した場合に、確かにpacket too bigが返されている事を確認するため、以下のようなアクセスリストを作成します。

動作確認 – 疎通確認

R1からR3へのpingを送信します。Cisco IOSのpingはデフォルトでdf-bitを付与しませんので、packet too bigを確認する際は、df-bitを引数に与えてpingを実行します。

packet too bigによる到達不能を示す「M」の文字が現れる事を確認します。

動作確認 – アクセスリストカウンタ上昇の確認

アクセスリストのカウンタを確認し、確かにpacket too bigが返された事を確認します。

ICMP redirectの観察

検証目的

デフォルトではICMP redirectが有効になっており、より良い経路がある場合は、ICMP redirectが返される事を確認します。

また、「no ip redirects」コマンドにより、icmp redirectを無効化できる事を確認します。

動作確認 – デフォルトの挙動

Cisco IOSはデフォルトでicmp redirectが有効になっています。

HOST4からR1へのpingを送信し、R3からicmp redirectが返される事を確認します。HOST4のデフォルトゲートウェイはR3になっていますが、R2にpingを送ったほうが近道ですので、R3は「R2の方が近道である」旨を伝えるためにicmp redirectを返します。

icmp redirectが返されたかどうかを確認可能にするため、HOST4に以下のようなアクセスリストを作成します。

HOST4でicmpのデバッグを有効にします。

HOST4からR1へのpingを送信します。

「ICMP: redirect rcvd」というログ出力より、ICMP redirectが返された事を確認します。

アクセスリストのカウンタより、ICMP redirectが返された事を確認します。

設定投入

R3のicmp redirectを無効化します。

インターフェース単位のICMP設定は、show ip interfaceコマンドで確認できます。「ICMP redirects are never sent」と表示されている事より、icmp redirectが無効化されている事を確認します。

動作確認 – ICMP redirect 無効時の挙動

HOST4のアクセスリストカウンタをクリアします。

HOST4からR1へのpingを送信します。

カウンタが上昇していない事より、確かにicmp redirectがなくなった事が確認できます。

ICMP host unreachableの観察

検証目的

ネットワーク機器はルーティングテーブルに存在しない経路を受け取った時に、host unreachableを送信元に返し到達不能を知らせます。このhost unreachableがCisco IOSではデフォルトで有効になっている事を確認します。

また、「no ip unreachables」コマンドにより、host unreachableを無効化できる事を確認します。

動作確認 – デフォルトの挙動

Cisco IOSはデフォルトでhost unreachableが有効になっています。

HOST4から8.8.8.8へのpingを送信し、R3からhost unreachableが返される事を確認します。

host unreachableが返されたかどうかを確認可能にするため、HOST4に以下のようなアクセスリストを作成します。

HOST4でicmpのデバッグを有効にします。

HOST4から8.8.8.8へのpingを送信します。到達不能を表す「U」が表示される事を確認します。タイムアウトを表す「.」とは意味が違う事に注意して下さい。

「host unreachable rcv」というログ出力より、ICMP redirectが返された事を確認します。

アクセスリストのカウンタより、ICMP redirectが返された事を確認します。

設定投入

R3のhost unreachableを無効化します。

インターフェース単位のICMP設定は、show ip interfaceコマンドで確認できます。「ICMP redirects are never sent」と表示されている事より、icmp redirectが無効化されている事を確認します。

動作確認 – ICMP host unreachable 無効時の挙動

HOST4のアクセスリストカウンタをクリアします。

HOST4からR1へのpingを送信します。到達不能を表す「U」ではなく、タイムアウトを表す「.」に変わった事を確認します。

カウンタが上昇していない事より、確かにhost unreachableがなくなった事が確認できます。

ICMP unreachable rate limit の設定

検証目的

ICMP unreachableはルータに負荷をかける処理です。そのため、Cisco IOSはDOS攻撃対策としてunreachableの流量制限機能を設けています。その流量制限はDF(packet too big)とその他の2種類の閾値を設ける事ができる事を確認します。

事前準備

R1からR2への通信について、host unreachable, packet too bigの2種類のunreachableを再現できる環境を構築します。R1, R2に以下の設定を投入します。

R1からR2へのpingについて、R2のルーティングテーブルに存在しない宛先の場合、host unreachableを返す事を確認します。

R1からR2へのpingについて、MTU size超過かつdf-bit ONの場合は、packet too bigを返す事を確認します。

設定投入 – unreachable limit 全体設定

R2にunreachableの流量制限の設定を投入します。200msecに1回のみunreachableを返すようにします。

動作確認 – unreachable limit 全体設定

R1からR2へhost unreachable, packet too bigを返すpingを発生させます。rate limit機能により、数回に1度タイムアウトが発生している事が分かります。

設定投入 – unreachable limit DF例外設定

R2にDF (packet too big) のみ流用制限の対象外とする設定を投入します。

動作確認 – unreachable limit DF例外設定

R1からR2へhost unreachable, packet too bigを返すpingを発生させます。DF (packet too big)は流用制限されず、確実にunreachableを返している事が分かります。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメント

  1. 匿名 より:

    いつも勉強させて頂いております。
    ACLが異なっておりませんでしょうか?

    tracerouteの戻り方向の通信はtime-exceeded, port-unreachableを使用します。
    R1 f0/0に以下のアクセスリストを設定し、tracerouteのみを許可する設定を投入します。

    [R1]
    ip access-list extended ACL_PING_BACK
    permit icmp any any echo-reply

    #下記を許可
    #permit icmp any any time-exceeded
    #permit icmp any any port-unreachable

    permit ospf any any
    !
    interface Ethernet 0/0
    ip access-group ACL_PING_BACK in

  2. syauichi より:

    ご連絡遅れてしまい申し訳ございません。誤植報告ありがとうございます。
    ICMP – type & codeの章について、軒並み、typeとcodeが逆になっていますね。ただ今、修正が完了いたしました。

    修正しやすいよう、RFCの直リンクも貼って頂きありがとうございます。

  3. k より:

    あ、見落としていましたが

    ICMP – code & type

    の部分もCodeとTypeが逆に思えます。

    https://tools.ietf.org/html/rfc792#page-14

    こちらも併せて、ご確認いただけますよう
    お願い申し上げます。

    • syauichi より:

      ご連絡遅れてしまい申し訳ございません。誤植報告ありがとうございます。
      ICMP – type & codeの章について、軒並み、typeとcodeが逆になっていますね。ただ今、修正が完了いたしました。

      修正しやすいよう、RFCの直リンクも貼って頂きありがとうございます。

  4. k より:

    ありがとうございます。
    大変、参考 & 勉強になります。

    \ 関連のtag or markdownが使えないようなのでそのまま記します。

    CODE TYPE 名称 CISCO ACLの表記 説明
    3 4 packet too big packet-too-big MTU sizeを上回り かつ DF bitが付与されている場合、
    分割不可能である旨を返すメッセージです。

    ここにtheadの部分ですが、TYPEとCODEが逆に思えます。

    packet capture の部分でもType 3, Code 4となっています

    またICMP のRFCにもそのようにあります。
    https://tools.ietf.org/html/rfc792#page-4

    fragmentation needed and DF set;

    ご確認いただけますでしょうか。
    よろしくお願いいたします。

    Thank you for your this blog!
    There’s no book without a misprint. also blog too.

  5. 匿名 より:

     いつも勉強させて頂いております。
     誤植ではありませんでしょうか?

    ICMP – code & type

     CODE,名称,CISCO ACLの表記,説明
     0,echo,echo-reply,echo requestに対する応答です。
     →0,echo-reply,echo-reply,echo requestに対する応答です。

     8,echo reply,echo-reply,応答を要求します。
     →8,echo request,echo,応答を要求します。

    • syauichi より:

      echo, echo-replyの件、ご指摘ありがとうございます。
      只今、修正が完了いたしました。

  6. 匿名 より:

    PMTU Discovery Blackholeとは

    >「全てのICMP」が許可
    「全てのICMP」が拒否

    誤字かと存じます。