この質問の最後に追加された新しい詳細。私が原因を突き止めている可能性があります。
UDP OpenVPNベースのVPNをtap
モードで設定しています(tap
マルチキャストパケットを通過させるためにVPNが必要なため、tun
ネットワークでは不可能と思われるため)、インターネット上の少数のクライアントを使用しています。VPNで頻繁にTCP接続がフリーズすることがあります。つまり、TCP接続(たとえば、SSH接続ですが、他のプロトコルには同様の問題があります)を確立し、セッション中のある時点で、そのTCPセッションを介したトラフィックの送信が停止するようです。
これはls
、SSHセッションでコマンドを実行する場合やcat
、長いログファイルを使用する場合など、大量のデータ転送が発生するポイントに関連しているようです。一部のGoogle検索では、Server Faultで次のような多数の回答が表示されます。原因はMTUの問題である可能性が高いことを示しています。トラフィックが多い期間中、VPNは、 VPNエンドポイント。上記のリンクの回答は、次のOpenVPN構成設定を使用して問題を軽減することを提案しています。
fragment 1400
mssfix
これにより、VPNで使用されるMTUが1400バイトに制限され、TCPの最大セグメントサイズが修正され、それより大きいパケットが生成されなくなります。これは問題を少し緩和するようですが、それでもフリーズが頻繁に発生します。fragment
ディレクティブの引数として、1200、1000、576のサイズをいくつか試しましたが、すべて同様の結果が得られました。このような問題を引き起こす可能性のある、両端間の奇妙なネットワークトポロジは考えられません。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
。fragment 1200; mssfix;
リンクで使用されるMTUを制限しようとして、両方のクライアントが構成されました。上記の結果は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
大きなログファイルを作成するだけで、1分程度でSSH接続のフリーズを確実に複製できます。
ただし、CentOS 6マシンをクライアントとして使用して同じテストを実行しても、問題は発生しません。Ubuntuマシンで使用していたのとまったく同じOpenVPNクライアントバージョンを使用してテストしました。cat
接続がフリーズすることなく、何時間もファイルを記録できます。これは、究極の原因に関するいくつかの洞察を提供するようですが、私はその洞察が何であるかだけではわかりません。
Wiresharkを使用してVPN経由のトラフィックを調べました。私はTCPの専門家ではないので、詳細をどうするかわかりませんが、要点は、インターネットリンクの帯域幅が制限されているためにUDPパケットがドロップされ、内部でTCP再送信が発生することですVPNトンネル。CentOSクライアントでは、これらの再送信が適切に行われ、状況は順調に進みます。ただし、Ubuntuクライアントのある時点で、リモートエンドは同じTCPセグメントの再送信を繰り返し開始します(再送信のたびに送信遅延が増加します)。クライアントは有効なTCP ACKのように見えるものを各再送信に送信しますが、リモートエンドは引き続き同じTCPセグメントを定期的に送信し続けます。これにより、広告が無限に拡張され、接続が停止します。ここに私の質問は次のようになります:
- TCPの問題の根本原因をトラブルシューティングおよび/または特定する方法について、誰かが推奨事項を持っていますか?リモートエンドが、VPNクライアントから送信されたACKメッセージを受け入れていないかのようです。
CentOSノードとさまざまなUbuntuリリースの一般的な違いの1つは、Ubuntuの方がはるかに新しいLinuxカーネルバージョン(Ubuntu 12.04の3.2から13.04の3.8まで)を持つことです。新しいカーネルのバグへのポインターですか?もしそうなら、問題を経験しているのは私だけではないだろうと思います。これは特にエキゾチックなセットアップのようには思えません。
tun
ネットワークと、(例えば、マルチキャストルーティングデーモン実行により可能であるべきであるPIMDを)と OpenVPNサーバーの使用を有する--topology
「サブネット」に設定されたオプションを-参照マニュアル