解決策 1:
基本的な TCP ACK には、「X までのすべてのバイトを受信しました」と表示されます。選択的 ACK を使用すると、「X-Y と V-Z のバイトを受信しました」と言うことができます。
したがって、たとえば、ホストが 10,000 バイトを送信し、3000 ~ 5000 バイトが転送中に失われた場合、ACK は「3000 まですべてを取得しました」と言うでしょう。もう一方の端は、バイト 3001 ~ 10000 を再度送信する必要があります。 SACK は「I got 1000-2999, and 5001-10000」と言うことができ、ホストは単に 3000-5000 を送信します。
これは、帯域幅が広く、損失が多い (または遅延が大きい) リンクで優れています。問題は、特定の状況で重大なパフォーマンスの問題が発生する可能性があることです。通常の TCP ACK では、サーバーはキッド グローブを使用して高帯域幅で損失の多い接続を処理します (500 バイトを送信、待機、500 バイトを送信、待機など)。 SACK は、実際のパケット数を正確に把握しているため、高い遅延に適応できます。
ここで悪いことが起こる可能性があります。攻撃者は、サーバーに大量の再送信キューを長時間保持させ、そのすべてを何度も何度も処理することができます。これにより、CPU が固定され、RAM が消費され、必要以上の帯域幅が消費される可能性があります。簡単に言えば、軽量のシステムは、強力なサーバーに対して DoS を開始できます。
サーバーが堅牢で、大きなファイルを処理しない場合は、これに対して十分に隔離されています。
主にイントラネットまたはその他の低遅延のユーザー グループにサービスを提供している場合、SACK は何も購入せず、セキュリティ上の理由でパフォーマンスを低下させることなくオフにすることができます。
低帯域幅のリンク (完全に恣意的な経験則として 1Mbps 以下) を使用している場合、SACK は接続を飽和させて通常の操作に問題を引き起こす可能性があるため、オフにする必要があります。
最終的には、あなた次第です。何を、誰に、何から提供しているかを検討し、リスクの程度と SACK のパフォーマンスへの影響を比較検討してください。
SACK とその脆弱性の概要については、こちらをご覧ください。
解決策 2:
TCP SACK がしばしば無効になるもう 1 つの理由は、このオプションを正しく処理できないネットワーク機器が驚くほど大量に存在することです。これは、当社が提供する TCP を使用した高速ファイル転送製品でよく見られます。最も一般的な問題は、内部ネットワークから外部にデバイスを通過する TCP パケットのシーケンス番号をランダム化するなどのことを行うが、リモートから送信される可能性のある TCP SACK オプションを「ランダム化解除」しないゲートウェイ デバイスの問題です。終わり。実際の SACK 値がこれらのデバイスによって適切な値に変換されない場合、リモート エンドが選択的 ACK の利点を得るために SACK を使用しようとすると、TCP セッションはパケット損失に直面して完了しません。
人々がこのギアに予防的なソフトウェア メンテナンスをより積極的に適用すれば、おそらくこれはあまり問題にならないでしょうが、そうしない傾向があります。
解決策 3:
特定の Cisco ASA ファイアウォール アプライアンスを使用している場合、tcp_sack =1 により sftp/rsync/scp などで約 12 MB を超えるファイルのデータ転送が停止することが、苦い経験から確認できます。
いつでも失速します。
ホスト A とホスト B の間の専用の 100 mbps リンクを介して、2 つの異なるデータ センターで転送していました。両方とも cisco ファイアウォールと centos のスイッチ ハードウェアを使用していました。
これは、バッファ サイズを変更することで多少緩和できます。 sftp バッファを 2048 に設定しない限り、sftp 経由でホスト A からホスト B に 1GB のファイルを転送できませんでしたが、ホスト B が A からファイルをプルしているかどうかに関係なく転送できました。
rsync と送受信バッファ チューニングを使用した同じファイルの実験により、A から B にプッシュされた 1 GB のファイルのうち約 70 MB を取得することができました。
しかし、最終的な解決策は、ホスト A で tcp_sack を無効にすることでした。最初はオンザフライでカーネルで tcp_sack =0 を設定しましたが、最終的には /etc/sysctl.conf に追加しました