CentOS 7及后续衍生版本中,Firewalld已经取代iptables成为默认的防火墙管理工具。很多人用Firewalld只停留在开放端口、关闭端口的初级阶段,一旦遇到CC攻击、端口扫描或者暴力破解,要么束手无策,要么只能求助于额外的防护软件。其实Firewalld内置的富规则(Rich Rules)功能极其强大,它允许你直接编写接近iptables逻辑的精细过滤策略,在不安装额外组件的情况下就能实现精准的访问控制和攻击拦截。下面直接讲具体的配置方法和实战策略。

理解富规则与传统规则的本质区别

普通Firewalld规则只能做简单的端口放行或拒绝,比如允许80端口、拒绝22端口。但富规则可以基于源IP、目标IP、协议类型、端口范围、连接状态、日志记录、速率限制等多个维度组合过滤。它的语法结构清晰,支持直接添加iptables风格的匹配条件。一条完整的富规则包含动作(accept、drop、reject)、方向(source、destination)、服务或端口、协议、以及可选的日志和限制参数。理解这一点后,你就能用富规则构建多层防御体系。

防范端口扫描的基础配置

攻击者在对服务器发起攻击前,通常会进行全端口扫描以探测开放服务。我们可以利用富规则对短时间内触发大量连接请求的IP进行封禁。下面的规则实现了对TCP端口扫描行为的检测和拦截:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="1-65535" protocol="tcp" limit value="10/m" accept'

这条规则的含义是,对来自任何IP的TCP全端口连接请求,限制每分钟最多接受10个新连接。超过这个速率的请求会被自动丢弃。注意这里用了accept而不是drop,因为limit只对accept动作生效。如果想对违规IP直接拒绝,可以配合第二条规则:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="1-65535" protocol="tcp" drop'

两条规则叠加后,正常速率的连接被允许,超出的直接被丢弃,这样既不影响正常服务,又能有效阻断扫描器的高速探测。

防御SSH暴力破解的实战策略

SSH暴力破解是最常见的攻击形式之一。攻击者用字典不断尝试root或其他用户的密码。传统做法是修改SSH端口,但端口扫描很容易发现新端口。用富规则可以做到:单个IP在短时间内发起超过一定次数的SSH连接请求时,直接将其加入黑名单。具体配置如下:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="ssh" limit value="3/m" log prefix="SSH_LIMIT: " level="warning" accept'

这条规则限制每个IP每分钟只能发起3次SSH连接,超过的请求会被记录日志并丢弃。日志前缀设为SSH_LIMIT,方便后续通过logwatch或自定义脚本分析。如果你需要更严格的防护,可以把limit值降到2/m甚至1/m。对于已经确认恶意的IP,直接手动添加到永久拒绝列表:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" reject'

这里的reject会返回拒绝响应,让攻击者明确知道被拦截,消耗其时间。如果不想有任何回应,换成drop即可。

CC攻击与HTTP洪水防护的富规则实现

CC攻击的本质是大量肉鸡或代理对网站发起海量HTTP请求,耗尽服务器资源。在Web服务器层面可以做限制,但在防火墙层面拦截效率更高。通过富规则限制80和443端口的并发连接数和连接速率,能在请求到达Nginx或Apache之前就拦截掉大部分恶意流量。以下是针对HTTP服务的限速规则:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="http" limit value="30/m" accept'
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" service name="https" limit value="30/m" accept'

每条规则限制每个IP每分钟最多30个新连接。对于正常用户浏览网页来说,30次完全够用,但对于CC攻击工具来说,这个频率远低于其攻击强度。你还可以根据实际业务调整数值,比如API接口可以放宽到60/m,静态资源站可以收紧到20/m。如果攻击流量特别大,可以启用更激进的限制,甚至对特定路径做过滤:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" port port="80" protocol="tcp" limit value="10/m" drop'

这条规则直接对80端口的TCP连接做硬限制,超过10次/分钟的IP直接被丢弃,不再区分正常请求还是攻击请求。这种策略适合在遭受大规模攻击时紧急启用。

基于地理位置的IP段封锁

如果你的业务只面向国内用户,可以直接在防火墙层面封锁海外IP段,大幅减少无效流量和攻击来源。富规则支持CIDR格式的网段定义,你可以从APNIC或IPIP等机构获取中国IP段列表,然后批量添加拒绝规则。单条规则的写法如下:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" drop'

实际操作中,海外IP段数量庞大,手动一条条添加不现实。建议编写Shell脚本循环读取IP段文件并批量添加。脚本逻辑大致是:从文本文件逐行读取网段,用firewall-cmd命令添加富规则,最后统一重载。这样可以在几分钟内完成数万条规则的部署。注意规则数量过多会影响防火墙性能,建议控制在5000条以内,或者使用ipset配合富规则来优化。

记录和审计攻击流量的日志策略

富规则可以灵活地记录匹配到的数据包日志,这对事后分析和溯源非常重要。通过在规则中添加log参数,可以指定日志前缀和级别。例如,记录所有被拒绝的入站连接:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="0.0.0.0/0" log prefix="DENIED_IN: " level="info" drop'

这条规则会丢弃所有未被前面规则放行的入站流量,并记录日志。日志会写入系统日志文件,通常位于/var/log/messages。你可以用grep过滤出DENIED_IN前缀的条目,分析攻击来源IP、攻击频率和端口分布。如果日志量太大,可以降低日志级别或者只对特定端口记录,避免日志把磁盘写满。

动态黑名单与自动化响应

富规则本身是静态的,但可以结合fail2ban或自定义脚本实现动态黑名单。fail2ban通过监控日志文件,匹配到符合规则的恶意行为后,自动调用firewall-cmd添加富规则封禁IP,并在指定时间后解封。如果你不想安装fail2ban,也可以自己写一个简单的监控脚本,定时分析日志,提取攻击IP并添加到防火墙。核心命令就是动态添加富规则:

firewall-cmd --add-rich-rule='rule family="ipv4" source address="恶意IP" drop'

注意这里不加--permanent参数,这样规则只在运行时生效,重启后消失。你可以配合定时任务,每隔一段时间清理过期的临时规则,或者重启firewalld服务来清空所有临时封禁。

富规则的顺序与优先级管理

Firewalld处理富规则的顺序是自上而下的,先匹配到的规则先生效。因此规则的排列顺序直接影响防护效果。查看当前所有富规则及其顺序:

firewall-cmd --list-rich-rules

输出结果就是规则的匹配顺序。通常应该把最精确、最严格的规则放在前面,把通用的兜底规则放在最后。比如先放行白名单IP,再限制特定服务的速率,最后拒绝所有其他连接。如果需要调整顺序,只能先删除再重新添加,或者直接编辑/etc/firewalld/zones/public.xml文件,手动调整rule节点的位置,然后重载防火墙。

富规则与direct规则的配合使用

当富规则的表达能力无法满足需求时,比如需要匹配TCP标志位、连接状态跟踪等更底层的条件,可以使用Firewalld的direct规则。Direct规则直接透传iptables命令,提供最大的灵活性。例如,禁止SYN Flood攻击的规则可以这样写:

firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0 -p tcp --syn -j DROP

这两条direct规则限制了SYN包的速率,超过的部分直接丢弃。富规则和direct规则可以共存,富规则适合大多数场景,配置简单、可读性强;direct规则适合高级用户处理复杂场景。建议优先用富规则解决问题,实在不行再上direct规则。

生产环境部署前的测试与验证

任何防火墙规则在上生产环境前,都应该在测试环境中充分验证。你可以用nmap扫描、hping3发包、ab压力测试等工具模拟攻击行为,观察规则是否生效、日志是否正确输出、正常业务是否受影响。重点验证以下几点:规则添加后firewalld是否能正常重载;规则顺序是否符合预期;limit限制的数值是否合理;误封白名单IP的情况是否存在。测试通过后,再通过ansible或手动方式部署到生产服务器。

日常维护与规则优化建议

防火墙规则不是一劳永逸的。随着业务变化和攻击手段演进,需要定期审查和优化。建议每月检查一次规则列表,删除不再需要的规则,合并功能重复的规则,调整limit数值以适应业务流量增长。同时关注系统日志,分析被拦截的流量趋势,发现新型攻击特征后及时补充对应规则。对于已经确定长期恶意的IP段,可以固化到永久规则中;对于临时封禁的IP,设置合理的过期时间,避免规则表无限膨胀影响性能。