Lösung 1:
Ein einfaches TCP ACK sagt:"Ich habe alle Bytes bis X erhalten." Mit der selektiven Bestätigung können Sie sagen:„Ich habe die Bytes X-Y und V-Z erhalten.“
Wenn Ihnen beispielsweise ein Host 10.000 Bytes gesendet hat und die Bytes 3000-5000 während der Übertragung verloren gegangen sind, würde ACK sagen:"Ich habe alles bis zu 3000." Das andere Ende müsste die Bytes 3001-10000 erneut senden. SACK könnte sagen "Ich habe 1000-2999 und 5001-10000" und der Host würde nur die 3000-5000 senden.
Dies ist großartig bei einer verlustbehafteten (oder stark verzögerten) Verbindung mit hoher Bandbreite. Das Problem ist, dass es unter bestimmten Umständen zu schwerwiegenden Leistungsproblemen kommen kann. Normale TCP-ACKs veranlassen den Server, eine verlustbehaftete Verbindung mit hoher Bandbreite mit Samthandschuhen zu behandeln (500 Bytes senden, warten, 500 Bytes senden, warten usw.). SACK passt sich der hohen Verzögerung an, weil es genau weiß, wie viele Pakete eigentlich waren verloren.
Hier können schlimme Dinge passieren. Ein Angreifer kann Ihren Server dazu zwingen, lange Zeit eine riesige Warteschlange für die erneute Übertragung zu halten und dann das ganze verdammte Ding immer und immer wieder zu verarbeiten. Dies kann die CPU binden, RAM auffressen und mehr Bandbreite verbrauchen, als es sollte. Kurz gesagt, ein leichtes System kann einen DoS gegen einen kräftigeren Server initiieren.
Wenn Ihr Server robust ist und keine großen Dateien bereitstellt, sind Sie dagegen ziemlich gut isoliert.
Wenn Sie hauptsächlich ein Intranet oder eine andere Gruppe von Benutzern mit geringer Latenz bedienen, kauft Ihnen SACK nichts und kann aus Sicherheitsgründen ohne Leistungsverlust deaktiviert werden.
Wenn Sie sich auf einer Verbindung mit geringer Bandbreite befinden (z. B. 1 Mbit/s oder weniger als völlig willkürliche Faustregel), kann SACK im normalen Betrieb Probleme verursachen, indem es Ihre Verbindung überlastet, und sollte deaktiviert werden.
Letztendlich liegt es an Ihnen. Überlegen Sie, was Sie wem aus was anbieten, und wägen Sie den Grad Ihres Risikos gegen die Leistungsauswirkungen von SACK ab.
Hier finden Sie einen großartigen Überblick über SACK und seine Schwachstellen.
Lösung 2:
Ein weiterer Grund, warum TCP SACK oft deaktiviert ist, ist, dass es eine erstaunliche Menge an Netzwerkgeräten gibt, die diese Option nicht richtig handhaben. Wir sehen dies ständig bei einem Hochgeschwindigkeits-Dateiübertragungsprodukt, das wir anbieten und das TCP verwendet. Das häufigste Problem ist das von Gateway-Geräten, die beispielsweise Sequenznummern für TCP-Pakete randomisieren, die das Gerät von internen zu externen Netzwerken durchlaufen, aber die TCP-SACK-Optionen, die möglicherweise von der Remote gesendet werden, nicht „unzufällig“ machen Ende. Wenn die tatsächlichen SACK-Werte von diesen Geräten nicht in die richtigen Werte zurückübersetzt werden, wird die TCP-Sitzung angesichts eines Paketverlusts niemals abgeschlossen, wenn das entfernte Ende versucht, SACK zu verwenden, um die selektiven ACK-Vorteile zu nutzen.
Wahrscheinlich wäre dies weniger ein Problem, wenn die Leute aggressiver vorbeugende Softwarewartung auf diese Ausrüstung anwenden würden, aber sie neigen dazu, dies nicht zu tun.
Lösung 3:
Ich kann aus bitterer Erfahrung bestätigen, dass tcp_sack =1 eine blockierte Datenübertragung über sftp/rsync/scp usw. mit Dateien von mehr als etwa 12 MB verursacht, wenn bestimmte Cisco ASA-Firewall-Appliances verwendet werden.
JEDES Mal würde es ins Stocken geraten.
Wir haben über eine dedizierte 100-Mbit/s-Verbindung zwischen Host A und Host B in zwei verschiedenen Rechenzentren übertragen, beide mit Cisco-Firewall und Switch-Hardware mit Centos.
Dies kann etwas gemildert werden, indem die Puffergrößen geändert werden - z. Ich konnte keine 1-GB-Datei per sftp von Host A auf Host B übertragen, es sei denn, ich habe den sftp-Puffer auf 2048 gesetzt, aber ich könnte es unabhängig davon tun, ob Host B die Datei von A zieht.
Experimente mit derselben Datei mit rsync und Sende-/Empfangspuffer-Tuning ermöglichten es mir, etwa 70 MB einer 1-GB-Datei zu erhalten, die von A nach B gepusht wurde.
Die ultimative Antwort war jedoch, tcp_sack auf Host A zu deaktivieren. Zunächst durch Setzen von tcp_sack =0 im Kernel on-the-fly – aber letztendlich – fügte ich es meiner /etc/sysctl.conf
hinzu