厦门高防服务器如何优化TCP/IP参数以提升抗攻击能力?
去年下半年,我一个做游戏私服的朋友遇到麻烦了。他在厦门某机房托管了一台高防服务器,配置不错,防御也买得挺高。但一到晚上高峰期,服务器就开始抽风——延迟忽高忽低,玩家频繁掉线,后台看CPU和带宽都没跑满,就是莫名其妙地卡。
他一开始怀疑是机房线路问题,找客服扯了好几天,换IP、换线路,折腾了一圈,问题依旧。后来他找到我,让我帮忙看看。我登录服务器之后,用 netstat -s 扫了一眼TCP统计信息,心里大概有数了。
你猜怎么着?那台服务器的TCP参数几乎是出厂默认状态。在高并发场景下,大量的SYN包在半连接队列里排队超时,重传率居高不下,还有不少连接直接被丢掉了。说白了,高防机房的硬防虽然把大流量攻击挡在了门外,但服务器自身的内核却因为参数没调好,自己先“虚”了,稍微有点风吹草动就扛不住。
那天晚上我花了半小时,把几个关键的TCP/IP内核参数重新配置了一遍。重启网络服务之后,他再进游戏测试,延迟从之前的两三百毫秒降到了五六十,连续跑了三天没掉过线。他问我改了什么魔法,我说哪有什么魔法,就是把服务器的“体质”调好了。
今天咱们就聊聊,在厦门高防服务器上,如何通过优化TCP/IP参数,让这台机器本身变得更抗揍。
一、为什么TCP/IP参数调优,和高防能力直接挂钩?
很多人对高防服务器有个误解,觉得防御能力全靠机房前端的硬件防火墙。防火墙确实能清洗掉大流量的DDoS攻击,比如把几百G的UDP Flood拦在外面。但有一种攻击,硬件防火墙不一定能完全替服务器扛住——那就是利用TCP协议栈自身弱点的攻击。
比如SYN Flood,攻击者发送大量伪造的SYN请求,但不完成三次握手。服务器的内核协议栈会为每个SYN请求分配半连接资源,等待超时。如果半连接队列被塞满,正常的用户就再也连不进来了。
再比如,当你的服务器遭受混合攻击时,网络状况会变得很差,丢包率上升。如果TCP的重传算法和拥塞控制还是老一套,它会不停地超时重传、降低窗口,导致正常用户的访问也变得极其缓慢。
厦门这边的机房,很多用的是BGP多线接入,网络环境本身就不算特别稳定,电信、联通、移动跨网访问时丢包和抖动是家常便饭。在这种环境下,一个调校得当的TCP/IP协议栈,能让你的服务器在恶劣网络条件下依然保持“呼吸通畅”。它提升的不是硬扛流量的上限,而是服务器在压力下的“生存质量”。
二、动手之前,先搞清楚几个核心概念
在改参数之前,咱们得先简单过一下TCP协议栈的几个关键“部件”,不然一会儿你看到那些参数名会一头雾水。
第一个是半连接队列,也叫SYN队列。当服务器收到客户端的SYN包时,会把这个连接放进半连接队列,等收到ACK确认后,再移动到全连接队列。SYN Flood攻击打的就是这个半连接队列。
第二个是全连接队列,也叫Accept队列。三次握手完成后,连接就在这里排队,等着应用程序调用accept()把它取走。如果应用程序处理不过来,这个队列满了,新的连接就会被拒绝或者丢弃。
第三个是TCP窗口大小。它决定了在收到对方确认之前,你能发送多少数据。窗口太小,传输效率就低;窗口太大,在丢包率高的网络里反而会加剧拥塞。
第四个是拥塞控制算法。它决定了TCP在检测到丢包时怎么调整发送速度。传统的算法遇到丢包就大幅降速,而新的算法比如BBR,在丢包环境下表现好得多。
理解了这些,后面的配置你就不会觉得是盲人摸象了。
三、实战:厦门高防服务器的内核参数调优清单
下面我直接给出经过验证的参数配置方案。这些配置在厦门多家机房的服务器上跑过,效果都不错。你需要用root权限修改 /etc/sysctl.conf 文件,然后执行 sysctl -p 使其生效。
第一部分:对抗SYN Flood,保护半连接队列
这是最核心的抗攻击调优,专门针对SYN Flood类型的攻击。
net.ipv4.tcp_syncookies = 1
这个参数设为1,表示当半连接队列满了之后,启用SYN Cookie机制。它不占用队列资源,通过算法在SYN+ACK包中编码信息,如果客户端返回的ACK是合法的,服务器再重建连接。这是抗SYN Flood的第一道防线,必须开。
net.ipv4.tcp_syn_retries = 2
服务器主动发送SYN+ACK后没收到回应,会重试几次。默认是5次,超时要将近三分钟。在高防场景下,等这么久太浪费资源了,改成2次,一两分钟没回应就直接放弃,把资源腾出来给正常用户。
net.ipv4.tcp_synack_retries = 2
同理,这个控制服务器回复SYN+ACK的重试次数,也改成2。
net.ipv4.tcp_max_syn_backlog = 8192
这是半连接队列的最大长度。默认值通常是1024或者更小,对于稍微有点流量的服务器来说根本不够用。调大到8192甚至16384,给SYN队列留出足够的缓冲空间。
第二部分:保护全连接队列,让应用来得及处理
net.core.somaxconn = 1024
这个是全连接队列的大小。很多应用程序比如Nginx、Redis,默认的listen backlog只有128,在高并发下很容易溢出。把这个系统级的参数调大到1024或更高,同时也要在Nginx等应用里把backlog配上去。
net.core.netdev_max_backlog = 5000
当网卡收到数据包的速度比内核处理的速度快时,数据包会在这个队列里排队。队列太小就会丢包。调大到5000,给服务器一点“缓冲”的余地。
第三部分:让数据传输更快、更稳
net.ipv4.tcp_window_scaling = 1
TCP窗口缩放。这个必须开,否则TCP窗口最大只能到64KB,在厦门的BGP网络环境下,带宽稍微大一点就会成为瓶颈。
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
这几行配置把TCP接收和发送缓冲区的最大值提高到了128MB。默认值太小了,在高带宽高延迟的网络里跑不起来。三个数值分别是最小值、默认值、最大值,给TCP协议栈足够的“内存”去缓冲数据。
net.ipv4.tcp_fastopen = 3
这是TCP Fast Open,允许在第一次握手时就携带数据,减少一次RTT的延迟。对于移动端或者跨网访问的用户,效果非常明显。设为3表示对客户端和服务器都启用。
第四部分:选择合适的拥塞控制算法
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
这两行要一起说。BBR是谷歌开发的拥塞控制算法,它和传统的CUBIC不一样——CUBIC遇到丢包就降速,而BBR通过测量带宽和延迟来主动控制发送速率,在丢包率较高的网络里表现要好得多。厦门BGP线路跨网访问时丢包难免,用BBR能让你的服务器在这种环境下依然保持稳定的传输速度。
需要确认一下你的内核版本,BBR需要4.9及以上版本才支持。现在主流的CentOS 7以上、Ubuntu 18.04以上都没问题。
第五部分:减少TIME_WAIT带来的端口耗尽
net.ipv4.tcp_tw_reuse = 1
这个参数允许将TIME_WAIT状态的socket用于新的连接。高并发服务器,尤其是作为客户端发起大量请求的服务器,必须开这个,不然端口号很快就不够用了。
net.ipv4.tcp_fin_timeout = 30
控制主动关闭连接后,FIN-WAIT-2状态的超时时间。默认是60秒,改成30秒,加快无意义连接的回收速度。
四、这些参数不是银弹,要结合实际业务调
上面给的是一套比较通用的“基础强化配置”,适用于大多数Web服务器、游戏服务器、API后端。但你的业务如果有特殊需求,需要在这个基础上微调。
举个例子。如果你的服务器主要是处理长连接,比如WebSocket或者消息推送,那么TIME_WAIT相关的参数就没那么重要,反而需要关注tcp_keepalive相关的参数,防止僵尸连接占着茅坑不拉屎。
再比如,如果你跑的是数据库服务器,并且主要在内网通信,内网环境丢包率极低,那拥塞控制算法反而不一定要用BBR,CUBIC在内网的性能可能更好。
所以我的建议是:先把这个通用配置套上去跑几天,观察服务器的TCP重传率、连接队列溢出情况,再根据监控数据做针对性的微调。
五、别忘了把硬防和软调结合起来
文章最后想强调一点。
厦门高防服务器的优势在于机房前端的硬件防火墙和充足的BGP带宽资源。这些TCP/IP参数的调优,不是要替代高防,而是要让你的服务器在防御体系的第二道关卡上也足够硬实。
硬件防火墙负责清洗大流量,把攻击流量挡在门外。优化后的内核协议栈,负责处理那些漏网的小流量攻击和恶劣网络环境下的生存问题。一个管“外”,一个管“内”,谁也离不开谁。
我见过不少厦门机房的用户,花了大价钱买高防,服务器本身却连最基本的syncookies都没开,半连接队列小得可怜,结果一个小型SYN Flood就能把他的业务打瘫。这种钱花得冤不冤?太冤了。
最后
运维这件事,有时候就是拼细节。高防机房给你铺好了路,但车能不能跑得快、跑得稳,还得看你怎么调校发动机。
上面这一套TCP/IP参数配置,我把它叫做服务器的“抗揍体质训练”。花十分钟把配置文件改好,执行一条sysctl -p,重启一下网络服务,你的厦门高防服务器的内核就从“出厂设置”变成了“战斗模式”。
别再让你的服务器裸奔在默认参数下了。赶紧登录上去看看,该开的开,该调的调。等到下一次有人敲门试探的时候,你会在监控面板上看到——这台机器的“骨头”,比想象中硬得多。


