前言

“明明设置了规则,却挡不住爬虫?”——在Ubuntu 20.04的系统中,设置ufw防火墙封禁爬取网站的IP,明明ufw status显示规则生效,可目标IP还是能疯狂连接,就像“装了门锁却没锁上”,让人又急又懵。今天结合实际踩坑经验,给大家分享一下问题原因和解决方案。

一、ufw规则“生效”却不生效,你是不是也这样?

对照情况看看,快速确认是否属于同一类情况:

  • 规则添加成功:执行ufw deny from A.B.C.D to any(A.B.C.D是要封禁的IP),终端提示“Rules updated”,看似添加成功;
  • 状态显示正常:输入ufw status查看,能在规则列表里看到“DENY A.B.C.D”,标注规则已生效;
  • IP仍能访问:通过服务器监控(如netstat、fail2ban日志)发现,被封禁的IP还在频繁连接网站,甚至爬取数据,封禁完全没起作用;
  • 重启防火墙没用:执行ufw reload重新加载规则,问题依旧,目标IP还是能绕过封禁进入。

如果符合这些情况,问题原因应该就是规则顺序错了——这是ufw(基于iptables)的常见“特性”,也是很容易踩的坑。

二、核心原因

ufw的规则匹配逻辑,就像“排队过安检”:安检人员会按排队顺序检查每个人的证件,只要符合某条“放行规则”,就直接放行,后面的“禁止规则”哪怕针对这个人,也不会再看。

1. 举个例子:为什么封禁IP会失效?

比如你之前为了方便远程连接服务器,添加过“允许22端口(SSH)访问”的规则:

Bash
ufw allow 22

后来发现IP A.B.C.D在爬网站,又添加“禁止该IP访问”的规则:

Bash
ufw deny from A.B.C.D to any

此时ufw的规则列表里,“允许22端口”的规则排在“禁止A.B.C.D”前面。当A.B.C.D连接服务器时,ufw先匹配到“允许22端口访问”,直接放行,根本不会去看后面的“禁止规则”——这就是为什么规则显示生效,却挡不住IP的原因。

2. 关键原理:规则顺序决定优先级

ufw(本质是iptables的前端工具)遵循“先匹配,先执行”的原则:

  • 规则列表里越靠前的规则,优先级越高;
  • 只要某个连接符合一条规则,ufw就会执行该规则(放行或禁止),不再检查后续规则;
  • 如果你先添加“允许”类规则,再添加“禁止”类规则,针对同一IP或端口时,“允许”会优先生效,“禁止”就成了“无效规则”。

三、解决方法

要让封禁IP的规则生效,核心是把“禁止规则”放到所有“允许规则”前面。ufw的before.rules文件专门用于存放“优先执行的规则”,我们只要在这里添加禁止IP的规则,就能确保它先被匹配。

第一步:编辑ufw的before.rules配置文件

用文本编辑器(如vim)打开/etc/ufw/before.rules文件,这是ufw优先加载的规则文件:

Bash
vim /etc/ufw/before.rules

如果不熟悉vim操作,也可以用nano(更简单的编辑器):

Bash
nano /etc/ufw/before.rules

第二步:在指定位置添加禁止IP的规则

在打开的文件里,找到# End required lines这一行——这是ufw默认规则的结束标记,我们要在它后面添加自定义的禁止规则,确保优先级高于后续的允许规则。

# End required lines下方,添加以下内容(把A.B.C.D换成你要封禁的IP):

Bash
# Block spammers or unwanted IP(注释:封禁爬虫或恶意IP)
-A ufw-before-input -s A.B.C.D -j DROP
  • 代码解释:-A ufw-before-input表示“把这条规则添加到ufw-before-input链(优先执行链)”;-s A.B.C.D指定“来源IP是A.B.C.D”;-j DROP表示“直接丢弃该IP的所有连接请求”,比deny更彻底(deny会返回“拒绝”,DROP直接无响应,更难被察觉)。

如果要封禁多个IP,可重复添加上述规则,每个IP占一行,比如:

Bash
# Block multiple unwanted IPs
-A ufw-before-input -s A.B.C.D -j DROP
-A ufw-before-input -s E.F.G.H -j DROP

第三步:保存文件并重新加载ufw规则

  • 若用vim:按Esc键,输入:wq(保存并退出),按回车;
  • 若用nano:按Ctrl+O(保存),按回车确认文件名,再按Ctrl+X(退出)。

最后执行ufw reload重新加载规则,让配置生效:

Bash
ufw reload

此时再通过监控查看,被封禁的IP就无法再连接服务器了——规则终于真正生效!

四、延伸技巧:避免ufw规则踩坑

解决了当下问题,再延伸几个实用技巧,帮你更好地管理ufw规则,减少后续麻烦:

1. 查看规则时,关注“顺序”而非“存在”

以后添加规则后,不要只看ufw status显示“生效”,还要用ufw status numbered查看规则的编号和顺序:

Bash
ufw status numbered

输出会像这样(带编号):

Bash
Status: active

     To                         Action      From
     --                         ------      ----
[ 1] 22/tcp                     ALLOW IN    Anywhere
[ 2] Anywhere                   DENY IN     A.B.C.D

如果“禁止规则”的编号比“允许规则”大(排在后面),就要按前面的方法,把它移到before.rules里。

2. 批量封禁IP:用文件导入,更高效

如果要封禁很多IP(比如爬虫IP列表),一个个手动添加太麻烦,可把IP存到文件里,再通过脚本批量添加到before.rules

  1. 创建IP列表文件block_ips.txt,每行一个IP:
Bash
   echo "A.B.C.D" > block_ips.txt
   echo "E.F.G.H" >> block_ips.txt
  1. 用命令批量添加到before.rules(在# End required lines后):
Bash
   sudo sed -i '/# End required lines/a # Block IPs from file\n' /etc/ufw/before.rules
   while read ip; do
     sudo sed -i "/# Block IPs from file/a -A ufw-before-input -s $ip -j DROP" /etc/ufw/before.rules
   done < block_ips.txt
  1. 重新加载规则:ufw reload

3. 临时测试规则:先“拒绝”再“永久添加”

添加禁止规则前,可先临时测试该IP是否真的需要封禁(避免误封正常IP):

Bash
# 临时禁止IP访问(重启ufw后失效)
ufw insert 1 deny from A.B.C.D to any

insert 1表示“把规则插入到第1位”,优先生效。观察1-2小时,确认没有正常访问后,再按前面的方法永久添加到before.rules里。

五、总结

ufw添加规则不生效,90%以上是因为规则顺序错了。记住这个核心逻辑:“允许规则”不能排在“禁止规则”前面,要让禁止IP/端口的规则优先执行,就必须把它们放到/etc/ufw/before.rules文件里。

按照编辑before.rules→添加DROP规则→重载ufw的顺序操作,就能解决IP封禁失效的问题,挡住烦人的爬虫。后续管理规则时,多关注规则顺序,用ufw status numbered检查,就能少走很多弯路,让防火墙真正发挥作用。

博客图片78

By 天海牧歌

东庵每见西庵雪,下涧长流上涧泉。 半夜白云消散后,一轮明月到窗前。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注