iptables 是一款控制系统进出流量的强大配置工具。
IPTABLES 是与最新的 3.5 版本 Linux 内核集成的 IP 信息包过滤系统。如果 Linux 系统连接到因特网或 LAN、服务器或连接 LAN 和因特网的代理服务器, 则该系统有利于在 Linux 系统上更好地控制 IP 信息包过滤和防火墙配置。
更多iptables相关文章请参见《系统管理员必备的16个经典iptables使用技巧》
展开索引
常用iptables操作
查找所有规则
iptables -L -n --line-numbers
删除一条规则
iptables -D INPUT 8 #注意,这个8是行号,是之前iptables -L INPUT --line-numbers 所打印出来的行号#
清空所有规则
iptables -F
保存/另存iptables规则
iptables-save #若要导出/另存为iptables规则,请参照: iptables-save > /root/iptables_copy_andyx.net.txt
还原iptables规则
# 先清空iptables规则表 iptables -F #然后再从另存的iptables规则中还原 iptables-restore 《 /root/iptables_copy_andyx.net.txt
关于iptables中tcp-flags的说明
F : FIN 结束标志; 结束会话 带有该标志置位的数据包用来结束一个TCP回话,但对应端口仍处于开放状态,准备接收后续数据。 S : SYN 同步标志; 表示开始会话请求 同步序列编号(Synchronize Sequence Numbers)栏有效。该标 志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号, 该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。 通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。 R : RST 复位标志;中断一个连接 复位标志有效。用于复位相应的TCP连接。 P : PSH 推标志; 数据包立即发送 该标志置位时,接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理 telnet 或 rlogin 等交互模式的连接时,该标志总是置位的 A : ACK 应答标志 确认编号(Acknowledgement Number)栏有效。大多数情况下该标志位是置位的。TCP报头 内的确认编号栏内包含的确认编号(w+1,Figure:1)为下一个预期的 序列编号,同时提示远端系统已经成功接收所有数据。 E : ECE 显式拥塞提醒回应 W : CWR 拥塞窗口减少
TCP三次握手的原理
一个虚拟连接的建立是通过三次握手来实现的
1. (B) → [SYN] → (A)
假如服务器A和客户机B通讯. 当A要和B通信时,B首先向A发一个SYN (Synchronize) 标记的包,告诉A请求建立连接.
注意: 一个SYN包就是仅SYN标记设为1的TCP包(参见TCP包头Resources)。认识到这点很重要,只有当A受到B发来的SYN包,才可建立连接,除此之外别无他法。
因此,如果你的防火墙丢弃所有的发往外网接口的SYN包,那么你将不能让外部任何主机主动建立连接。2. (B) ← [SYN/ACK] ←(A)
接着,A收到后会发一个对SYN包的确认包(SYN/ACK)回去,表示对第一个SYN包的确认,并继续握手操作.
注意: SYN/ACK包是仅SYN和ACK标记为1的包.3. (B) → [ACK] → (A)
B收到SYN/ACK 包,B发一个确认包(ACK),通知A连接已建立。至此,三次握手完成,一个TCP连接完成
注意: ACK包就是仅ACK 标记设为1的TCP包. 需要注意的是当三此握手完成、连接建立以后,TCP连接的每个包都会设置ACK位
这就是为何连接跟踪很重要的原因了。如果没有连接跟踪,防火墙将无法判断收到的ACK包是否属于一个已经建立的连接。一般的包过滤(Ipchains)收到ACK包时,会让它默认通过(这绝对不是个好主意)。而当状态型防火墙收到此种包时,它会先在连接表中查找是否属于哪个已建连接,否则丢弃该包。
TCP四次挥手的原理
四次挥手用来关闭已建立的TCP连接
1. (B) → ACK/FIN → (A)
2. (B) ← ACK ← (A)
3. (B) ← ACK/FIN ← (A)
4. (B) → ACK → (A)
注意: 由于TCP连接是双向连接,因此关闭连接需要在两个方向上做。ACK/FIN 包(ACK 和FIN 标记设为1)通常被认为是FIN(终结)包。然而,由于连接还没有关闭,FIN包总是打上ACK标记。没有ACK标记而仅有FIN标记的包不是合法的包,并且通常被认为是恶意的。
三次握手和四次挥手示意图
TCP连接复位的原理
四次挥手不是关闭TCP连接的唯一方法. 有时,如果主机需要尽快关闭连接(或连接超时,端口或主机不可达),RST (Reset)包将被发送。
注意在,由于RST包不是TCP连接中的必须部分, 可以只发送RST包(即不带ACK标记)。
但在正常的TCP连接中RST包可以带ACK确认标记
注意:RST包是可以不要收到方确认的
无效的TCP标记
到目前为止,你已经知晓了 SYN, ACK, FIN, 和RST 标记。另外,还有PSH (Push) 和URG (Urgent)标记。
最常见的非法组合是SYN/FIN 包。注意:由于 SYN包是用来初始化连接的, 它不可能和FIN和RST标记一起出现。所以说这一定是一个恶意攻击。
由于现在大多数防火墙已知 SYN/FIN 包, 别的一些组合,例如SYN/FIN/PSH, SYN/FIN/RST, SYN/FIN/RST/PSH。很明显,当网络中出现这种包时,你的网络肯定受到攻击了。
别的已知的非法包有FIN (无ACK标记)和”NULL”包,如同早先讨论的,由于ACK/FIN包的出现是为了关闭一个TCP连接,那么正常的FIN包总是带有ACK标记。
“NULL”包就是没有任何TCP标记的包(URG,ACK,PSH,RST,SYN,FIN都为0)。
到目前为止,正常的网络活动下,TCP协议栈不可能产生带有上面提到的任何一种标记组合的TCP包。当你发现这些不正常的包时,肯定有人对你的网络不怀好意。
tcp-flags基本使用方法
基本使用如下:
iptables -p tcp --tcp-flags 参数列表1 参数列表2 参数列表N
匹配指定的TCP标记,有两个参数列表,列表内部用逗号为分隔符,两个列表之间用空格分开,
LIST1用作参数检查,LIST2用作参数匹配。可用标志有:
SYN( 同步; 表示开始会话请求 ), ACK(应答);
FIN(结束; 结束会话),RST(复位;中断一个连接);
PSH(推送; 数据包立即发送),URG(紧急 );
ALL(指选定所有的标记),NONE(指未选定任何标记);
举例如下,当23端口符合规则时则抛弃:
[root@andyx.net ~]# iptables -A INPUT -p tcp --dport 23 --tcp-flags SYN,ACK,FIN,RST,URG,PSH SYN -j DROP [root@andyx.net ~]# iptables -A INPUT -p tcp --dport 23 --tcp-flags ALL SYN -j DROP [root@andyx.net ~]# iptables -A INPUT -p tcp --dport 23 --syn -j DROP
上面3条规则其实是一样的,ALL表示“SYN,ACK,FIN,RST,URG,PSH”,表示匹配三次握手中的第一次,此外tcp扩展模块还提供了一个选项 – -syn 也表示第一次握手。
iptables防御实战
使用iptables对防火墙端口进行操作
开启指定端口,例如开启80或22端口:
iptables -I INPUT -p tcp --dport 80 -j ACCEPT iptables -I INPUT -p tcp --dport 22 -j ACCEPT
关闭指定端口,例如关闭8080或9000:
iptables -I INPUT -p tcp --dport 8080 -j DROP iptables -I INPUT -p tcp --dport 9000 -j DROP
使用iptables屏蔽指定IP/IP段
屏蔽单个IP:
iptables -I INPUT -s 201.192.138.51 -j DROP
屏蔽小范围IP段:
# 这是个来自山东的恶意SQL注入扫描器,屏蔽范围113.128.12.1 至 113.128.12.254 iptables -I INPUT -s 113.128.12.0/24 -j DROP # 这是个来自北京的恶意SQL注入扫描器,屏蔽范围219.143.140.1 至 219.143.140.254 iptables -I INPUT -s 219.143.140.0/24 -j DROP
屏蔽中等范围IP段:
# 这是一个来自于景安机房的恶意扫描器,屏蔽范围122.114.0.1 至 122.114.254.254 iptables -I INPUT -s 122.114.0.0/16 -j DROP # 这是一个假冒百度搜索引擎的扫描器,屏蔽范围104.251.0.1 至 104.251.254.254 iptables -I INPUT -s 104.251.0.0/16 -j DROP
屏蔽广域范围IP段(慎用!!!):
# 可能的DDOS僵尸网络,屏蔽范围106.0.0.1 至 106.254.254.254 iptables -I INPUT -s 106.0.0.0/8 -j DROP
使用iptables防御SYN洪水攻击
SYN Flood 主要是利用了TCP协议的三次握手的缺陷,在这个攻击中,Flood带有一系列的syn数据包,每个数据包都会导致服务端发送SYN-ACK响应,然后服务器等待SYN+ACK之后的第三次握手ACK,由于客户端是软件生成的虚拟IP,永远不会再发送ACK响应服务端,服务端会利用从传机制直到超时后删除,整个系统资源也会被队列积压消耗,导致服务器无法对正常的请求进行服务。
判断SYN攻击非常的简单,当你在服务器上使用netstat命令看到大量的SYN_RECV半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击。
iptables对于SYN的一般防御方法:
#缩短SYN - Timeout时间: iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT iptables -A INPUT -m limit --limit 1/sec --limit-burst 5 -j ACCEPT #设置同IP每秒 最多5个syn封包 进入,且burst为15,超出拒绝 : iptables -N syn-flood #新建一条额外iptables链 iptables -A INPUT -p tcp --syn -j syn-flood iptables -A syn-flood -p tcp -m limit --limit 5/s --limit-burst 15 -j RETURN iptables -A syn-flood -j REJECT
注意:这个方式需要调节一个合理的速度值,不然会影响正常用户的请求!
使用iptables防御AB压力测试/CC攻击
防御此类供给的最好办法就限制特定IP在指定时间内的访问次数,通常新版本Linux内核模块都支持kernel-smp-modules-connlimit,所以我们可以直接使用connlimit进行限制:
实例1:抵御拒绝服务攻击 ,允许外网最多24个初始连接,然后服务器每秒新增12个,访问太多超过的丢弃
第二条是允许服务器内部每秒1个初始连接进行转发
iptables -A INPUT -p tcp --syn -m limit --limit 12/s --limit-burst 24 -j ACCEPT iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
实例2:允许单IP访问服务器的80端口的最大连接数为 20
iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 20 -j REJECT
实例3:使用recent模块对访问本机的22端口进行限制,每个ip每小时只能连接5次,超过的拒接,1小时候重新计算次数
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --rcheck --seconds 3600 --hitcount 5 -j DROP iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --name SSHPOOL --set -j ACCEPT # 提示:上面recent规则只适用于默认规则为DROP中,如果要适用默认ACCEPT的规则,需要--set放前面 并且无-j ACCEPT
实例4:防止过多拒绝服务连接,设置允许外网网卡(eth0)每个IP最多15个初始连接,超过则丢弃
iptables -A INPUT -i eth0 -p tcp --syn -m connlimit --connlimit-above 15 -j DROP iptables -A INPUT -p tcp -m state --state ESTABLISHED,RELATED -j ACCEPT
提示:攻击这东西只能防御不能完全根除!只能缓解,降低到最低的风险。
使用iptables屏蔽部分扫描器
屏蔽NMAP SCAN
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
屏蔽XMAS TREE
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
屏蔽Null Scan
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
屏蔽INVALID COMBINATIONS
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP
这里只列出一些常见的组合,此外还有一些非法的包组合,具体参考:http://www.stearns.org/modwall/archives/tcpchk.v0.1.1
屏蔽全部畸形包列表:
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -A INPUT -p tcp --tcp-flags FIN,ACK FIN -j DROP iptables -A INPUT -p tcp --tcp-flags RST,FIN RST,FIN -j DROP iptables -A INPUT -p tcp --tcp-flags SYN,URG SYN,URG -j DROP iptables -A INPUT -p tcp --tcp-flags ALL SYN,PSH -j DROP iptables -A INPUT -p tcp --tcp-flags ALL SYN,ACK,PSH -j DROP iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j DROP iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j DROP iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j DROP iptables -A INPUT -p tcp --tcp-flags ALL RST -j RETURN iptables -A INPUT -p tcp --tcp-flags SYN,ACK NONE -j DROP
(END)
文章由AndyX 收集整理,转载请注明来源:https://andyx.net/using_iptables_to_prevent_syn_flood_ab_stress_cc_attack/