ICMPとはネットワークを制御するためのプロトコルです。疎通確認で使用するping, tracerouteは、ICMPを利用した仕組みのひとつです。
このページでは、ICMP, ping, tracerouteに関する深い知識とよくある誤解について説明します。CCIE R&S ラボ試験では、ICMPのport unreachable, time exceeded, packet too bigの意味を正しく理解しないと、設定どころか問題文の意味すら理解できません。
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は以下の通りです。
[table “53” not found /]実際にICMPを利用しているpingをパケットキャプチャしてみると、protocol numberが1である事が分かります。
Frame 6: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface 0 Ethernet II, Src: ArubaNet_00:c9:70 (00:1a:1e:00:c9:70), Dst: IntelCor_4c:38:00 (64:80:99:4c:38:00) Internet Protocol Version 4, Src: 8.8.8.8 (8.8.8.8), Dst: 10.4.187.48 (10.4.187.48) Version: 4 Header Length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport)) Total Length: 60 Identification: 0xf4a4 (62628) Flags: 0x00 Fragment offset: 0 Time to live: 53 Protocol: ICMP (1) Header checksum: 0xbbd8 [validation disabled] Source: 8.8.8.8 (8.8.8.8) Destination: 10.4.187.48 (10.4.187.48) [Source GeoIP: Unknown] [Destination GeoIP: Unknown] Internet Control Message Protocol
以上のことから、ICMPとはLayer 4のプロトコルである事がお分かり頂けたと思います。
ICMP – type & code
ICMP headerの中には、typeと呼ばれるフィールドがあります。このtypeによって、ICMPの役割が異なります。最も有名なのが、pingコマンドが使用するecho request, echo(echo-reply)です。
ICMPのtypeとその役割をまとめると以下の表のようになります。
type | 名称 | Cisco ACLの表記 | 説明 |
---|---|---|---|
0 | echo reply | echo-reply | echo requestに対する応答です。 |
3 | destination unreachable | unreachable | 到達不能を意味します。 host unreachable, port unreachableなどが存在します。 |
5 | redirect | redirect | より良い経路がある旨を伝えるメッセージです。 |
8 | echo request | echo | 応答を要求します。 |
11 | time exceeded | time-exceeded | TTLが0になった旨を伝えるメッセージです。 |
17 | mask request | mask-request | サブネットマスクを要求します。 |
18 | mask reply | mask-reply | mask replyに対する応答です。 |
ICMP type 3である”destination unreachable”は、さらにcodeと呼ばれるフィールドが存在し、さらに細分されます。CCIEを目指すならば、host unreachable, port unreachableの違いくらいは説明できて当たり前です。
ICMPのtype codeをまとめると以下のようになります。
type | code | 名称 | Cisco ACLの表記 | 説明 |
---|---|---|---|---|
3 | 1 | host unreachable | host-unreachable | 宛先ホストがルーティングテーブル上に存在しない場合に 返すメッセージです。 |
3 | 3 | port unreachable | port-unreachable | LISTENしていないポート宛てのTCP, UDPを 受信した場合に返すメッセージです。 |
3 | 4 | packet too big | packet-too-big | MTU sizeを上回り かつ DF bitが付与されている場合、 分割不可能である旨を返すメッセージです。 |
Ping
ping 概要
pingは到達可能かどうかを調査するためのコマンドです。多くのOSはICMP echo requestを送信し、requestを受け取ったマシンはICMP echo replyを返す事によって、ネットワークの到達可能を確認する事ができます。
ping パケットキャプチャ
それでは、pingの仕様を確認するために、パケットキャプチャを試みてみます。pingの送信側が送るパケット、すなわち、ICMP echo requestは以下のようになります。ICMP type 8と書かれている事が読み取れます。
Frame 40: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface 0 Ethernet II, Src: IntelCor_4c:38:00 (64:80:99:4c:38:00), Dst: IETF-VRRP-VRID_0d (00:00:5e:00:01:0d) Internet Protocol Version 4, Src: 10.4.187.48 (10.4.187.48), Dst: 8.8.8.8 (8.8.8.8) Internet Control Message Protocol Type: 8 (Echo (ping) request) Code: 0 Checksum: 0x2ea6 [correct] Identifier (BE): 1 (0x0001) Identifier (LE): 256 (0x0100) Sequence number (BE): 7861 (0x1eb5) Sequence number (LE): 46366 (0xb51e) [No response seen] Data (32 bytes)
pingの受信側が送るパケット、すなわち、ICMP echo replyは以下のようになります。ICMP type 8と書かれている事が読み取れます。
Frame 39: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on interface 0 Ethernet II, Src: ArubaNet_00:c9:70 (00:1a:1e:00:c9:70), Dst: IntelCor_4c:38:00 (64:80:99:4c:38:00) Internet Protocol Version 4, Src: 8.8.8.8 (8.8.8.8), Dst: 10.4.187.48 (10.4.187.48) Internet Control Message Protocol Type: 0 (Echo (ping) reply) Code: 0 Checksum: 0x36a7 [correct] Identifier (BE): 1 (0x0001) Identifier (LE): 256 (0x0100) Sequence number (BE): 7860 (0x1eb4) Sequence number (LE): 46110 (0xb41e) [Request frame: 38] [Response time: 61.419 ms] Data (32 bytes)
Ping 応答許可設定
CCIE R&S ラボ試験とは関係ありませんが、実践ではどのようにすればping応答を返すのかを知っておくのはとても良い事だと思います。よく「pingが通らない、すなわち、ネットワークに問題がある」と誤解する人が多いですが、設定によってはpingを拒否している事があります。
例えば、Windows OSの場合は、デフォルトでpingを拒否しています。Windowsファイアウォールの画面で”エコー要求”を許可する事によって、pingに応答するようになります。
Linux環境のiptablesならば、”-p icmp”というのがpingを許可する設定になります。
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT -A INPUT -p tcp --dport 22 -j ACCEPT -A INPUT -p tcp --dport 80 -j ACCEPT -A INPUT -p tcp --dport 443 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT
最近の話題になりますが、AWSもデフォルトではpingに応答しません。デフォルト設定のセキュリティグループはSSHのみを許可しているので、pingに応答するようにしたいならば、以下のように”ALL ICMP”を許可する必要があります。
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つずつ大きくしながらパケットを送っている事が読み取れます。
57 1.840473 133.242.169.96 216.81.59.173 UDP 74 Source port: 46032 Destination port: 33434 58 1.840547 133.242.169.96 216.81.59.173 UDP 74 Source port: 46285 Destination port: 33435 59 1.840603 133.242.169.96 216.81.59.173 UDP 74 Source port: 57014 Destination port: 33436 60 1.840715 133.242.169.96 216.81.59.173 UDP 74 Source port: 52017 Destination port: 33437 61 1.840770 133.242.169.96 216.81.59.173 UDP 74 Source port: 34128 Destination port: 33438 62 1.840815 133.242.169.96 216.81.59.173 UDP 74 Source port: 34985 Destination port: 33439 64 1.840849 133.242.169.96 216.81.59.173 UDP 74 Source port: 36585 Destination port: 33440 65 1.840899 133.242.169.96 216.81.59.173 UDP 74 Source port: 46226 Destination port: 33441 66 1.840955 133.242.169.96 216.81.59.173 UDP 74 Source port: 53332 Destination port: 33442 67 1.841007 133.242.169.96 216.81.59.173 UDP 74 Source port: 44068 Destination port: 33443 68 1.841057 133.242.169.96 216.81.59.173 UDP 74 Source port: 34373 Destination port: 33444 69 1.841101 133.242.169.96 216.81.59.173 UDP 74 Source port: 48663 Destination port: 33445
このUDPパケットの詳細を眺めると、TTLが小さい値である事が分かります。
Frame 57: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) Ethernet II, Src: 52:54:0a:00:93:22 (52:54:0a:00:93:22), Dst: IETF-VRRP-VRID_15 (00:00:5e:00:01:15) Internet Protocol Version 4, Src: 133.242.169.96 (133.242.169.96), Dst: 216.81.59.173 (216.81.59.173) Version: 4 Header Length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport)) Total Length: 60 Identification: 0x85f1 (34289) Flags: 0x00 Fragment offset: 0 Time to live: 1 Protocol: UDP (17) Header checksum: 0xf06e [validation disabled] Source: 133.242.169.96 (133.242.169.96) Destination: 216.81.59.173 (216.81.59.173) [Source GeoIP: Unknown] [Destination GeoIP: Unknown] User Datagram Protocol, Src Port: 46032 (46032), Dst Port: 33434 (33434) Source Port: 46032 (46032) Destination Port: 33434 (33434) Length: 40 Checksum: 0x438b [validation disabled] [Stream index: 0] Data (32 bytes)
通信経路上の機器が返すパケットを観察します。ICMP type 11であるtime exceededが返されている事が読み取れます。
Frame 74: 70 bytes on wire (560 bits), 70 bytes captured (560 bits) Ethernet II, Src: IETF-VRRP-VRID_15 (00:00:5e:00:01:15), Dst: 52:54:0a:00:93:22 (52:54:0a:00:93:22) Internet Protocol Version 4, Src: 133.242.168.1 (133.242.168.1), Dst: 133.242.169.96 (133.242.169.96) Internet Control Message Protocol Type: 11 (Time-to-live exceeded) Code: 0 (Time to live exceeded in transit) Checksum: 0x2d90 [correct] Internet Protocol Version 4, Src: 133.242.169.96 (133.242.169.96), Dst: 216.81.59.173 (216.81.59.173) User Datagram Protocol, Src Port: 46032 (46032), Dst Port: 33434 (33434) Source Port: 46032 (46032) Destination Port: 33434 (33434) Length: 40 Checksum: 0x90dc [unchecked, not all data available] [Stream index: 0]
tracerouteの宛先となる機器が返すパケットを観察します。宛先となる機器はUDP port 33463が送られてきても、そんなportではListenしていません。ですので、宛先となる機器はICMP type 3 code 3であるport unreachableを返します。
Frame 207: 102 bytes on wire (816 bits), 102 bytes captured (816 bits) Ethernet II, Src: BrocadeC_9b:26:00 (00:24:38:9b:26:00), Dst: 52:54:0a:00:93:22 (52:54:0a:00:93:22) Internet Protocol Version 4, Src: 8.8.8.8 (8.8.8.8), Dst: 133.242.169.96 (133.242.169.96) Internet Control Message Protocol Type: 3 (Destination unreachable) Code: 3 (Port unreachable) Checksum: 0x3c99 [correct] Internet Protocol Version 4, Src: 133.242.169.96 (133.242.169.96), Dst: 8.8.8.8 (8.8.8.8) User Datagram Protocol, Src Port: 56106 (56106), Dst Port: 33463 (33463) Data (32 bytes)
traceroute OSによる仕様の違い
tracerouteはOSによって仕様が異なり、UDPを使用する場合とICMPを使用する場合の両方があります。
OS | 仕様説明 |
---|---|
Cisco IOS | UDPによるtracerouteを行ないます。 |
Windows | ICMPによる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を使用します。
[root@localhost ~]# traceroute -f 18 -m 40 -I 216.81.59.173 traceroute to 216.81.59.173 (216.81.59.173), 40 hops max, 60 byte packets 18 Episode.IV (206.214.251.1) 216.192 ms 218.289 ms 225.428 ms 19 A.NEW.HOPE (206.214.251.6) 232.098 ms 223.140 ms 236.860 ms 20 It.is.a.period.of.civil.war (206.214.251.9) 235.405 ms 225.820 ms 228.530 ms 21 Rebel.spaceships (206.214.251.14) 233.529 ms 219.542 ms 235.630 ms 22 striking.from.a.hidden.base (206.214.251.17) 237.888 ms 240.074 ms 242.218 ms 23 have.won.their.first.victory (206.214.251.22) 227.260 ms 224.160 ms 225.570 ms 24 against.the.evil.Galactic.Empire (206.214.251.25) 220.309 ms 221.806 ms 223.259 ms 25 During.the.battle (206.214.251.30) 224.554 ms 226.286 ms 223.968 ms 26 Rebel.spies.managed (206.214.251.33) 226.188 ms 228.647 ms 229.710 ms 27 to.steal.secret.plans (206.214.251.38) 227.997 ms 221.054 ms 226.843 ms 28 to.the.Empires.ultimate.weapon (206.214.251.41) 221.575 ms 226.600 ms 221.715 ms 29 the.DEATH.STAR (206.214.251.46) 230.277 ms 230.668 ms 222.617 ms 30 an.armored.space.station (206.214.251.49) 223.521 ms 225.977 ms 227.987 ms 31 with.enough.power.to (206.214.251.54) 221.636 ms 226.065 ms 222.251 ms 32 destroy.an.entire.planet (206.214.251.57) 228.688 ms 230.805 ms 231.743 ms 33 Pursued.by.the.Empires (206.214.251.62) 216.961 ms 219.620 ms 220.688 ms 34 sinister.agents (206.214.251.65) 222.564 ms 220.779 ms 221.819 ms 35 Princess.Leia.races.home (206.214.251.70) 221.414 ms 220.170 ms 215.987 ms 36 aboard.her.starship (206.214.251.73) 223.182 ms 224.058 ms 226.774 ms 37 custodian.of.the.stolen.plans (206.214.251.78) 225.834 ms 225.598 ms 228.224 ms 38 that.can.save.her (206.214.251.81) 226.513 ms 229.119 ms 221.563 ms 39 people.and.restore (206.214.251.86) 230.363 ms 226.322 ms 228.878 ms 40 freedom.to.the.galaxy (206.214.251.89) 227.834 ms 221.388 ms 222.312 ms
Windows 環境でよくある事ですが、tracerouteの名前解決待ちでイライラする事があるかもしれません。そのような場合は、-dオプションで名前解決を行なわないようにする事ができます。
C:\Users\admin>tracert -d 8.8.8.8 8.8.8.8 へのルートをトレースしています。経由するホップ数は最大 30 です 1 4 ms 6 ms 3 ms 192.168.43.1 2 * * * 要求がタイムアウトしました。 3 * * * 要求がタイムアウトしました。 4 140 ms 220 ms 237 ms 172.23.22.210 5 218 ms 215 ms 46 ms 172.23.207.5 6 199 ms 73 ms 141 ms 172.23.23.61 7 339 ms 88 ms 125 ms 106.162.241.73 8 435 ms 48 ms 155 ms 59.128.99.153 9 166 ms 203 ms 203 ms 59.128.5.86 10 219 ms 203 ms 203 ms 72.14.204.58 11 213 ms 204 ms 203 ms 72.14.236.215 12 211 ms 203 ms 203 ms 216.239.46.207 13 225 ms 203 ms 203 ms 8.8.8.8 トレースを完了しました。 C:\Users\admin>
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が含まれています。
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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
DF bitがセットされていない場合は、パケットはMTU size以下にフラグメント(分割)されます。パケットの分割/再組立の分だけリソースを消費し、またヘッダーのオーバーヘッドが大きくなるため、伝送効率が落ちます。
一方、DF bitがセットされている場合は、MTU sizeを超過している旨を送信元に伝え、送信元がMTU size以下でパケットを送るようにします。伝送効率が落ちないメリットがあるものの、MTU sizeが超過している旨を送信元に正常に返さない場合は疎通不能になってしまうデメリットがあります。この疎通不能現象は、PMTU Discovery blackholeと呼ばれる現象で、後程、詳しく説明します。
改めてDF bitのメリット・デメリットをまとめ直すと以下のようになります。
DF bit | OFF | ON |
---|---|---|
伝送効率 | MTU sizeを超過すると伝送効率が落ちる | MTU sizeを超過しても伝送効率が落ちない |
PMTU Discovery Blackholeによる疎通不能 | 疎通不能は発生しない | 疎通不能が発生しうる |
クライアントOSは伝送効率を落ちる事を嫌うのか、WindowsもRedhatもデフォルトの挙動はDF bitを付与してパケットを送信します。以下はWindows 7から送信されるパケットをキャプチャした結果で、確かにDF bitが付与されている事が読み取れます。
Frame 1: 1252 bytes on wire (10016 bits), 1252 bytes captured (10016 bits) on interface 0 Ethernet II, Src: IntelCor_4f:5e:b4 (84:3a:4b:4f:5e:b4), Dst: Kyocera_86:2f:a7 (c4:21:c8:86:2f:a7) Internet Protocol Version 4, Src: 192.168.43.193 (192.168.43.193), Dst: 133.242.188.42 (133.242.188.42) Version: 4 Header Length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport)) Total Length: 1238 Identification: 0x63a2 (25506) Flags: 0x02 (Don't Fragment) Fragment offset: 0 Time to live: 128 Protocol: TCP (6) Header checksum: 0x63f9 [validation disabled] Source: 192.168.43.193 (192.168.43.193) Destination: 133.242.188.42 (133.242.188.42) [Source GeoIP: Unknown] [Destination GeoIP: Unknown] Transmission Control Protocol, Src Port: 51220 (51220), Dst Port: 80 (80), Seq: 1, Ack: 1, Len: 1198 Hypertext Transfer Protocol
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サイズを伝えている事が分かります。
Ethernet II, Src: cc:02:04:90:00:02 (cc:02:04:90:00:02), Dst: cc:03:04:90:00:02 (cc:03:04:90:00:02) Internet Protocol Version 4, Src: 192.168.23.2 (192.168.23.2), Dst: 200.3.3.254 (200.3.3.254) Internet Control Message Protocol Type: 3 (Destination unreachable) Code: 4 (Fragmentation needed) Checksum: 0x074c [correct] MTU of next hop: 500 Internet Protocol Version 4, Src: 200.3.3.254 (200.3.3.254), Dst: 10.1.1.1 (10.1.1.1) Internet Control Message Protocol Type: 8 (Echo (ping) request) Code: 0 Checksum: 0xebba Identifier (BE): 1 (0x0001) Identifier (LE): 256 (0x0100) Sequence number (BE): 0 (0x0000) Sequence number (LE): 0 (0x0000)
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を拒否したいならば、以下のように必要最小限のプロトコルを拒否すべきです。
Cisco(config)# access-list 100 deny icmp any any echo Cisco(config)# access-list 100 deny icmp any any echo-reply Cisco(config)# access-list 100 permit ip any any
または、以下のように経路制御で使う最小限のメッセージ unreachable, time-exceededのみを許可するように設定しても良いでしょう。
Cisco(config)# access-list 100 permit icmp any any unreachable Cisco(config)# access-list 100 permit icmp any any time-exceeded Cisco(config)# access-list 100 deny icmp any any Cisco(config)# access-list 100 permit ip any any
ICMP 応答可否の設定
Ciscoのネットワーク機器は、ICMPの応答を返すかどうかを制御する事ができます。いつもよく使う「show ip interface」コマンドを注意深く見ると、ICMP redirects, ICMP unreachables, ICMP mask repliesに関して応答を返すかどうか制御できる事が分かります。
R2#show ip interface Ethernet 0/0 Ethernet0/0 is up, line protocol is up Internet address is 192.168.123.2/24 Broadcast address is 255.255.255.255 Address determined by setup command MTU is 1500 bytes Helper address is not set Directed broadcast forwarding is disabled Multicast reserved groups joined: 224.0.0.5 224.0.0.6 Outgoing access list is not set Inbound access list is not set Proxy ARP is enabled Local Proxy ARP is disabled Security level is default Split horizon is enabled ICMP redirects are always sent ICMP unreachables are always sent ICMP mask replies are never sent <omitted>
redirect message
より良い経路がある場合は、ICMP redirectと呼ばれるメッセージを返送する事によって、送信元により良い経路を伝える事があります。デフォルトではICMP redirectは有効になっていますが、敢えて無効化したい場合は、以下のように「no ip redirects」コマンドを使用します。
Router(config-if)# no ip redirects
host unreachable
パケットを受信したものの、その宛先がルーティングテーブルに載っておらず到達不能となる場合は、host unreachableと呼ばれるメッセージを返します。個人的には過剰セキュリティと思いますが、「host unreachableを返すのは内部ネットワーク構造を教える事になるので、host unreachableは返すべきではない」という意見も存在します。もし、このような意見を採用し、敢えてhost unreachableを無効化したい場合は、以下のように「no ip unreachables」コマンドを使用します。
Router(config-if)# no ip unreachables
mask reply
最近では使用する事は滅多にありませんが、ICMPの中にはサブネットマスクを要求するものもあります。その応答がICMP mask replyです。ICMP mask replyを無効化したい場合は、「no ip mask-reply」コマンドを使用します。
Router(config-if)# 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を返すという意味になります。コマンドの構文は以下の通りです。
Router(config)# ip icmp rate-limit unreachable <msec>
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のみ個別で流量制限を設定する事ができます。設定コマンドは以下の通りです。
Router(config)# ip icmp rate-limit unreachable DF <msec>
例えば、以下のように2種類の閾値を設けると、packet too bigは秒間100回まで(10msec間隔で)応答するものの、それ以外のunreachableは秒間10回まで(100msec間隔で)応答するように設定する事ができます。
Router(config)# ip icmp rate-limit unreachable 100 Router(config)# ip icmp rate-limit unreachable DF 10
以下のような設定例にすれば、packet too bigは流量制限なしで、それ以外のunreachableは秒間10回まで(100msec間隔で)応答するようになります。
Router(config)# ip icmp rate-limit unreachable 100 Router(config)# no ip icmp rate-limit unreachable DF
ICMPの動作確認
ネットワーク構成図
以下の環境で動作確認を行います。
初期設定
R1, R2, R3はOSPFによるルーティングを行います。HOST4はルーティングを無効化しデフォルトゲートウェイをR3に向けます。
初期設定全文は以下の通りです。
pingの通信許可設定
検証目的
以下のようなR1からR3へのpingについて、最小限の許可設定を考察し、pingがecho request, echo replyを使っている事に対する理解を深めます。
[R1] R1#ping 10.3.3.3 source Loopback 0 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds: Packet sent with a source address of 10.1.1.1 !!!!! Success rate is 100 percent (5/5), round-trip min/avg/max = 192/248/312 ms R1#
設定投入
pingの行き方向の通信はecho request (ACL表記は”echo”) を使用します。R2 f0/0に以下のアクセスリストを設定し、pingのみを許可する設定を投入します。
[R2] ip access-list extended ACL_PING_FORWARD permit icmp any any echo permit ospf any any ! interface Ethernet 0/0 ip access-group ACL_PING_FORWARD in
pingの戻り方向の通信はecho replyを使用します。R1 f0/0に以下のアクセスリストを設定し、pingのみを許可する設定を投入します。
[R1] ip access-list extended ACL_PING_BACK permit icmp any any echo-reply permit ospf any any ! interface Ethernet 0/0 ip access-group ACL_PING_BACK in
動作確認 – 疎通確認
R1からR3へのpingが疎通可能である事を確認します。
R1#ping 10.3.3.3 source Loopback 0 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds: Packet sent with a source address of 10.1.1.1 !!!.! Success rate is 80 percent (4/5), round-trip min/avg/max = 232/336/388 ms R1#
ping以外の通信を禁止されている事を確認するために、traceroute, telnetを実行します。traceroute, telnetが疎通不能である事を確認します。
R1#traceroute 10.3.3.3 source Loopback 0 Type escape sequence to abort. Tracing the route to 10.3.3.3 1 * * * 2 * * * 3 * * * 4 * * * 5 * * * 6 * * * 7 * * * 8 * * * 9 * * R1# R1# R1#telnet 10.3.3.3 Trying 10.3.3.3 ... % Connection timed out; remote host not responding R1#
動作確認 – アクセスリストカウンタ上昇の確認
アクセスリストのカウンタを確認し、確かにpingがecho, echo-replyを使用している事を確認します。
[R1] R1#show access-lists Extended IP access list ACL_PING_BACK 10 permit icmp any any echo-reply (8 matches) 20 permit ospf any any (38 matches) R1# [R2] R2#show access-lists Extended IP access list ACL_PING_FORWARD 10 permit icmp any any echo (4 matches) 20 permit ospf any any (45 matches) R2#
設定削除
R1, R2のACLを削除してから、次の動作確認に望みます。
[R1] interface Ethernet 0/0 no ip access-group ACL_PING_BACK in no ip access-list extended ACL_PING_BACK [R2] interface Ethernet 0/0 no ip access-group ACL_PING_FORWARD in no ip access-list extended ACL_PING_FORWARD
tracerouteの通信許可設定
検証目的
以下のようなR1からR3へのtracerouteについて、最小限の許可設定を考察し、pingがudp, time-exceeded, port-unreachableを使っている事に対する理解を深めます。
[R1] R1#traceroute 10.3.3.3 source Loopback 0 Type escape sequence to abort. Tracing the route to 10.3.3.3 1 192.168.12.2 152 msec 124 msec 128 msec 2 192.168.234.3 316 msec 272 msec 364 msec R1#
設定投入
tracerouteの行き方向の通信はudp 33434-33523を使用します。R2 f0/0に以下のアクセスリストを設定し、tracerouteのみを許可する設定を投入します。
[R2] ip access-list extended ACL_TRACERT_FORWARD 10 permit udp any any range 33434 33523 20 permit ospf any any ! interface Ethernet 0/0 ip access-group ACL_TRACERT_FORWARD in
tracerouteの戻り方向の通信はtime-exceeded, port-unreachableを使用します。R1 f0/0に以下のアクセスリストを設定し、tracerouteのみを許可する設定を投入します。
ip access-list extended ACL_TRACERT_BACK 10 permit icmp any any time-exceeded 20 permit icmp any any port-unreachable 30 permit ospf any any ! interface Ethernet 0/0 ip access-group ACL_TRACERT_BACK in
動作確認 – 疎通確認
R1からR3へのtracerouteが疎通可能である事を確認します。
R1#traceroute 10.3.3.3 source Loopback 0 Type escape sequence to abort. Tracing the route to 10.3.3.3 1 192.168.12.2 276 msec 244 msec * 2 192.168.234.3 300 msec 292 msec 240 msec R1#
traceroute以外の通信を禁止されている事を確認するために、ping, telnetを実行します。ping, telnetが疎通不能である事を確認します。
R1#ping 10.3.3.3 source Loopback 0 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds: Packet sent with a source address of 10.1.1.1 ..... Success rate is 0 percent (0/5) R1# R1# R1#telnet 10.3.3.3 Trying 10.3.3.3 ... % Connection timed out; remote host not responding R1#
動作確認 – アクセスリストカウンタ上昇の確認
アクセスリストのカウンタを確認し、確かにtracerouteがudp, time-exceeded, port-unreachableを使用している事を確認します。
[R1] R1#show ip access-lists Extended IP access list ACL_TRACERT_BACK 10 permit icmp any any time-exceeded (4 matches) 20 permit icmp any any port-unreachable (6 matches) 30 permit ospf any any (13 matches) R1# [R2] R2#show ip access-lists Extended IP access list ACL_TRACERT_FORWARD 10 permit udp any any range 33434 33523 (6 matches) 20 permit ospf any any (12 matches) R2#
設定削除
R1, R2のACLを削除してから、次の動作確認に望みます。
[R1] interface Ethernet 0/0 no ip access-group ACL_TRACERT_BACK in no ip access-list extended ACL_TRACERT_BACK [R2] interface Ethernet 0/0 no ip access-group ACL_TRACERT_FORWARD in no ip access-list extended ACL_TRACERT_FORWARD
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に以下の設定を投入します。
[R2] interface Ethernet0/1 ip mtu 500
MTU sizeを超過した場合に、確かにpacket too bigが返されている事を確認するため、以下のようなアクセスリストを作成します。
[R1] ip access-list extended ACL_VERIFY_PMTU permit icmp any any packet-too-big permit ip any any ! interface Ethernet 0/0 ip access-group ACL_VERIFY_PMTU in
動作確認 – 疎通確認
R1からR3へのpingを送信します。Cisco IOSのpingはデフォルトでdf-bitを付与しませんので、packet too bigを確認する際は、df-bitを引数に与えてpingを実行します。
packet too bigによる到達不能を示す「M」の文字が現れる事を確認します。
R1#ping 10.3.3.3 source Loopback 0 size 1500 df-bit Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds: Packet sent with a source address of 10.1.1.1 Packet sent with the DF bit set MMMMM Success rate is 0 percent (0/5) R1#
動作確認 – アクセスリストカウンタ上昇の確認
アクセスリストのカウンタを確認し、確かにpacket too bigが返された事を確認します。
R1#show ip access-lists Extended IP access list ACL_VERIFY_PMTU 10 permit icmp any any packet-too-big (10 matches) 20 permit ip any any (1 match) R1#
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] ip access-list extended ACL_VERIFY_ICMP permit icmp any any redirect permit ip any any ! interface Ethernet 0/0 ip access-group ACL_VERIFY_ICMP in
HOST4でicmpのデバッグを有効にします。
HOST4#debug ip icmp ICMP packet debugging is on HOST4#
HOST4からR1へのpingを送信します。
HOST4#ping 10.1.1.1 repeat 1 Type escape sequence to abort. Sending 1, 100-byte ICMP Echos to 10.1.1.1, timeout is 2 seconds: ! Success rate is 100 percent (1/1), round-trip min/avg/max = 180/180/180 ms HOST4#
「ICMP: redirect rcvd」というログ出力より、ICMP redirectが返された事を確認します。
[HOST4] HOST4# *Feb 19 21:57:26.607: ICMP: echo reply rcvd, src 10.1.1.1, dst 192.168.234.4, topology BASE, dscp 0 topoid 0 *Feb 19 21:57:26.607: ICMP: redirect rcvd from 192.168.234.3- for 10.1.1.1 use gw 192.168.234.2 *Feb 19 21:57:26.611: ICMP: echo reply rcvd, src 10.1.1.1, dst 192.168.234.4, topology BASE, dscp 0 topoid 0 HOST4#
アクセスリストのカウンタより、ICMP redirectが返された事を確認します。
HOST4#show access-lists Extended IP access list ACL_VERIFY_ICMP 10 permit icmp any any redirect (144 matches) 20 permit ip any any (549 matches) HOST4#clear ip access-list counters HOST4#
設定投入
R3のicmp redirectを無効化します。
[R3] interface Ethernet0/0 no ip redirects
インターフェース単位のICMP設定は、show ip interfaceコマンドで確認できます。「ICMP redirects are never sent」と表示されている事より、icmp redirectが無効化されている事を確認します。
[R3] Ethernet0/0 is up, line protocol is up Internet address is 192.168.234.3/24 Broadcast address is 255.255.255.255 Address determined by non-volatile memory MTU is 1500 bytes Helper address is not set Directed broadcast forwarding is disabled Multicast reserved groups joined: 224.0.0.5 224.0.0.6 Outgoing access list is not set Inbound access list is not set Proxy ARP is enabled Local Proxy ARP is disabled Security level is default Split horizon is enabled ICMP redirects are never sent ICMP unreachables are always sent ICMP mask replies are never sent
動作確認 – ICMP redirect 無効時の挙動
HOST4のアクセスリストカウンタをクリアします。
HOST4#clear ip access-list counters
HOST4からR1へのpingを送信します。
HOST4#ping 10.1.1.1 repeat 1 Type escape sequence to abort. Sending 1, 100-byte ICMP Echos to 10.1.1.1, timeout is 2 seconds: ! Success rate is 100 percent (1/1), round-trip min/avg/max = 208/208/208 ms HOST4#
カウンタが上昇していない事より、確かにicmp redirectがなくなった事が確認できます。
HOST4#show access-lists Extended IP access list ACL_VERIFY_ICMP 10 permit icmp any any redirect 20 permit ip any any (510 matches) HOST4#
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] ip access-list extended ACL_VERIFY_ICMP permit icmp any any host-unreachable permit ip any any ! interface Ethernet 0/0 ip access-group ACL_VERIFY_ICMP in
HOST4でicmpのデバッグを有効にします。
HOST4#debug ip icmp ICMP packet debugging is on HOST4#
HOST4から8.8.8.8へのpingを送信します。到達不能を表す「U」が表示される事を確認します。タイムアウトを表す「.」とは意味が違う事に注意して下さい。
HOST4#ping 8.8.8.8 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds: UUUUU Success rate is 0 percent (0/5) HOST4#
「host unreachable rcv」というログ出力より、ICMP redirectが返された事を確認します。
[HOST4] HOST4# *Mar 1 00:06:43.427: ICMP: dst (192.168.234.4) host unreachable rcv from 192.168.234.3 *Mar 1 00:06:43.583: ICMP: dst (192.168.234.4) host unreachable rcv from 192.168.234.3 *Mar 1 00:06:43.647: ICMP: dst (192.168.234.4) host unreachable rcv from 192.168.234.3 *Mar 1 00:06:43.679: ICMP: dst (192.168.234.4) host unreachable rcv from 192.168.234.3 *Mar 1 00:06:43.747: ICMP: dst (192.168.234.4) host unreachable rcv from 192.168.234.3 HOST4#
アクセスリストのカウンタより、ICMP redirectが返された事を確認します。
HOST4#show ip access-lists Extended IP access list ACL_VERIFY_ICMP 10 permit icmp any any host-unreachable (5 matches) 20 permit ip any any HOST4#
設定投入
R3のhost unreachableを無効化します。
[R3] interface Ethernet0/0 no ip unreachables
インターフェース単位のICMP設定は、show ip interfaceコマンドで確認できます。「ICMP redirects are never sent」と表示されている事より、icmp redirectが無効化されている事を確認します。
[R3] R3#show ip interface Ethernet 0/0 Ethernet0/0 is up, line protocol is up Internet address is 192.168.234.3/24 Broadcast address is 255.255.255.255 Address determined by non-volatile memory MTU is 1500 bytes Helper address is not set Directed broadcast forwarding is disabled Multicast reserved groups joined: 224.0.0.5 224.0.0.6 Outgoing access list is not set Inbound access list is not set Proxy ARP is enabled Local Proxy ARP is disabled Security level is default Split horizon is enabled ICMP redirects are never sent ICMP unreachables are never sent ICMP mask replies are never sent
動作確認 – ICMP host unreachable 無効時の挙動
HOST4のアクセスリストカウンタをクリアします。
HOST4#clear ip access-list counters
HOST4からR1へのpingを送信します。到達不能を表す「U」ではなく、タイムアウトを表す「.」に変わった事を確認します。
[HOST4] HOST4#ping 8.8.8.8 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds: ..... Success rate is 0 percent (0/5) HOST4#
カウンタが上昇していない事より、確かにhost unreachableがなくなった事が確認できます。
[HOST4] HOST4#show ip access-lists Extended IP access list ACL_VERIFY_ICMP 10 permit icmp any any host-unreachable 20 permit ip any any (23 matches) HOST4#
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] ip route 0.0.0.0 0.0.0.0 192.168.12.2 [R2] interface Ethernet0/1 ip mtu 500
R1からR2へのpingについて、R2のルーティングテーブルに存在しない宛先の場合、host unreachableを返す事を確認します。
[R1] R1#ping 8.8.8.8 Type escape sequence to abort. Sending 5, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds: UUUUU Success rate is 0 percent (0/5) R1#
R1からR2へのpingについて、MTU size超過かつdf-bit ONの場合は、packet too bigを返す事を確認します。
[R1] R1#ping 10.3.3.3 size 1500 df-bit Type escape sequence to abort. Sending 5, 1500-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds: Packet sent with the DF bit set MMMMM Success rate is 0 percent (0/5) R1#
設定投入 – unreachable limit 全体設定
R2にunreachableの流量制限の設定を投入します。200msecに1回のみunreachableを返すようにします。
[R2] ip icmp rate-limit unreachable 200
動作確認 – unreachable limit 全体設定
R1からR2へhost unreachable, packet too bigを返すpingを発生させます。rate limit機能により、数回に1度タイムアウトが発生している事が分かります。
[R1] R1#ping 8.8.8.8 repeat 10 Type escape sequence to abort. Sending 10, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds: U.U.U.UU.U Success rate is 0 percent (0/10) R1# R1# R1#ping 10.3.3.3 size 1500 df-bit repeat 10 Type escape sequence to abort. Sending 10, 1500-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds: Packet sent with the DF bit set M.M.M.M.M. Success rate is 0 percent (0/10) R1#
設定投入 – unreachable limit DF例外設定
R2にDF (packet too big) のみ流用制限の対象外とする設定を投入します。
[R2] no ip icmp rate-limit unreachable DF
動作確認 – unreachable limit DF例外設定
R1からR2へhost unreachable, packet too bigを返すpingを発生させます。DF (packet too big)は流用制限されず、確実にunreachableを返している事が分かります。
[R1] R1#ping 8.8.8.8 repeat 10 Type escape sequence to abort. Sending 10, 100-byte ICMP Echos to 8.8.8.8, timeout is 2 seconds: U.UU.U.U.U Success rate is 0 percent (0/10) R1# R1# R1#ping 10.3.3.3 size 1500 df-bit repeat 10 Type escape sequence to abort. Sending 10, 1500-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds: Packet sent with the DF bit set MMMMMMMMMM Success rate is 0 percent (0/10) R1#