Ale*_*bes 31 linux kernel tcp flooding
最近我们有一个 apache 服务器,由于 SYN 泛滥,它的响应非常缓慢。解决方法是启用 tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf
)。
如果您想要更多背景知识,我在这里发布了一个关于此的问题。
启用 syncookies 后,我们开始大约每 60 秒在 /var/log/messages 中看到以下消息:
[84440.731929] possible SYN flooding on port 80. Sending cookies.
Vinko Vrsalovic 告诉我,这意味着 syn backlog 已满,所以我将 tcp_max_syn_backlog 提高到 4096。在某些时候,我还通过发出sysctl -w net.ipv4.tcp_synack_retries=3
. 这样做之后,频率似乎下降了,消息的间隔在大约 60 到 180 秒之间变化。
接下来我发出了sysctl -w net.ipv4.tcp_max_syn_backlog=65536
,但仍然在日志中收到消息。
在所有这一切中,我一直在观察处于 SYN_RECV 状态的连接数(通过运行watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'
),它永远不会高于大约 240,远低于积压的大小。但是我有一个 Red Hat 服务器,它在 512 左右徘徊(此服务器的限制是默认值 1024)。
是否有任何其他 tcp 设置会限制积压的大小,或者我是否在咆哮错误的树?SYN_RECV 连接的数量是否应该netstat -tuna
与积压的大小相关?
尽我所能,我正在处理这里的合法连接,netstat -tuna|wc -l
徘徊在 5000 左右。我今天一直在研究这个,并发现了来自 last.fm 员工的这篇文章,它非常有用。
我还发现启用 syncookies 时 tcp_max_syn_backlog 不起作用(根据此链接)
因此,作为下一步,我在 sysctl.conf 中设置了以下内容:
net.ipv4.tcp_syn_retries = 3
# default=5
net.ipv4.tcp_synack_retries = 3
# default=5
net.ipv4.tcp_max_syn_backlog = 65536
# default=1024
net.core.wmem_max = 8388608
# default=124928
net.core.rmem_max = 8388608
# default=131071
net.core.somaxconn = 512
# default = 128
net.core.optmem_max = 81920
# default = 20480
Run Code Online (Sandbox Code Playgroud)
然后我设置了我的响应时间测试,sysctl -p
通过sysctl -w net.ipv4.tcp_syncookies=0
.
执行此操作后,处于 SYN_RECV 状态的连接数仍保持在 220-250 左右,但连接再次开始延迟。一旦我注意到这些延迟,我就重新启用了 syncookies 并且延迟停止了。
我相信我所看到的仍然是初始状态的改进,但是一些请求仍然被延迟,这比启用 syncookies 更糟糕。所以看起来我一直坚持启用它们,直到我们可以让更多的服务器联机以应对负载。即便如此,我也不确定是否有正当理由再次禁用它们,因为它们仅在(显然)服务器缓冲区已满时才发送。
但是 SYN_RECV 状态下只有约 250 个连接,syn 积压似乎并不完整!SYN 泛滥消息是否有可能是一条红鲱鱼,而不是正在填满的 syn_backlog?
如果有人有我还没有尝试过的任何其他调整选项,我很乐意尝试一下,但我开始怀疑是否由于某种原因没有正确应用 syn_backlog 设置。
Sla*_*ast 28
所以,这是一个很好的问题。
最初,我很惊讶您在启用 SYN cookie 的情况下看到任何处于 SYN_RECV 状态的连接。SYN cookie 的美妙之处在于,您可以使用加密技术作为服务器无状态地参与 TCP 3 次握手,因此我希望服务器根本不会表示半开连接,因为那将是完全相同的状态不被保留。
事实上,快速浏览源代码 (tcp_ipv4.c) 会显示有关内核如何实现 SYN cookie 的有趣信息。本质上,尽管打开了它们,内核仍会正常运行,直到其挂起的连接队列已满。这解释了您现有的 SYN_RECV 状态连接列表。
只有当挂起的连接队列已满,并且收到另一个 SYN 数据包(连接尝试),并且距离上次警告消息已经超过一分钟时,内核才会发送您看到的警告消息(“发送 cookie”) )。即使没有警告消息,也会发送 SYN cookie;警告消息只是为了提醒您问题尚未消失。
换句话说,如果您关闭 SYN cookie,消息就会消失。如果您不再被 SYN 淹没,那只会对您有用。
要解决您所做的其他一些事情:
net.ipv4.tcp_synack_retries
:
net.ipv4.tcp_syn_retries
: 改变这个对入站连接没有任何影响(它只影响出站连接)你提到的其他变量我还没有研究过,但我怀疑你的问题的答案就在这里。
如果您没有被 SYN 淹没并且机器响应非 HTTP 连接(例如 SSH),我认为可能存在网络问题,您应该让网络工程师帮助您查看。如果即使您没有被 SYN 淹没,机器通常也没有响应,如果它影响 TCP 连接的创建(非常低级别和资源非密集型),这听起来像是一个严重的负载问题
Jef*_*eff 16
我在全新安装的 Ubuntu Oneiric 11.10 上遇到了完全相同的问题,该 Ubuntu Oneiric 11.10 运行带有重载网站的网络服务器 (apache2)。在 Ubuntu Oneiric 11.10 上,默认启用了 syncookies。
我有相同的内核消息,说明可能对网络服务器端口进行 SYN 洪水攻击:
内核:[739408.882650] TCP:端口 80 上可能发生 SYN 泛洪。正在发送 cookie。
同时,我很确定,没有发生攻击。我有此消息以 5 分钟的间隔返回。这看起来就像是负载窥视,因为攻击者会一直保持高负载,同时试图让服务器停止响应请求。
调整net.ipv4.tcp_max_syn_backlog
参数没有带来任何改进 - 消息以相同的速度继续。SYN_RECV 连接的数量总是非常低(在我的情况下低于 250)这一事实表明,必须有其他一些参数负责此消息。
我在红帽网站上发现了这个错误消息https://bugzilla.redhat.com/show_bug.cgi?id=734991指出内核消息可能是应用程序端的错误(或配置错误)的结果. 当然,日志消息非常具有误导性!因为在这种情况下,这不是负责的内核参数,而是您的应用程序的参数,bee 传递给内核。
所以我们还应该看看我们的网络服务器应用程序的配置参数。获取 apache 文档并转到http://httpd.apache.org/docs/2.0/mod/mpm_common.html#listenbacklog
ListenBacklog
参数的默认值为511。(这与您在 red hat 服务器上观察到的连接数相对应。您的另一台服务器可能配置了较低的数字。)
Apache 有一个自己的配置参数,用于传入连接的积压队列。如果您有很多传入连接,并且在任何时候(就像随机的事情一样)它们几乎同时到达,这样网络服务器就无法以适当的方式为它们提供足够快的服务,您的积压将充满 511 个连接,内核将触发上述消息,说明可能存在 SYN 洪水攻击。
为了解决这个问题,我/etc/apache2/ports.conf
将以下行添加到其他 .conf 文件之一,该文件将由 apache 加载(/etc/apache2/apache2.conf
应该也可以):
ListenBackLog 5000
您还应该将 设置net.ipv4.tcp_max_syn_backlog
为一个合理的值。据我了解,内核最大值将限制您可以在 apache 配置中配置的值。所以运行:
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=5000
Run Code Online (Sandbox Code Playgroud)
调整配置后,不要忘记重新启动 apache:
sudo service apache2 restart ( or sudo /etc/init.d/apache2 restart )
Run Code Online (Sandbox Code Playgroud)
就我而言,此配置更改立即停止了内核警告。我可以通过在 apache 配置中设置较低的 ListenBackLog 值来重现消息。
在对内核 3.4.9 进行一些测试后,netstat 中的 SYN_RECV 连接数取决于
/proc/sys/net/core/somaxconn
四舍五入到 2 的下一个幂(例如 128 -> 256)/proc/sys/net/ipv4/tcp_max_syn_backlog
if 的75%/proc/sys/net/ipv4/tcp_syncookies
设置为0
或 100% if/proc/sys/net/ipv4/tcp_syncookies
设置为1
ListenBackLog
在 apache 配置中四舍五入到 2 的下一个幂(例如 128 -> 256)使用每个参数中的最小值。更改 somaxconn 或 ListenBackLog 后,必须重新启动 apache。
在增加 tcp_max_syn_backlog 之后,apache 也必须重新启动。
没有 tcp_syncookies apache 是阻塞的,为什么在这种情况下只有 75% 的 tcp_max_syn_backlog 是限制是奇怪的。并增加此参数将 SYN_RECV 连接增加到旧值的 100%,而无需重新启动 apache。
归档时间: |
|
查看次数: |
141711 次 |
最近记录: |