web-dev-qa-db-ja.com

「Linux-Linux」ではインターネット経由のパケット損失が発生しますが、「Windows-Linux」では発生しません(tldr:MTUです)

私は今、インターネット上のマシン間のパケット損失に関する現象と戦う追加の白髪を取得しています。

下の図を確認してください。 「SSH」を使用するときはいつでも「HTTPS」を使用できることに注意してください。そのプロトコルでも同じ現象が発生します。

Fedora 22を実行しているSSHサーバーは「サイトA」(ワインレッド)にあります。 「最近」まで接続の問題はありませんでした。

Fedora22またはFedora23を実行しているAmazonEC2マシンから「サイトA」へのSSH接続は完全に機能します(「AmazonEC2」ボックス内に緑色で​​表示されているホスト)

同じAS上にある「サイトB」から「サイトA」へのSSH接続は、私がテストしたどのFedoraシステム(オレンジ色のボックス)からも機能しません。ただし、それらdoは、PuTTYを使用してWindows7システムから機能します。どちらの場合も、同じ(デュアルブート)ハードウェアが関係します。 「サイトB」にもファイアウォールがありますが、それは何の役割も果たしていないようです。FritzBoxルーターから直接接続をセットアップしようとしましたが、Fedoraでは機能しませんでしたが、Windowsでは機能しました。

問題はどのように現れますか:

SSHを使用して接続すると、最初のパケット交換が行われます(tcpdumpで示されています)。ただし、20パケット程度になると、発信パケットはどこにも行かないように見えます。サイトAから確認応答が返されることはありません。パスワードプロンプトが表示されることはありません。 CTRL-Cは接続を適切にリセットしますが、その後Linuxはまだ少しACKされていないパケットを送信しようとします。

The setup

ISPに問題があるのではないかと思います。特に、「最近」変更されたのはサイトBに「固定IPアドレス」を実装するために、ISPが疑わしい魔法を実行しているのではないかと思います。

ただし、SSH接続がWindowsからは機能するが、同じ条件下でLinuxからは機能しないという事実をネットワーク的に説明する理由がわかりません。何を探すべきですか?

2
David Tonhofer

パケットトレースは次のことを示しています。

22:29:22.180852 IP (tos 0x0, ttl 64, id 52989, offset 0, flags [DF], proto TCP (6), length 1900)   
SITE_B_LAN_ADDR.54358 > SITE_A.SSH_PORT: Flags [P.], cksum 0x05c4 (incorrect -> 0xadce), seq 22:1870, ack 22, win 229, options [nop,nop,TS val 4294917498 ecr 71539420], length 1848

パケットにフラグメント禁止オプションが設定された1900サイズのバイト長に注意してください。一般的なMTUは、1400〜1500バイトになる傾向があります。

おそらくパケットが大きすぎるICMPメッセージを返しますが、サイトAファイアウォールで受信するすべてのICMPトラフィックをドロップします。

これをテストするには、ファイアウォールでicmpおよびtcp22のパケットトレースを実行する必要があります。

サイトAで受信するICMPパケットが大きすぎるメッセージを許可していることを確認してください。

または、サイトAのLinuxボックスのMTUをネットワークMTUのサイズ未満に設定してみてください。 Fedoraではジャンボパケットが有効になっているが、Windowsでは有効になっていないと推測するのは危険です。

2
Matthew Ife

親愛なるコメンテーターの提案の後、私はMTUの問題が原因である可能性があるかどうかを調べました。

Fedoraシステムから「サイトA」から「サイトB」に接続しようとすると、以下が見つかりました。 Windowsシステムでは、すべてが完全に正常に機能しています。wiresharkは、発信パケットの長さが1158バイトを超えることはないことを示しているため、そこで問題は発生しません。

簡単に言えば、これを正しく読んだ場合:

  1. 小さなパケットの最初の正常な交換があります。
  2. 長さ1900のパケットが送信されます。ローカルネットワークのMTUが1500であるため、ネットワークカードがこれを分割すると思います。
  3. アドレス10.10.80.7のISPネットワーク内のルーターは、「パケットをMTU1492にフラグメント化してください」と指示します。
  4. ウィルコ!長さ1492のパケットが送信されます。
  5. アドレス10.10.80.7のISPネットワーク内のルーターは、「パケットをMTU1492にフラグメント化してください」と指示します。
  6. ここから物事は下り坂になります。

ISPでチケットを開く必要があるようです(POST Telecom Luxembourgところで、誰かが同様の問題をグーグルで検索した場合に備えて)。

また、修復を提案します。 MTUをSITE_Aから1000に強制します。

ip route add $SITE_A_IP via $GATEWAY_IP dev $ETHDEV mtu lock 1000

確かに、これは問題を修正します。

参考情報

pingを使用してMTUの動作をテストします:

ping -c $COUNT -M $MTUDS -s $PPLSZ $Host

どこ

  • COUNT=1 "1つのpingのみ"
  • MTUDS=do:MTU検出戦略は、「ローカルのものでも断片化を禁止する」です。つまり、「DF」(断片化しない)ビットを設定します(なぜこれは「行う」のですか?わからない)。これを使って。
  • MTUDS=want:MTU検出戦略は、「PMTU検出を実行し、パケットサイズが大きい場合はローカルでフラグメント化する」です。つまり、「DF」ビットを設定し、ローカルでフラグメント化します。
  • MTUDS=dont:MTU検出戦略は、「「DF」ビットを設定しない」、つまり必要に応じてフラグメント化することです。
  • PPLSZ=1464:ICMP pingパケットのペイロードサイズ(バイト単位)。

tcpdumpを使用して、すべてのICMPパケットと「サイトA」との間のパケットを監視します:

tcpdump -vvv -n -nn icmp or '(' Host $SITE_A_IP ')'

しかし、これは少し読みにくいです。

カーネルが「サイトA」へのMTUについてどのように考えているかを監視します。

watch ip route get to $SITE_A_IP

デフォルトよりも低いMTUは、最初にpingが失敗してから600秒のTTL)でキャッシュされることに注意してください。

シナリオ

バイト単位の最大IPパケットサイズ(つまりイーサネットペイロードのサイズ)が1492(Amazon EC2の場合)であるとすると、IPおよびICMPヘッダーに28バイトが使用されるため、興味深いpingペイロードサイズは1465になります。情報は1493、最大1バイトpasを与えます。

次にping -c 1 -M want -s 1465 $Host_IPは次のことを行います:

最初のpingで、「Frag required and DF set(mtu = 1492)100%packetloss」」が表示されます。tcpdumpは、エコー要求パート1(長さ1493)が送信されていることを示しています。ターゲットネットワークのルーターが、MTU1492までフラグメント化する要求とともに「ICMPunreachable」を送り返します。MTU= 1492のキャッシュされたエントリがカーネルルートキャッシュに表示されます。

以降のpingで、「1パケットが送信され、1パケットが受信されました」というメッセージが表示されます。 tcpdumpは、エコー要求パート1(長さ1492)とエコー要求パート2(長さ21、オフセット1472)、および対応するエコー応答(長さ1493)を示しています。

またはtracerouteを使用できます

# traceroute --mtu SITE_A 1500

パケットサイズ1500。Tracerouteは、ルート10.10.80.7にMTU1492があることを示しています。

traceroute to SITE_A (SITE_A_IP), 30 Hops max, 1500 byte packets
 1  gateway (192.168.10.1)  0.550 ms  0.536 ms  0.393 ms
 2  192.168.178.1 (192.168.178.1)  1.458 ms  1.485 ms  1.344 ms
 3  10.10.80.7 (10.10.80.7)  4.889 ms F=1492  2.968 ms  4.854 ms
 4  10.10.80.7 (10.10.80.7)  4.955 ms !F-1492  3.559 ms !F-1492  5.022 ms !F-1492

1492で試してください:同じ問題です!

traceroute to SITE_A (SITE_A_IP), 30 Hops max, 1492 byte packets
 1  gateway (192.168.10.1)  0.635 ms  0.554 ms  0.483 ms
 2  192.168.178.1 (192.168.178.1)  1.510 ms  1.504 ms  1.311 ms
 3  10.10.80.7 (10.10.80.7)  48.305 ms  17.436 ms  5.496 ms
 4  10.10.80.7 (10.10.80.7)  5.963 ms !F-1492  6.865 ms !F-1492  4.887 ms !F-1492

1491で試してください:同じ問題です!

traceroute to SITE_A (SITE_A_IP), 30 Hops max, 1491 byte packets
 1  gateway (192.168.10.1)  0.594 ms  0.650 ms  0.492 ms
 2  192.168.178.1 (192.168.178.1)  1.716 ms  1.782 ms  1.580 ms
 3  10.10.80.7 (10.10.80.7)  7.327 ms  7.385 ms  4.775 ms
 4  10.10.80.7 (10.10.80.7)  5.210 ms !F-1492  5.624 ms !F-1492  4.841 ms !F-1492

1490で試してください:私たちは通り抜けます。そこには1つずつエラーが発生するはずです。

traceroute to SITE_A (SITE_A_IP), 30 Hops max, 1490 byte packets
 1  gateway (192.168.10.1)  0.616 ms  0.688 ms  0.484 ms
 2  192.168.178.1 (192.168.178.1)  1.712 ms  1.853 ms  1.611 ms
 3  10.10.80.7 (10.10.80.7)  6.248 ms  7.008 ms  4.995 ms
 4  SITE_A_IP.dyn.luxdsl.pt.lu (SITE_A_IP)  12.441 ms !X  9.641 ms !X  9.576 ms !X

さらに興味深い情報:

1
David Tonhofer