この広告は、90日以上更新していないブログに表示しています。
普通、何らかの通信障害が発生すると、当然、通信の当事者に関する事を調べ出します。
サーバ側に何かログは出ていないか、パケットキャプチャをして相手からどんなパケットが届いているのか、Firewall 等で当該ホストに関するルールが引っかかっていないか....
ところが、Path MTU Discovery に起因する問題が発生すると、通信の当事者では、一見、相手が悪いように見えるし、実際、原因が当事者とは無関係のように見えるところにあります。
通信障害の最終手段として登場*1するパケットキャプチャをしても、単に、相手からのパケットが届かないだけに見えます。
フレッツ網が出始めた頃、ネットワークスピードの改善方法として MTU のサイズを調整する話で有名になった MTU ですが、Maximum Transmission Unit の略で、1つのフレームで送信できる最大サイズの事を言います。
元々、MTU 自体は回線の種別によって決まるもので、一般的なEthernet では 1500 バイトで、WAN 回線で使われる PPP の場合は可変ですが、Ethernet と同じ 1500 バイトになる事が多いようです。今はほとんど見かけないFDDI では 4352、IP over ATM で 9180 バイト、といった具合に、本来は様々な MTU を持つ回線があります。
フレッツ網が登場したときに MTU が話題になったのは、PPPoE というカプセル化技術を使ったためで、1500 バイトのEthernet フレームの中に、ユーザ側の端末と契約先のISP をつなぐ為の PPP を入れ、さらにその中に IP を入れる、という仕組みです。
そのため、通常の Ehternet に比べて PPP の分だけ、入れられる IP のサイズは小さくなります。
「Path」は「経路」を意味します。相手にパケットが届くまで、いくつものルータを渡っていきますが、その間の回線がどんな物が使われているか分りません。
ある相手と通信する時に、その経路全体での MTU が Path MTU です。
つまり、経路全体で、最も小さい MTU が Path MTU です。
Path MTU Discovery は、経路全体で最も小さい MTU をどうやったら分るか? という仕組みです。
ルータが受け取ったパケットを転送する際、転送先となる回線の MTU が受け取ったサイズより小さかった場合、パケットを分割して送ることがあります。
こうすれば、通信当事者は経路上の MTU など意識することなく、パケットを送信できますが、その代わり、ルータに取っては負担になります。
Path MTU Discovery のRFC 1191 が出されたのは 1990 年ですが、1990 年代に入ってから、ISP のルータのような、多くのネットワークとつながって、大量のパケットを裁くルータにかかる負荷が問題になっていました。
時期的に次期 IP(後のIPv6)の策定が行われていて、次期 IP のテーマの一つに、このルータの負荷問題もありました。
経路上の MTU が分ってしまえば、最初っからそれに合わせたサイズでパケットを送り出すことになるので、ルータでの分割は発生しません。
そのため、IPv6 では Path MTU Discovery が使われる事が前提になりました。
もともと、IP パケットには DF(Don't Fragment)フラグというフラグがあり、このフラグがセットされているパケットは、ルータによる分割をしてはならない、ということになっています。
ルータがより小さい MTU を持つ回線を使ってパケットを転送しようとした時に、「分割できない」という事は、これ以上、パケットを転送する事ができない、という事を意味します。
こういった事態が発生していることを、パケットの送信元に伝えるために ICMP が使われます。
Type 3(Destination Unreachable Message)の Code 4(fragmentation needed and DF set)という ICMP がルータから送信元に送られ、この中に「○○○バイトだったら転送できるんだけど...」という情報が入っています。
送信元がこれを受け取ったら、そのサイズに合わせて IP パケットを再送します。
最終的に相手にパケットが届くまで、ICMP の情報に合わせて小さくしていけば、経路上の最小 MTU が見つかる、という仕組みです。
Path MTU Discovery は、パケットが分割できないときにルータが返す ICMP を利用して実現しています。ということは、もし ICMP がフィルタされている*2と、
ということになります。
IPv6 では Path MTU Discovery が使われるので、ICMP をバッサリとFirewall 等で落としてしまうと、通信できない事態が発生する可能性があります。そのため、わざわざRFC で、ICMPv6 のフィルタリングに関する文章が出されています。
RFC 4890: Recommendations for Filtering ICMPv6 Messages in Firewalls
考えなしにまるごとフィルタリングをしてはいけません。
IPv6 の話だと思って、「そんなの使っていないし」と思っていると落とし穴があります。Path MTU Discovery 自体はIPv4 でも使える仕組みなので、原理的には同じことが発生しうることになります。
実は、割と以前からLinux ではIPv4 でも Path MTU Discovery が有効になっていて、そのことに私が気がついたのは5年ほど前のCentOS Ver.6 系でした。CentOS 上でSquid を動かした HTTP Proxy を経由すると、繋がったり繋がらなかったり、みたいなことがあって、そのときにパケットキャプチャをして DF フラグが立っていることに気が付きました。
Linux でIPv4 の Path MTU Discovery が有効になっているかは sysctl コマンドで分ります。
$ sysctl net.ipv4.ip_no_pmtu_disc
net.ipv4.ip_no_pmtu_disc = 0
ちょっと分りづらいですが、ip_no_pmtu_disc なので、値が 0 なら有効です。
今やLinux はサーバ以外にもいろいろなところで使われています。という事は、明確に「Linux」と認識していないものでも、Path MTU Discovery が有効になっている、ということになります。ネットワーク機器や IoT デバイスにもLinux は使われています。
私が実際に経験したのは、AWS のロードバランサである ELB です。
ELB に対する接続がVPN 経由だと NG、という事があったのですが、「ELB の実体って、AmazonLinux のインスタンスとかじゃないかなぁ」と思って、ICMP をブロックしていた NetworkACL の設定を変更したら解消した、という事がありました。
IPv6 に限らずIPv4 に関しても、いたずらに「ICMP を丸ごとブロック」をするべきではありません。
Ping of Death*3 やSmurf 攻撃*4は、正直、過去の物です。ICMP に対して過大な恐怖心を持たず、フィルタするなら ICMP の「中身」も意識したいものです。
*1:個人的には、レイヤー 3 以下が原因になりそうな症状で、当事者がLinux だったら、最初っからtcpdump の登場させますが。
*2:Firewall 製品だと、意図的にブロックしない限り、許可している通信に対して発生した ICMP は適切に転送してくれる事が多いです。L3 スイッチのACL のように、ステートレスにパケットを判断する場合、フィルタされてしまいがちです。
*3:Windows 95 が登場した頃、UNIX 系 OS がサイズの大きい ICMP Echo Request を送りつけられると、カーネルパニックに陥る欠陥があった。
*4:宛先がブロードキャストアドレスとなっている ICMP Echo Request に対して、該当するホストが応答する動作利用し、送信元アドレスを攻撃対象のアドレスに偽装してパケットを送りつけると、その何倍ものパケットが攻撃対象に向かう、という DDoS 攻撃の一種
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。