Linux防SYN_Flood攻击的方法

最近管理的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
2
3
4
5
[root@apache ~]# w 
14:15:41 up 42 days, 56 min, 2 users, load average: 0.07, 0.02, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 116.204.64.165 14:15 0.00s 0.06s 0.04s w
root pts/1 116.204.64.165 14:15 2.00s 0.02s 0.02s –bash
  • 查看当前自己占用终端,防止把自己干掉了
1
2
[root@apache ~]# who am i 
root pts/0 2013-01-16 14:15 (116.204.64.165)
  • 用pkill 命令剔除对方
1
2
# 信号代码 -9 ,表示强制终止
[root@apache ~]# pkill -9 -t pts/1
  • 用w命令在看看干掉没。
1
2
3
4
[root@apache ~]# w 
14:19:47 up 42 days, 1:00, 1 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 116.204.64.165 14:15 0.00s 0.03s 0.00s w

抵御SYN攻击的方法

SYN攻击是利用TCP/IP协议3次握手的原理,发送大量的建立连接的网络包,但不实际建立连接,最终导致被攻击服务器的网络队列被占满,无法被正常用户访问。

修改SYN相关系统配置

Linux内核提供了若干SYN相关的配置,用命令: sysctl -a | grep syn 看到:

1
2
3
4
net.ipv4.tcp_max_syn_backlog = 1024 
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_synack_retries = 5
net.ipv4.tcp_syn_retries = 5

tcp_max_syn_backlog是SYN队列的长度,tcp_syncookies是一个开关,是否打开SYN Cookie 功能,该功能可以防止部分SYN攻击tcp_synack_retries和tcp_syn_retries定义SYN 的重试次数。  

加大SYN队列长度可以容纳更多等待连接的网络连接数,打开SYN Cookie功能可以阻止部分 SYN攻击,降低重试次数也有一定效果。

调整上述设置的方法是:

1
2
3
4
5
6
7
8
9
# 增加SYN队列长度到2048:
sysctl -w net.ipv4.tcp_max_syn_backlog=2048

# 打开SYN COOKIE功能:
sysctl -w net.ipv4.tcp_syncookies=1

# 降低重试次数:
sysctl -w net.ipv4.tcp_synack_retries=3
sysctl -w net.ipv4.tcp_syn_retries=3

为了系统重启动时保持上述配置,可将上述命令加入到/etc/rc.d/rc.local文件中。

iptables阻止syn flood攻击

防止同步包洪水(Sync Flood):

1
2
# –limit 1/s 限制syn并发数每秒1次,可以根据自己的需要修改
iptables -A FORWARD -p tcp –syn -m limit –limit 1/s -j ACCEPT

防止各种端口扫描:

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

参考链接

  1. LINUX 服务器遭到SYN FLOOD攻击,by 晓风残梦.
  2. Linux netstat命令详解,by ggjucheng.
  3. netstat 的10个基本用法,by LCTT bazz2.
  4. netstat用法及TCP state解析,by vigarbuaa.
  5. Linux踢出其他正在SSH登陆用户,by 艾欧里亚.
  6. [Linux] killall 、kill 、pkill 命令详解,by 骑着蜗牛游世界.
  7. Linux中kill,pkill,killall和xkill命令汇总讲解,by simonGeek.
  8. Linux防止syn flood攻击,屏蔽 SYN_RECV 的连接,by Sphinx 中文站.
  9. iptables,by wangchujiang.
  10. TCP状态机,by 大蟒传奇.