ハングしている接続

このトピックでは、クラウド・ネットワークとオンプレミス・ネットワーク間の通信で見られる最も一般的な問題の1つである、接続してホストにpingを送信できているのに接続がハングするという問題について説明します。

問題と解決策のサマリー

症状:仮想クラウド・ネットワーク(VCN)が、サイト間VPNまたはOracle Cloud Infrastructure FastConnectを介して既存のオンプレミス・ネットワークに接続されています。接続の片側のホストは反対側のホストにpingを送信できますが、接続がハングします。例:

  • この接続を介してSSHでホストにログインできますが、ログイン後に接続がハングします。
  • Virtual Networking Computing (VNC)接続を開始できますが、セッションがハングします。
  • SFTPダウンロードを開始できますが、ダウンロードがハングします。

一般的な問題: 接続の片側または両側でPath Maximum Transmission Unit Discovery (PMTUD)が機能していない可能性があります。これが接続の両側で機能していないと、双方が送信しようとしているパケットが接続に対して大きすぎるかどうかを判断して、それに応じた調整をすることができません。最大転送単位(MTU)およびPMTUDの概要は、MTUの概要およびPMTUDの概要を参照してください。

PMTUDを修復するための解決策:

  1. ホストがPMTUDを使用するように構成されていることを確認する: オンプレミス・ネットワーク内のホストがPMTUDを使用していない(つまり、パケットにDon't Fragmentフラグが設定されていない)場合、送信しようとしているパケットが接続に対して大きすぎるかどうかを調べる方法がありません。接続のOracle側のインスタンスでは、デフォルトでPMTUDが使用されます。インスタンスのその構成を変更しないでください。
  2. VCNセキュリティ・リストとインスタンス・ファイアウォールの両方でICMPタイプ3コード4のメッセージが許可されていることを確認する: PMTUDが使用されている場合、送信側のホストが接続に対して大きすぎるパケットを送信すると、特別なICMPメッセージが返されます。このメッセージを受信すると、ホストはパケットのサイズを接続に収まるように動的に更新できます。ただし、VCN内のサブネットのセキュリティ・リストとインスタンス・ファイアウォール両方がこの重要なICMPメッセージを受け入れるように構成されていない場合、インスタンスはそのメッセージを受信できません。

    ヒント

    (TCP、UDP、またはICMPトラフィックに対して)ステートフル・セキュリティ・リスト・ルールを使用している場合は、ネットワーキング・サービスにより接続が追跡され、ICMPタイプ3コード4のメッセージが自動的に許可されるため、セキュリティ・リストにこれらのメッセージを許可する明示的なルールがあることを確認する必要はありません。ステートレス・ルールでは、ICMPタイプ3コード4のメッセージに対する明示的なイングレス・セキュリティ・リスト・ルールが必要です。インスタンス・ファイアウォールが正しく設定されていることを確認します。

    ホストがこれらのメッセージを受信しているかどうかを確認するには、PMTUDの破損場所の検出を参照してください。

  3. ルーターがDon't Fragmentフラグを適用していることを確認する: ルーターがフラグを適用せずにPMTUDの使用を無視している場合、断片化されたパケットがVCN内のインスタンスに送信され、良くない状況になります(フラグメンテーションを避ける理由を参照)。VCNのセキュリティ・リストは初期フラグメントのみを認識するように構成されている可能性が高く、それ以外のフラグメントがドロップされることにより、接続がハングします。これを避けるために、ルーターはPMTUDを使用し、Don't Fragmentフラグを適用して、その接続を介して送信する断片化されていないパケットの正しいサイズを決定する必要があります。

次の図では、解決策の各部分に番号が付けられ、赤色のイタリックでコールアウトが示されています。これは、オンプレミス・ネットワークがサイト間VPNを介してVCNに接続されているシナリオ例を示しています。

この図は、ハングしている接続を修復するための解決策の各部分を示しています

MTUとPMTUDの概要、およびネットワーク接続の両側でPMTUDが機能しているか確認する方法を引き続きお読みください。

フラグメンテーションを避ける理由

なぜフラグメンテーションを避ける必要があるのか、疑問に思われるかもしれません。1つ目の理由は、アプリケーションのパフォーマンスが低下することです。フラグメンテーションが起こるとフラグメントの再構築が必要になり、フラグメントが失われた場合は再送信が必要になります。再構築および再送信には、時間とCPUリソースが必要です。

2つ目の理由は、最初のフラグメントのみにソースと宛先のポート情報が含まれていることです。つまり、ファイアウォールまたはVCNのセキュリティ・リストは、通常はポート情報を評価するように構成されているため、他のパケットをドロップする可能性があります。ファイアウォールおよびセキュリティ・リストでフラグメンテーションに対処するには、その権限を通常よりも強力に構成する必要がありますが、それは望ましくありません。

MTUの概要

インターネット・プロトコル(IP)ネットワーク上の2つのホスト間の通信では、パケットが使用されます。各パケットには、ソースと宛先のIPアドレスおよびデータのペイロードが含まれています。2つのホスト間の各ネットワーク・セグメントは、1つのパケットで伝送できるバイト数を表す最大転送単位(MTU)を持っています。

標準のインターネットMTUサイズは、1500バイトです。これは、大半のホーム・ネットワークや多くの企業ネットワーク(およびそのWi-Fiネットワーク)にも該当します。Oracle Cloud Infrastructureのデータ・センターなど、一部のデータ・センターのMTUは、それより大きい場合があります。コンピュート・インスタンスでデフォルトで使用されるMTUは、9000です。Linuxホストでは、ifconfigコマンドを使用すると、ホストのネットワーク接続のMTUが表示されます。たとえば、Ubuntuインスタンスからのifconfig出力を次に示します(MTUは赤色のイタリックで強調表示されています):

ifconfig
ens3 Link encap:Ethernet HWaddr 00:00:00:00:00:01
inet addr:10.0.6.9 Bcast:10.0.6.31 Mask:255.255.255.224
inet6 addr: 2001:db8::/32 Scope:Link
UP BROADCAST RUNNING MULTICAST 

MTU:9000

 Metric:1

比較のために、企業ネットワークに接続されたマシンからの出力を次に示します:

ifconfig
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST>


mtu 1500

そのMTUは、より一般的な1500バイトになっています。

企業VPNを介してホストが接続されている場合、VPNトンネルはトラフィックをIPSecパケット内にカプセル化してローカル・ネットワーク経由で送信する必要があるため、MTUはさらに小さくなります。例:

ifconfig
utun0: flags=81d1<UP,POINTOPOINT,RUNNING,NOARP,PROMISC,MULTICAST>


mtu 1300

2つのホストは、互いに送信できるパケットの大きさをどのようにして判断するのでしょうか。HTTP、SSH、FTPなど、多くのタイプのネットワーク・トラフィックでは、ホストはTCPを使用して新しい接続を確立します。各ホストは、2つのホスト間の最初の3方向ハンドシェーク中に、可能な最大ペイロード・サイズを示す最大セグメント・サイズ(MSS)を送信し合います。これはMTUより小さい値です。(TCPがインターネット・プロトコル(IP)内部で実行されるため、TCP/IPと呼ばれます。セグメントとTCPの関係は、パケットとIPの関係に似ています。)

tcpdumpアプリケーションを使用すると、ハンドシェイク中に共有されたMSS値を確認できます。tcpdumpの例を次に示します(MSSは赤色のイタリックで強調表示されています):

12:11:58.846890 IP 192.168.0.25.22 > 10.197.176.19.58824: Flags [S.], seq
2799552952, ack 2580095593, win 26844, options [

mss 1260

,sackOK,TS val
44858491 ecr 1321638674,nop,wscale 7], length 0

前のパケットは、SSH接続により、企業VPNに接続されたラップトップからインスタンスに送信されたものです。ラップトップでインターネット接続に使用されるローカル・ネットワークのMTUは、1500バイトです。VPNトンネルでは、1300バイトのMTUが適用されます。その後、SSH接続の試行時に、(IP接続内部で実行されている) TCPによって、1260バイト以下のTCPセグメントがサポートされることがOracle Cloud Infrastructureインスタンスに通知されます。企業VPN接続を使用する場合、通常、VPNに接続されたラップトップのMTUとMSSは、インターネット経由で通信するどの場合と比べても最小になります。

2つのホストのMTUが、そのどちらにも直接接続されていない両者間のネットワーク・リンクのMTUよりも大きいとき、さらに複雑になります。次の図に例を示します。

この図は、ネットワーク接続全体の各地点における異なるMTUレベルを示しています

この例では、2つのサーバーがあり、それぞれが9000バイトのMTUをサポートする各自のルーティング済ネットワークに直接接続されています。これらのサーバーは異なるデータ・センター内にあります。各データ・センターは、1500バイトのMTUをサポートするインターネットに接続されています。サイト間VPN IPSecトンネルは、2つのデータ・センターを接続します。そのトンネルはインターネットを経由するため、トンネル内部のMTUはインターネットよりも小さくなります。この図では、そのMTUは1380バイトです。

2つのサーバーが(たとえば、SSHを使用して)通信を試行すると、双方は3方向のハンドシェイク中にMSSを約8960にすることに合意します。最初のSSH接続設定時の最大パケット・サイズは通常1380バイト未満なので、最初のSSH接続は成功する可能性があります。片側が2つのエンドポイント間の最小リンクより大きいサイズのパケットを送信しようとしたときに、Path MTU Discovery (PMTUD)が重要になります。

PMTUDの概要

Path MTU Discoveryは、RFC 1191で定義されています。これは、通信する2つの各ホストに対して、送信するパケット内にDon't Fragmentフラグを設定するように要求することにより機能します。一方のホストから送信されたパケットがルーターに到達したが、そのエグレス(アウトバウンド)インタフェースのMTUがパケット長よりも小さい場合、ルーターはそのパケットをドロップします。また、ルーターは、ICMPタイプ3コード4のメッセージをホストに返します。このメッセージは、「Destination Unreachable, Fragmentation Needed and Don't Fragment Was Set」という内容です(RFC 792で定義されています)。これは、ルーターがホストに対して、「大きすぎるパケットを断片化しないようにそちらから指示されましたが、このパケットは大きすぎるのでこちらからは送信しません。」と伝えているということです。また、ルーターは、そのエグレス・インタフェースを介して許可される最大サイズ・パケットをホストに通知します。送信側のホストは、メッセージに示されたルーターよりも小さい値になるように、そのアウトバウンド・パケットのサイズを調整します。

次の例は、あるインスタンスが、8000バイトのパケットおよびDon't Fragmentフラグが設定されている(つまり、PMTUDが使用されている)ホスト(203.0.113.2)にインターネット経由でpingを送信しようとしたときの結果を示しています。返されたICMPメッセージは、赤色のイタリックで強調表示されています:

ping 203.0.113.2 -M do -s 8000
PING 203.0.113.2 (203.0.113.2) 8000(8028) bytes of data.
From 10.0.0.2 icmp_seq=1 

Frag needed and DF set (mtu = 1500)

レスポンスは予測したとおりのものです。宛先ホストは、MTUが1500バイトであるインターネットを経由します。送信側のホストのローカル・ネットワーク接続のMTUが9000バイトであっても、そのホストからの8000バイトのパケットは宛先ホストに到達できず、それを示すICMPメッセージが返されます。PMTUDは正しく機能しています。

比較のために、宛先ホストがサイト間VPN IPSecトンネルを経由する場合の同じpingを次に示します:

ping 192.168.6.130 -M do -s 8000
PING 192.168.0.130 (192.168.0.130) 8000(8028) bytes of data.
From 192.0.2.2 icmp_seq=1 Frag needed and DF set 

(mtu = 1358)

ここでは、VPNルーターは、このパケットを宛先に送信するためのアウトバウンド・インタフェースがVPNトンネルであると判断します。そのトンネルはインターネットを経由するため、トンネルはインターネットの1500バイトのMTUのリンクに収まる必要があります。その結果、トンネル内部で許可されるパケットは最大1360バイトになります(後からルーターによってこの値が1358に下げられたため、さらに混乱を招きやすくなっています)。

PMTUDの破損場所の検出

接続のどこかでPMTUDが機能していない場合は、その原因と場所を特定する必要があります。一般的な原因は、(パケットに収まらない制約付きリンクのあるルーターからの) ICMPタイプ3コード4のパケットが送信側ホストに返されないことです。これは、ホストとルーターの間にその種類のトラフィックをブロックしている何かが存在する場合に起こる可能性があります。また、VPNトンネル(または他の制約付きMTUリンク)のどちらかの側でも起こる可能性があります。

接続の各側からのpingの試行

破損したPMTUDに関するトラブルシューティングを行うには、接続の各側でPMTUDが機能しているかどうかを判別する必要があります。このシナリオでは、サイト間VPNを使用する接続を想定します。

ping送信の方法: PMTUDの概要に示したように、大きすぎてVPNトンネルに収まらないとわかっているパケット(たとえば、1500バイト以上のパケット)を使用して、接続の相手側のホストにpingを送信します。送信側のホストで使用されているオペレーティング・システムによっては、Don't Fragmentフラグが設定されているか確認するためのpingコマンド形式を少し変える必要がある場合があります。UbuntuとOracle Linuxではいずれも、pingコマンドで-Mフラグを使用します。

-Mフラグに関する情報は次のとおりです:

-M pmtudisc_opt
Select Path MTU Discovery strategy. pmtudisc_option may be either do
(prohibit fragmentation, even local one), want (do PMTU discovery, fragment
locally when packet size is large), or dont (do not set DF flag).

pingの例を次に示します(-Mフラグを使用、結果のICMPメッセージは赤色のイタリックで強調表示されています)

ping 

-M do

 -s 1500 192.168.6.130
PING 192.168.0.130 (192.168.0.130) 1500(1528) bytes of data.
From 10.0.0.2 icmp_seq=1 

Frag needed and DF set (mtu = 1358)

良い: PMTUDが機能している

結果に「From x.x.x.x icmp_seq=1 Frag needed and DF set (mtu = xxxx)」という行が含まれる場合、トンネルのその側のPMTUDは機能しています。ICMPメッセージのソース・アドレスは、トラフィックを送信しようとしているトンネルのパブリックIPアドレスです(たとえば、前出のUbuntuの例では203.0.113.13)。

また、接続の反対側からもpingを送信して、その側からのPMTUDが機能していることを確認します。接続の両側が、大きいパケットが収まらないトンネルが両者間に存在することを認識する必要があります。

悪い: 自分側の接続をテストして、pingが成功する場合

オンプレミス・ネットワーク内のホストからpingを送信してpingが成功した場合は、エッジ・ルーターがDon't Fragmentフラグを適用していない可能性があります。かわりに、ルーターは大きいパケットを断片化しています。最初のフラグメントは宛先ホストに到達するため、pingは成功しますが、これが誤解を招きます。pingより先のことを実行しようとすると、2つ目以降のフラグメントはドロップされ、接続がハングします。

ルーターの設定でDon't Fragmentフラグが適用されることを確認します。ルーターのデフォルト構成ではフラグが適用されますが、誰かがデフォルトを変更した可能性もあります。

悪い: 接続のVCN側をテストして、ICMPメッセージが表示されない場合

接続のVCN側からテストして、レスポンスにICMPメッセージが表示されない場合は、ICMPパケットがインスタンスに到達する前に何かがドロップされた可能性があります。

次の2つの問題が考えられます:

  • セキュリティ・リスト: ネットワーキングセキュリティ・リストに、ICMPタイプ3コード4のメッセージがインスタンスに到達することを許可するイングレス・ルールが含まれていない可能性があります。これが問題になるのは、ステートレス・セキュリティ・リスト・ルールを使用している場合のみです。ステートフル・ルールを使用している場合は、接続が追跡されてICMPメッセージは自動的に許可されるため、それを許可する特定のセキュリティ・リスト・ルールは必要ありません。ステートレス・ルールを使用している場合は、インスタンスが属するサブネットに、ソース0.0.0.0/0および任意のソース・ポートからのICMPトラフィック・タイプ3コード4を許可するイングレス・ルールを含むセキュリティ・リストが存在することを確認してください。詳細は、セキュリティ・リスト(特に既存のセキュリティ・リスト内のルールを更新するには)を参照してください。
  • インスタンス・ファイアウォール: (OSで設定されている)インスタンスのファイアウォール・ルールに、ICMPタイプ3コード4のメッセージがインスタンスに到達することを許可するルールが含まれていない可能性があります。特にLinuxインスタンスの場合は、iptablesまたはfirewalldがICMPタイプ3コード4のメッセージを許可するように構成されていることを確認してください。

PMTUDの必要性の回避

PMTUDの使用をお薦めします。ただし、状況によっては、これに依存する必要がないようにサーバーを構成できる場合もあります。VCN内のインスタンスがサイト間VPNを介してオンプレミス・ネットワーク内のホスト間と通信する場合について考えてみます。オンプレミス・ネットワークのIPアドレスの範囲はわかっています。そのアドレス範囲内のホストと通信する際に使用する最大MTUを指定する特殊ルートを、インスタンスに追加できます。VCN内部のインスタンス間通信には、引き続き9000バイトのMTUが使用されます。

次の情報は、Linuxインスタンスにそのルートを設定する方法を示しています。

インスタンスのデフォルト・ルート表には、通常は2つのルートがあります。1つはデフォルト・ルート(デフォルト・ゲートウェイ用)で、もう1つはローカル・ルート(ローカル・サブネット用)です。例:

ip route show
default via 10.0.6.1 dev ens3
10.0.6.0/27 dev ens3  proto kernel  scope link  src 10.0.6.9

オンプレミス・ネットワークのアドレス範囲と、より小さいMTUサイズを設定して、同じデフォルト・ゲートウェイを指す別のルートを追加できます。たとえば、次のコマンドでは、オンプレミス・ネットワークは1.0.0.0/8、デフォルト・ゲートウェイは10.0.6.1、オンプレミス・ネットワークに送信されるパケットの最大MTUサイズは1300です。

ip route add 1.0.0.0/8 via 10.0.6.1 mtu 1300

更新されたルート表は次のようになります:

ip route show
default via 10.0.6.1 dev ens3
1.0.0.0/8 via 10.0.6.1 dev ens3  mtu 1300
10.0.6.0/27 dev ens3  proto kernel  scope link  src 10.0.6.9

VCN内部のインスタンス間通信には、引き続き9000 MTUが使用されます。ただし、オンプレミス・ネットワークとの通信では最大1300が使用されます。この例では、オンプレミス・ネットワークとVCNの間の接続に、1300より小さいMTUを使用する部分が存在しないことを前提としています。

重要

インスタンスの再起動後は、前述のコマンドは保存されません。ルートをOS内の構成ファイルに追加すると、そのルートを永続的にすることができます。たとえば、Oracle Linuxの場合、/etc/sysconfig/network-scripts/route-<interface>というインタフェース固有ファイルを使用します。詳細は、ご使用のLinuxバージョンのドキュメントを参照してください。