Solution 1 :
Un ACK TCP de base indique "J'ai reçu tous les octets jusqu'à X". L'accusé de réception sélectif vous permet de dire "J'ai reçu les octets X-Y et V-Z".
Ainsi, par exemple, si un hôte vous a envoyé 10 000 octets et que 3 000 à 5 000 octets ont été perdus en transit, ACK dirait "J'ai tout reçu jusqu'à 3 000". L'autre extrémité devra envoyer à nouveau les octets 3001-10000. SACK pourrait dire "J'ai 1000-2999, et 5001-10000" et l'hôte enverrait simplement 3000-5000.
C'est très bien sur une liaison à bande passante élevée, avec perte (ou retard élevé). Le problème est qu'il peut entraîner de graves problèmes de performances dans des circonstances spécifiques. Les ACK TCP normaux obligeront le serveur à traiter une connexion à bande passante élevée et avec perte avec des gants pour enfants (envoyer 500 octets, attendre, envoyer 500 octets, attendre, etc.). SACK lui permet de s'adapter au délai élevé car il sait exactement combien de paquets étaient réellement perdu.
C'est ici que de mauvaises choses peuvent arriver. Un attaquant peut forcer votre serveur à conserver une file d'attente de retransmission massive pendant une longue période, puis à traiter tout cela encore et encore et encore. Cela peut bloquer le processeur, consommer de la RAM et consommer plus de bande passante qu'il ne le devrait. En un mot, un système léger peut initier un DoS contre un serveur plus costaud.
Si votre serveur est robuste et ne sert pas de fichiers volumineux, vous êtes assez bien isolé contre cela.
Si vous servez principalement un intranet ou un autre groupe d'utilisateurs à faible latence, SACK ne vous achète rien et peut être désactivé pour des raisons de sécurité sans perte de performances.
Si vous êtes sur une liaison à faible bande passante (disons 1 Mbps ou moins en règle générale complètement arbitraire), SACK peut causer des problèmes dans les opérations normales en saturant votre connexion et doit être désactivé.
En fin de compte, c'est à vous de décider. Considérez ce que vous servez, à qui, de quoi, et pesez le degré de risque par rapport aux effets de SACK sur les performances.
Vous trouverez ici un excellent aperçu de SACK et de sa vulnérabilité.
Solution 2 :
Une autre raison pour laquelle TCP SACK est souvent désactivé est qu'il existe une quantité incroyable d'équipements réseau qui ne gèrent pas correctement cette option. Nous le voyons tout le temps avec un produit de transfert de fichiers à grande vitesse que nous fournissons et qui utilise TCP. Le problème le plus courant est celui des périphériques de passerelle qui font des choses comme randomiser les numéros de séquence pour les paquets TCP transitant par le périphérique des réseaux internes vers l'externe, mais qui ne "dé-randomisent" pas les options TCP SACK qui pourraient être envoyées de la télécommande fin. Si les valeurs SACK réelles ne sont pas reconverties en valeurs appropriées par ces appareils, la session TCP ne se terminera jamais face à la perte de paquets lorsque l'extrémité distante essaie d'utiliser SACK pour obtenir les avantages ACK sélectifs.
Ce serait probablement moins un problème si les gens appliquaient de manière plus agressive la maintenance logicielle préventive à cet équipement, mais ils ont tendance à ne pas le faire.
Solution 3 :
Je peux confirmer par expérience amère que tcp_sack =1 provoque le blocage du transfert de données sur sftp/rsync/scp, etc. avec des fichiers dépassant environ 12 Mo lors de l'utilisation de certains dispositifs de pare-feu Cisco ASA.
À CHAQUE fois, il serait bloqué.
Nous transférions via une liaison dédiée de 100 Mbps entre l'hôte A et l'hôte B dans deux centres de données différents, utilisant tous deux un pare-feu Cisco et un matériel de commutation avec centos.
Cela peut être quelque peu atténué en modifiant la taille des tampons - par ex. Je ne pouvais pas transférer un fichier de 1 Go via sftp de l'hôte A à l'hôte B à moins que je ne définisse le tampon sftp sur 2048, mais je le pouvais, que l'hôte B extraie le fichier de A.
Des expériences avec le même fichier en utilisant rsync et le réglage du tampon d'envoi/réception m'ont permis d'obtenir environ 70 Mo d'un fichier de 1 Go poussé de A à B.
Cependant, la réponse ultime était de désactiver tcp_sack sur l'hôte A. Initialement en définissant tcp_sack =0 dans le noyau à la volée - mais finalement - je l'ai ajouté à mon /etc/sysctl.conf