何时关闭 TCP SACK?

何时关闭 TCP SACK?

我一直在查看 Linux 调优参数,发现有些配置中 SACK 已关闭。有人能解释一下吗?

这将针对繁忙的 Web 服务器进行调整。

答案1

基本 TCP ACK 表示“我收到了直到 X 的所有字节。”选择性 ACK 允许您表示“我收到了字节 XY 和 VZ。”

因此,例如,如果主机向您发送了 10,000 个字节,而 3000-5000 个字节在传输过程中丢失,ACK 会说“我已收到 3000 字节之前的所有内容”。另一端必须再次发送 3001-10000 个字节。SACK 可能会说“我已收到 1000-2999 和 5001-10000”,主机只会发送 3000-5000 个字节。

对于高带宽、有损(或高延迟)的链路来说,这非常好。问题是,在特定情况下,它可能会导致严重的性能问题。正常的 TCP ACK 会让服务器小心翼翼地处理高带宽、有损的连接(发送 500 字节,等待,发送 500 字节,等待,等等)。SACK 让它适应高延迟,因为它确切地知道有多少数据包实际上丢失的。

这就是可能发生的坏事。攻击者可以迫使您的服务器长时间保留大量重传队列,然后一遍又一遍地处理整个该死的东西。这会占用大量 CPU、消耗大量 RAM 并消耗比应有的更多的带宽。简而言之,轻量级系统可以对更强大的服务器发起 DoS 攻击。

如果您的服务器很强大并且不提供大文件,那么您就可以很好地避免这种情况。

如果您主要为内部网或其他低延迟用户群提供服务,那么 SACK 对您没有任何好处,并且可以出于安全原因将其关闭,且不会造成任何性能损失。

如果您使用的是低带宽链路(根据经验法则,假设带宽为 1Mbps 或更低),SACK 可能会使您的连接饱和,从而导致正常运行出现问题,因此应将其关闭。

最终,这取决于您。考虑一下您要提供什么服务、服务对象、服务来源,并权衡您的风险程度与 SACK 的性能影响。

这里有一篇关于 SACK 及其漏洞的精彩概述这里。

答案2

TCP SACK 经常被禁用的另一个原因是,大量的网络设备无法正确处理此选项。我们在提供的使用 TCP 的高速文件传输产品中经常看到这种情况。最常见的问题是网关设备会执行一些操作,例如将通过设备从内部网络传输到外部网络的 TCP 数据包的序列号随机化,但不会“取消随机化”可能从远程端发送的 TCP SACK 选项。如果这些设备没有将实际的 SACK 值转换回正确的值,那么当远程端尝试使用 SACK 获得选择性 ACK 的好处时,TCP 会话将永远无法在数据包丢失的情况下完成。

如果人们更积极地对这些设备进行预防性软件维护,那么这个问题可能就不会那么严重了,但他们往往不会这样做。

答案3

我可以从痛苦的经历中确认,当使用某些 Cisco ASA 防火墙设备时,tcp_sack = 1 会导致通过 sftp/rsync/scp 等进行的数据传输停滞,文件大小超过 12mb 左右。

每次它都会停滞。

我们在两个不同的数据中心的主机 A 和主机 B 之间通过专用的 100mbps 链路进行传输,均使用带有 centos 的 cisco 防火墙和交换机硬件。

通过修改缓冲区大小可以在一定程度上缓解这一问题 - 例如,除非我将 sftp 缓冲区设置为 2048,否则我无法通过 sftp 将 1GB 文件从主机 A 传输到主机 B,但无论主机 B 是否从 A 提取文件,我都可以这样做。

使用 rsync 和发送/接收缓冲区调整对同一文件进行实验,使我能够从 A 推送到 B 的 1GB 文件中的约 70mb。

然而,最终的答案是在主机 A 上禁用 tcp_sack。最初,我在内核中动态设置 tcp_sack = 0 - 但最终 - 我将其添加到我的 /etc/sysctl.conf 中

相关内容