web-dev-qa-db-ja.com

OpenVPNネットワークでTCP接続がフリーズするのを防ぐにはどうすればよいですか?

この質問の最後に新しい詳細が追加されました。原因を突き止めている可能性があります。

UDP OpenVPNベースのVPNをtapモードで設定しています(tapが必要なのは、VPNにマルチキャストパケットを渡す必要があるためです。tunネットワーク)、インターネット上の少数のクライアント。 TCP接続がVPNを介してフリーズすることが頻繁にあります。つまり、TCP接続(たとえば、SSH接続ですが、他のプロトコルでは同様の問題)、およびセッション中のある時点で、トラフィックはそのTCPセッションを介して送信されなくなります。

これは、SSHセッションでlsコマンドを実行した場合や、長いログファイルをcatした場合など、大量のデータ転送が発生するポイントに関連しているようです。一部のGoogle検索では、いくつかの回答が表示されます サーバーの障害に関するこの前の例のように 。これは、原因としてMTUの問題である可能性が高いことを示しています。トラフィックが多い期間、VPNはVPNエンドポイント間のパイプのどこかにドロップしました。上記のリンクされた回答は、問題を軽減するために次のOpenVPN構成設定を使用することを提案しています:

fragment 1400
mssfix

これにより、VPNで使用されるMTUを1400バイトに制限し、TCP最大セグメントサイズを修正して、それより大きいパケットが生成されないようにします。これにより、問題が少し緩和されるようですが、それでも頻繁にフリーズが見られます。fragmentディレクティブの引数としていくつかのサイズを試しました:1200、1000、576、すべて同じような結果になります。2つの間の奇妙なネットワークトポロジーは考えられませんVPNサーバーがインターネットに直接接続されている pfSense マシンで実行されており、クライアントも別の場所でインターネットに直接接続されています。

もう1つの奇妙なパズルのピース:tracepathユーティリティを実行すると、問題が解決するようです。サンプル実行は次のようになります。

[~]$ tracepath -n 192.168.100.91
 1:  192.168.100.90                                        0.039ms pmtu 1500
 1:  192.168.100.91                                       40.823ms reached
 1:  192.168.100.91                                       19.846ms reached
     Resume: pmtu 1500 Hops 1 back 64 

上記の実行は、VPN上の2つのクライアント間で行われました。192.168.100.90から192.168.100.91の宛先へのトレースを開始しました。リンクで使用されるMTUを制限するために、両方のクライアントにfragment 1200; mssfix;が構成されました。上記の結果は、tracepathが2つのクライアント間の1500バイトのパスMTUを検出できたことを示唆しているようです。 OpenVPN構成で指定されたフラグメンテーション設定により、これは多少小さくなると思います。その結果はやや奇妙なことがわかりました。

ただし、見知らぬ人もいます:TCP接続が停止した状態(たとえば、途中でフリーズしたディレクトリリストを含むSSHセッション)の場合)、上記のtracepathコマンドを実行すると、接続が再び開始されます!これが当てはまる理由についての合理的な説明はわかりませんが、このように感じます最終的に問題を根絶するためのソリューションを指している可能性があります。

誰か他のことを試すための推奨事項はありますか?

編集:私は戻ってこれをもう少し見てみましたが、さらに混乱する情報しか見つかりませんでした:

  • 上記のように、OpenVPN接続を1400バイトでフラグメント化するように設定しました。次に、インターネット経由でVPNに接続し、Wiresharkを使用して、ストールが発生している間にVPNサーバーに送信されたUDPパケットを調べました。指定された1400バイトカウントを超えるものはなかったため、断片化は適切に機能しているようです。

  • 1400バイトのMTUで十分であることを確認するために、次の(Linux)コマンドを使用してVPNサーバーにpingを実行しました。

    ping <Host> -s 1450 -M do
    

    これは(私は信じています)フラグメンテーションを無効にして1450バイトのパケットを送信します(1600バイトのように明らかに大きすぎる値に設定した場合、少なくとも動作しないことを確認しました)。これらは問題なく動作するようです。問題なくホストから返信が届きます。

したがって、これはMTUの問題ではない可能性があります。他に何があるのか​​混乱しています!

編集2:うさぎの穴がさらに深くなり続けています。問題をもう少し特定しました。 VPNクライアントが使用する正確なOSに関連しているようです。私は問題を少なくとも3台のUbuntuマシン(バージョン12.04から13.04)で再現しました。大きなログファイルをcat- ingするだけで、SSH接続のフリーズを1分程度で確実に複製できます。

ただし、CentOS 6マシンをクライアントとして使用して同じテストを実行しても、問題は発生しません!私は、Ubuntuマシンで使用していたのとまったく同じOpenVPNクライアントバージョンを使用してテストしました。接続がフリーズすることなく、何時間もログファイルをcatできます。これは最終的な原因に関する洞察を提供するようですが、私はその洞察が何であるのかよくわかりません。

Wiresharkを使用してVPN上のトラフィックを調べました。私はTCP=エキスパートではないので、細かいことをどうするかわかりませんが、要点は、ある時点で、帯域幅が制限されているためにUDPパケットがドロップされることですVPNトンネル内でTCP=再送信が発生します。CentOSクライアントでは、これらの再送信が適切に行われ、問題なく動作します。ただし、Ubuntuクライアントのある時点で、リモートエンド同じTCPセグメントを繰り返し再送信し始めます(再送信のたびに送信遅延が増加します)。クライアントは、有効なように見えるものをTCP ACKをそれぞれに送信します再送信しますが、リモートエンドは引き続き同じTCPセグメントを定期的に送信し続けます。これにより、無限に拡張され、接続が停止します。私の質問は次のとおりです。

  • TCP問題の根本的な原因をトラブルシューティングおよび/または特定する方法に関する推奨事項はありますか?リモートクライアントがVPNクライアントから送信されたACKメッセージを受け入れていないかのようです。

CentOSノードとさまざまなUbuntuリリースの一般的な違いの1つは、UbuntuのLinuxカーネルバージョンがはるかに新しいことです(Ubuntu 12.04の3.2から13.04の3.8へ)。新しいカーネルのバグへのポインタかもしれませんか?もしそうなら、問題を経験しているのは私だけではないでしょう。これは特にエキゾチックなセットアップのようには思えません。

20
Jason R

このコマンドは私のためにそれを解決します:

$ Sudo ip link set dev tun0 mtu 1350 && echo ":)"

あなたはtun0設定を確認することができます

$ ip a s

乾杯!

TCPでウィンドウスケーリングを無効にします。

sysctl -w net.ipv4.tcp_window_scaling=0

その後、VPNを介したDebian/UbuntuシステムへのSSHが正常に機能します。

3
Mifpi

PuTTYを使用するWindowsでは、VPN接続のローカル接続に移動してMTUを変更する必要があります->ネットワークインターフェースの詳細(TAP Windowsアダプターなど)->詳細設定->プロパティ-> MTU(何かに変更) 1500未満)。再接続する必要がある場合があります。 WindowsとPuTTYで動作しました

0
Nick_K