尽管SYN_RECV连接数较少,但日志中仍存在“可能的SYN泛洪”


30

最近,我们有一个apache服务器,由于SYN泛洪,响应速度非常慢。解决方法是启用tcp_syncookies(net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf)。

如果您需要更多背景知识,我在这里发布了一个与此有关的问题。

启用syncookie之后,我们大约每60秒开始在/ var / log / messages中看到以下消息:

[84440.731929] possible SYN flooding on port 80. Sending cookies.

Vinko Vrsalovic告诉我,这意味着syn待办事项已满,因此我将tcp_max_syn_backlog提高到4096。在某些时候,我还通过发出来将tcp_synack_retries降低到3(从默认值5降低)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

然后,我设置了响应时间测试,sysctl -p并通过运行和禁用了syncookie sysctl -w net.ipv4.tcp_syncookies=0

完成此操作后,处于SYN_RECV状态的连接数仍保持在220-250附近,但是连接又开始延迟。一旦发现这些延迟,便重新启用了syncookies,并且延迟停止了。

我相信我所看到的仍然比初始状态有所改善,但是一些请求仍然被延迟,这比启用syncookies更糟糕。因此,在我们让更多的服务器联机以应对负载之前,我似乎一直启用它们。即使这样,我也不确定是否有再次禁用它们的正当理由,因为它们仅在服务器缓冲区已满时才发送(显然)。

但是,在SYN_RECV状态下,仅约250个连接就无法满足syn积压!SYN泛洪消息是否有可能是一条红色鲱鱼,而不是填充了syn_backlog的东西?

如果有人还有其他调优选项,但我还没有尝试过,我会很乐意尝试一下,但是我开始怀疑syn_backlog设置是否由于某些原因未正确应用。


Answers:


27

所以,这是一个整洁的问题。

最初,我很惊讶您看到启用了SYN cookie的任何处于SYN_RECV状态的连接。SYN cookie的优点在于,您可以使用加密技术无状态地作为服务器参与TCP 3-way握手,因此,我希望服务器根本不代表半开连接,因为那将是完全相同的状态,而不是不被保留。

实际上,快速浏览源代码(tcp_ipv4.c)会显示有关内核如何实现SYN cookie的有趣信息。从本质上讲,尽管打开了它们,内核仍会像往常一样运行,直到其挂起的连接队列已满。这说明了您现有的处于SYN_RECV状态的连接列表。

仅当挂起的连接队列已满,并且接收到另一个SYN数据包(连接尝试),并且距上一条警告消息已经超过一分钟时,内核才会发送您已经看到的警告消息(“发送cookie” )。即使没有警告消息,也会发送SYN cookie。警告消息只是提醒您问题尚未消除。

换句话说,如果关闭SYN cookie,该消息将消失。如果您不再被SYN淹没,那只会为您解决。

要解决您已经完成的其他一些事情:

  • net.ipv4.tcp_synack_retries
    • 增大此比率不会对那些欺骗的传入连接产生任何积极影响,也不会对收到SYN cookie而非服务器端状态的任何连接产生积极影响(也不会重试)。
    • 对于传入的欺骗连接,增加它会增加发送到假地址的数据包的数量,并可能增加该欺骗地址在连接表中保留的时间(这可能会带来严重的负面影响)。
    • 在正常负载/传入连接数下,此值越高,您越有可能通过丢弃数据包的链接快速/成功完成连接。增加收益的收益递减。
  • net.ipv4.tcp_syn_retries:更改此设置不会对入站连接产生任何影响(仅影响出站连接)

您提到的其他变量我还没有研究过,但我怀疑您问题的答案就在这里。

如果您没有被SYN淹没,并且计算机正在响应非HTTP连接(例如SSH),我认为可能是网络问题,您应该请网络工程师来帮助您解决问题。如果即使您没有被SYN淹没,机器通常也无响应,则如果它影响TCP连接的创建(相当低的级别和资源不密集),这听起来像是一个严重的负载问题。


谢谢-这是一个有趣且有益的答案。它肯定回答了我关于SYN_RECV状态下的连接与cookie发送之间的关系的查询。该机器对非HTTP(包括SSH和HTTPS)的响应速度比HTTP少得多。因此,我们决定减少流量是必须的。
亚历克斯·福布斯

关于让网络工程师看一下-很好的建议,但是我们正在从这个数据中心迁移,因此,当我们在其他地方将几个新服务器联机时,这可能不值得。我认为您可能认为这是网络问题-负载平衡器或防火墙有问题。再次感谢您的见解!
亚历克斯·福布斯

13

我在全新安装的Ubuntu Oneiric 11.10上遇到了完全相同的问题,该版本运行的Web服务器(apache2)的网站负载很大。在Ubuntu Oneiric 11.10上,默认启用syncookies。

我有相同的内核消息,说明在Web服务器端口上可能发生了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,指出内核消息可能是由于应用程序端的错误(或配置错误)导致的。当然,日志消息非常容易引起误解!因为在这种情况下,这不是负责内核的参数,而是将应用程序的参数传递给内核。

因此,我们还应该查看Web服务器应用程序的配置参数。获取apache文档并转到http://httpd.apache.org/docs/2.0/mod/mpm_common.html#listenbacklog

ListenBacklog参数的默认值为511。(这与您在Red Hat服务器上观察到的连接数相对应。您的另一台服务器可能配置的连接数较少。)

Apache对于传入连接的积压队列具有自己的配置参数。如果您有很多传入连接,并且在任何时候(只是随机的事情)它们几乎都同时到达,从而使Web服务器无法以适当的方式为它们提供足够快的服务,则您的积压将拥有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

调整配置后,请不要忘记重新启动apache:

sudo service apache2 restart ( or sudo /etc/init.d/apache2 restart )

就我而言,此配置更改立即停止了内核警告。我可以通过在apache配置中设置较低的ListenBackLog值来重现消息。


2
好答案。假设您说的是正确的,我会将其标记为已接受的答案,但我无法真正测试它-减少负载解决了该问题,并且我制定了一项政策,不要无缘无故地修补生产服务器:)
Alex Forbes

我可以确认这实际上是有效的,它是内核的反DDOS功能,但是当您收到说很多网络流量时,它最终会阻塞您的合法用户!
Areeb Soo Yasir

5

在使用内核3.4.9进行一些测试之后,netstat中的SYN_RECV连接数取决于

  • /proc/sys/net/core/somaxconn 四舍五入到下一个2的幂(例如128-> 256)
  • /proc/sys/net/ipv4/tcp_max_syn_backlogif的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。


而且该调用/bin/echo m >/proc/sysrq-trigger通常会导致端口80上可能发生SYN泛洪。发送cookie消息。
usoft 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.