最近管理的Linux服务器遭遇了SYN Flood攻击,因此研究一下防范该攻击的方法。
SYN Flood攻击的表现
使用ssh登录Linux服务器,在终端中输入netstat -antp能查看到有大量的链接时SYN_RECV状态,说明Linux服务器遭遇了SYN Flood攻击。
netstat常用参数
netstat常用参数如下:
- -a (all)显示所有选项,默认不显示LISTEN相关
- -t (tcp)仅显示tcp相关选项
- -u (udp)仅显示udp相关选项
- -n 拒绝显示别名,能显示数字的全部转化成数字。
- -l 仅列出有在 Listen (监听) 的服務状态
- -p 显示建立相关链接的程序名
- -r 显示路由信息,路由表
- -e 显示扩展信息,例如uid等
- -s 按各个协议进行统计
- -c 每隔一个固定时间,执行该netstat命令。
TCP连接状态
- ESTABLISHED
指TCP连接已建立,双方可以进行方向数据传递
- CLOSE_WAIT
这种状态的含义其实是表示在等待关闭。当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。
- LISTENING
指TCP正在监听端口,可以接受链接
- TIME_WAIT
指连接已准备关闭。表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。
- FIN_WAIT_1
FIN_WAIT_1和 FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报 文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN 报文,此时该SOCKET即进入到FIN_WAIT_1 状态。而当对方回应ACK 报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况 下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2 状态还有时常常可以用 netstat看到。
- FIN_WAIT_2
FIN_WAIT_2 状态下的SOCKET,表示半连接,也即有一方要求close 连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。
- LAST_ACK
是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了
- SYNC_RECEIVED
表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。
- SYNC_SEND
已经主动发出连接建立请求。与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。
防范措施
首先确保ssh登录密码没有泄露,再修改系统相关配置。
剔出其他登录用户
当ssh登录密码泄露,会有其他用户登录,所以需要剔出其他登录用户,再修改密码和系统相关配置。剔出其他登录用户的方法如下:
- 查看系统在线用户
1 | [root@apache ~]# w |
- 查看当前自己占用终端,防止把自己干掉了
1 | [root@apache ~]# who am i |
- 用pkill 命令剔除对方
1 | # 信号代码 -9 ,表示强制终止 |
- 用w命令在看看干掉没。
1 | [root@apache ~]# w |
抵御SYN攻击的方法
SYN攻击是利用TCP/IP协议3次握手的原理,发送大量的建立连接的网络包,但不实际建立连接,最终导致被攻击服务器的网络队列被占满,无法被正常用户访问。
修改SYN相关系统配置
Linux内核提供了若干SYN相关的配置,用命令: sysctl -a | grep syn 看到:
1 | net.ipv4.tcp_max_syn_backlog = 1024 |
tcp_max_syn_backlog是SYN队列的长度,tcp_syncookies是一个开关,是否打开SYN Cookie 功能,该功能可以防止部分SYN攻击tcp_synack_retries和tcp_syn_retries定义SYN 的重试次数。
加大SYN队列长度可以容纳更多等待连接的网络连接数,打开SYN Cookie功能可以阻止部分 SYN攻击,降低重试次数也有一定效果。
调整上述设置的方法是:
1 | # 增加SYN队列长度到2048: |
为了系统重启动时保持上述配置,可将上述命令加入到/etc/rc.d/rc.local文件中。
iptables阻止syn flood攻击
防止同步包洪水(Sync Flood):
1 | # –limit 1/s 限制syn并发数每秒1次,可以根据自己的需要修改 |
防止各种端口扫描:
1 | iptables -A FORWARD -p tcp –tcp-flags SYN,ACK,FIN,RST RST -m limit –limit 1/s -j ACCEPT |
Ping洪水攻击(Ping of Death):
1 | iptables -A FORWARD -p icmp –icmp-type echo-request -m limit –limit 1/s -j ACCEPT |
屏蔽 SYN_RECV 的连接:
1 | iptables -A INPUT -p tcp -m tcp –tcp-flags SYN,RST,ACK SYN -m limit –limit 1/sec -j ACCEPT |
禁止某IP访问:
1 | iptables -I INPUT -s xxx.xxx.xxx.xx -j DROP |
参考链接
- LINUX 服务器遭到SYN FLOOD攻击,by 晓风残梦.
- Linux netstat命令详解,by ggjucheng.
- netstat 的10个基本用法,by LCTT bazz2.
- netstat用法及TCP state解析,by vigarbuaa.
- Linux踢出其他正在SSH登陆用户,by 艾欧里亚.
- [Linux] killall 、kill 、pkill 命令详解,by 骑着蜗牛游世界.
- Linux中kill,pkill,killall和xkill命令汇总讲解,by simonGeek.
- Linux防止syn flood攻击,屏蔽 SYN_RECV 的连接,by Sphinx 中文站.
- iptables,by wangchujiang.
- TCP状态机,by 大蟒传奇.