承接上篇内容,文章开篇之前我们首先新建5个链,方便我们后面有效组织规则和查看防火墙日志的需要
firewall-cmd --permanent --direct --add-chain \
ipv4 mangle ANTI_TCP_INVALID
firewall-cmd --permanent --direct --add-chain \
ipv4 mangle ANTI_TCP_UNORMAL_MSS
firewall-cmd --permanent --direct --add-chain \
ipv4 mangle ANTI_FORGE_TCP_FLAG
firewall-cmd --permanent --direct --add-chain \
ipv4 mangle ANTI_IP_SPOOF
firewall-cmd --permanent --direct --add-chain \
ipv4 filter ANTI_TCP_FLOOD
DDoS的类型多种多样,几乎不可能对所有DDoS维护基于签名的规则,但是幸运的是有一种称为连接跟踪的东西(nf_conntrack内核模块),它可以帮助我们缓解几乎所有基于TCP的DDoS攻击且不会使用看似合法的SYN数据包,包括所有类型的ACK和SYN-ACK DDoS攻击以及使用伪造的TCP标志的DDoS攻击。
我们仅从五个简单的iptables规则开始,这些规则将已经丢弃了许多基于TCP的DDoS攻击。
提醒读者
以下所有规则都省略了firewall-cmd --permanent --direct --add-rule这段命令前缀,有读者自行实践时,请自行加上。
阻挡无效的数据包
ipv4 mangle ANTI_TCP_INVALID 0 -m conntrack --ctstate INVALID -j DROP
此规则将阻止所有不是SYN数据包且不属于已建立的TCP连接的数据包。
阻止不是SYN的新数据包
ipv4 mangle ANTI_TCP_INVALID 1 -p tcp ! \
--syn -m conntrack --ctstate NEW -j DROP
这会阻止所有新数据包(不属于已建立的连接)并且不使用SYN标志。此规则类似于“阻止无效数据包”,但是我们发现它捕获了一些其他数据包却没有的数据包。
阻止不常见的MSS值
ipv4 mangle ANTI_TCP_UNORMAL_MSS 0 \
-p tcp -m conntrack --ctstate NEW \
-m tcpmss ! --mss 536:65535 -j DROP
这会阻止所有新的数据包(不属于已建立的连接),并且不使用SYN标志。该规则类似于“阻止无效数据包”规则,但是我们发现它捕获了一些其他规则没有捕获的数据包。
拦截带有伪造TCP标志的数据包
ipv4 mangle ANTI_FORGE_TCP_FLAG 0 \
-p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 1 \
-p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 2 \
-p tcp --tcp-flags SYN,RST SYN,RST -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 3 \
-p tcp --tcp-flags FIN,RST FIN,RST -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 4 \
-p tcp --tcp-flags FIN,ACK FIN -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 5 \
-p tcp --tcp-flags ACK,URG URG -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 6 \
-p tcp --tcp-flags ACK,FIN FIN -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 7 \
-p tcp --tcp-flags ACK,PSH PSH -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 8 \
-p tcp --tcp-flags ALL ALL -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 9 \
-p tcp --tcp-flags ALL NONE -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 10 \
-p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 11 \
-p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
ipv4 mangle ANTI_FORGE_TCP_FLAG 12 \
-p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
上述规则集阻止使用假TCP标志的数据包,即。合法数据包不会使用的TCP标志。
拦截来自私有子网的数据包(欺骗)
ipv4 mangle ANTI_IP_SPOOF 0 -s 224.0.0/3 -j DROP
ipv4 mangle ANTI_IP_SPOOF 1 -s 192.0.2.0/24 -j DROP
ipv4 mangle ANTI_IP_SPOOF 2 -s 169.254.0.0/16 -j DROP
ipv4 mangle ANTI_IP_SPOOF 3 -s 172.16.0.0/12 -j DROP
ipv4 mangle ANTI_IP_SPOOF 4 -i enp3s0 -s 192.168.0.0/16 -j DROP
ipv4 mangle ANTI_IP_SPOOF 5 -s 10.0.0.0/8 -j DROP
ipv4 mangle ANTI_IP_SPOOF 6 -s 0.0.0.0/8 -j DROP
ipv4 mangle ANTI_IP_SPOOF 7 -s 240.0.0.0/5 -j DROP
ipv4 mangle ANTI_IP_SPOOF 8 -s 127.0.0.0/8 ! -i lo -j DROP
这些规则阻止源自专用(本地)子网的欺骗数据包。在您的公网接口上,您通常不想接收来自内源IP的数据包。这些规则假定您的环回接口使用127.0.0.0/8 IP空间。仅这五组规则就已经以非常高的数据包速率阻止了许多基于TCP的DDoS攻击。使用上面提到的内核设置和规则,您将能够以线速过滤ACK和SYN-ACK攻击。
使用上面这组规则有些问题你需要注意的,如果你的内网的私有IP段必定有一个在这些拦截规则中的,例如你的内网是192.168.32.0/24的私有网段,最好在对应的拦截规则显式加上入站的公网接口,例如上买呢的优先级为20的规则。这个细节漏掉的话,你内网的用户必定会抱怨无法上网。
防范ICMP泛洪
这个嘛,我们没必要使用direct规则,使用firewalld的原生命令,例如我们公网ip位于external区域
firewall-cmd --zone=external --set-target=DROP --permanent
firewall-cmd --reload
这条指令就可阻挡所有来自外网的ICMP的数据包,当然包括你认为来自可信任源主机的所有ICMP请求的包。由于通常不需要此漏洞,它仅代表攻击者可以利用的另一个漏洞,因此我们阻止了所有ICMP数据包,以缓解Ping of Death(ping Flood),ICMP Flood和ICMPFragmentation Flood的危害。
以下规则有助于抵御连接攻击。 它拒绝来自拥有80多个已建立连接的主机的连接。 如果遇到任何问题,则应提高该限制,因为这可能会给建立大量TCP连接的合法客户端造成麻烦。
ipv4 filter INPUT 0 -p tcp -m connlimit \
--connlimit-above 80 -j REJECT --reject-with tcp-reset
以下规则用于限制客户端每秒可以建立的新TCP连接。这对防止连接攻击很有用,但对SYN洪流就没什么用了,因为通常会使用无穷无尽的不同欺骗源IP。
ipv4 filter INPUT 1 -p tcp -m conntrack \
--ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT
防范TCP/UDP碎片泛洪
以下规则拦截碎片化的UDP数据包。通常情况下,您不需要这些,阻塞片段将缓解UDP碎片泛滥。但在大多数情况下,UDP碎片泛洪使用的带宽很高,可能会耗尽网卡的容量,这使得此规则成为可选规则,而且可能不是最有用的规则。
ipv4 mangle PREROUTING 25 -f -j DROP
以下规则限制了入站的TCP RST数据包以缓解TCP RST泛洪。 该规则的有效性值得怀疑。
ipv4 filter ANTI_TCP_FLOOD 0 -p tcp \
-m connlimit --connlimit-above 80 \
-j REJECT --reject-with tcp-reset
ipv4 filter ANTI_TCP_FLOOD 1 -p tcp \
-m conntrack --ctstate NEW -m limit --limit 60/s \
--limit-burst 20 -j ACCEPT
ipv4 filter ANTI_TCP_FLOOD 2 -p tcp \
--tcp-flags RST RST -m limit --limit 2/s \
--limit-burst 2 -j ACCEPT
ipv4 filter ANTI_TCP_FLOOD 3 -p tcp \
--tcp-flags RST RST -j DROP
部署预防的5个DDoS链
我们前面定义5种常见DDoS类型的预防规则,其中4个是部署到mangle表的PREROUTING链,和ANTI_TCP_FLOOD链作为target应用到filter表的INPUT链
ipv4 mangle PREROUTING 0 -j ANTI_TCP_INVALID
ipv4 mangle PREROUTING 1 -j ANTI_TCP_UNORMAL_MSS
ipv4 mangle PREROUTING 2 -j ANTI_FORGE_TCP_FLAG
ipv4 mangle PREROUTING 3 -j ANTI_IP_SPOOF
ipv4 filter INPUT 0 -j ANTI_TCP_FLOOD
使用iptables -t mangle -L -nv 命令检测一下效果,这样的数据是比较随机性,理想情况下当然希望它们都是0,就看你人品问题比较突出,这项数值可能会异常高。效果是立竿见影的,图中左侧两列就是打印当前拦截的恶意数据包的数量。
可见当你的服务器上架时,DDoS攻击的防范是灰常必要的。但我们工作还没有完
使用SYNPROXY缓解SYN泛洪
SYN代理是Linux内核版本3.12和iptables 1.4.21中添加的iptables的新target。CentOS7支持该功能,并且在其3.10默认内核中可用。SYN代理的目的是检查发送SYN数据包的主机是实际建立了完整的TCP连接,还是在发送SYN数据包后什么也不做。如果它什么都不做,它会丢弃数据包,而对性能的影响最小。虽然我们上面提供的iptables规则已经阻止了大多数基于TCP的攻击,但是如果足够复杂,仍然可以通过它们的攻击类型是SYN泛红。
重要的是要注意,如果我们找到要阻塞的特定模式或签名,例如数据包长度(-m长度)、TOS(-m tos)、TTL(-m ttl)或字符串和十六进制值(对于更高级的用户,-m字符串和-m u32),规则的性能总是会更好。
但在极少数情况下,这是不可能的,或者至少不容易实现。因此,在这些情况下,您可以使用SYNPROXY。以下是iptables SYNPROXY规则,可帮助缓解绕过其他规则的SYN泛滥:
ipv4 raw PREROUTING 0 -p tcp -m tcp --syn -j CT --notrack
ipv4 filter INPUT 4 -p tcp -m tcp -m conntrack \
--ctstate INVALID,UNTRACKED \
-j SYNPROXY --sack-perm \
--timestamp --wscale 7 -mss 1460
另外,这些规则可用于提高Linux服务器的整体安全性:
防止SSH入侵爆破
首先仍然新建一个链叫ANTI_SSH_INTRUSION
firewall-cmd --permanent --direct \
--add-chain ipv4 filter ANTI_SSH_INTRUSION
在ANTI_SSH_INTRUSION定义以下两条规则
ipv4 filter ANTI_SSH_INTRUSION 0
-p tcp --dport <填写ssh随机端口> \
-m conntrack --ctstate NEW
-m recent --set
ipv4 filter ANTI_SSH_INTRUSION 1
-p tcp --dport <填写ssh随机端口>
-m conntrack \
--ctstate NEW -m recent \
--update --seconds 60 --hitcount 10 -j DROP
然后,我们将ANTI_SSH_INTRUSION应用到filter表的INPUT链当中
ipv4 filter INPUT 0 -j ANTI_SSH_INTRUSION
防止被端口扫描
首先我们使用direct命令行选项创建一个新的链叫PORT_SCANNING
firewall-cmd --direct --permanent --direct --add-chain ipv4 filter PORT_SCANNING
然后我们向PORT_SCANNING的链中两条添加规则
ipv4 filter PORT_SCANNING 0 -p tcp \
--tcp-flags SYN,ACK,FIN,RST RST \
-m limit --limit 1/s --limit-burst 2 \
-j RETURN
ipv4 filter PORT_SCANNING 1 -j DROP
之后,我们将这个新的链添加iptables内置的INPUT链即可。
ipv4 filter INPUT 1 -j PORT_SCANNING
OK,我们看看最后新加的两条规则
ss8.png
这样你的Linux/Unix服务器很大程度上得到了安全
总结
本篇我们体会到firewalld设定iptables规则的微妙用法,从第6篇我已经开篇讲述了direct规则的用法,是为了在第7篇和第8篇《Linux网络安全 预防DDoS攻击》展开具体的防火墙安全实战配置,做配置的。这里我们体会到iptables是一个非常强大的防火墙工具。只要你的规则配置得当,你的Linux服务强就套上了一个强大安全套。
网友评论