请问 Linux 防火墙屏蔽 IP 为什么无效?

2019-08-02 01:31:45 +08:00
 Phishion

之前使用 fail2ban 设置了一下 ssh 暴力尝试 root 用户名密码会被拒绝的功能

现在想如法炮制设置 nginx 404 访问次数达到阈值之后,也会被拒绝访问

但是我发现 iptable 能看到被捕获的 ip 也生成了相应规则,但是依然可以正常访问,然而 ssh 登录的规则一直是正常的

另外,我自己直接在防火墙写规则也是无效,还是可以正常访问。

iptables -A INPUT -s 182.254.74.167 -j DROP

有没有大佬能指点一二,我自己琢磨半天了,谢谢

附上 fail2ban 规则

/etc/fail2ban/jail.local

[nginxno404]
enabled = true
port = http,https
filter = nginx-not-found
action = iptables[name=nginxno404, port=http, protocol=tcp]
logpath  = /var/log/nginx/access.log
bantime = 86400
findtime = 300
maxretry = 50

附上 iptable 结果

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    8   320 f2b-nginxno404  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
 3748  305K f2b-SSH    tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
 2585  243K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
 1293 70223 INPUT_direct  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
 1293 70223 INPUT_ZONES_SOURCE  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
 1293 70223 INPUT_ZONES  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
   15   747 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
 1119 61450 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited
 

Chain f2b-SSH (1 references)
 pkts bytes target     prot opt in     out     source               destination         
   20  1720 REJECT     all  --  *      *       218.92.0.181         0.0.0.0/0            reject-with icmp-port-unreachable
   31  2176 REJECT     all  --  *      *       132.232.18.128       0.0.0.0/0            reject-with icmp-port-unreachable
   57  3776 REJECT     all  --  *      *       177.32.64.189        0.0.0.0/0            reject-with icmp-port-unreachable
   2259  210K RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0  


Chain f2b-nginxno404 (1 references)
 pkts bytes target     prot opt in     out     source               destination         
    8   320 REJECT     all  --  *      *       182.254.74.167       0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 REJECT     all  --  *      *       182.254.28.36        0.0.0.0/0            reject-with icmp-port-unreachable
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0           
5477 次点击
所在节点    程序员
32 条回复
Phishion
2019-08-02 14:38:46 +08:00
@daviswei 我在想是不是 Docker 的问题,我的 nginx 是容器,宿主机上的 80 端口实际上是映射到 nginx 容器的 80 端口,是不是因为 Docker 导致所有 80 端口无视 iptable 无条件转发给 nginx
littlewing
2019-08-02 15:00:13 +08:00
@Phishion 很有可能,如果流量在进入 input 链之前就被截获然后发到 docker 的话,iptables 根本就不起作用了
artandlol
2019-08-02 17:41:08 +08:00
iptable 有两种模式,一个默认 drop 一个默认 accept, docker 默认会把局域网的特定网段都打通
Phishion
2019-08-02 18:54:35 +08:00
@ik @omph @lpvekk @xduanx @Bardon @ladypxy @znood @VD @daviswei @littlewing @artandlol

感谢各位大佬
问题已经解决,排查出是 Docker 的问题,因为宿主机的 80 口映射到容器的 80 端口,所以无论怎么配置 iptables,80 端口都不会受到影响。

应该是 Docker 提前接管了对于端口的访问

解决方法如下:
编辑 /etc/fail2ban/action.d/iptables-common.conf 文件
将 chain = INPUT 改成 chain = DOCKER-USER 这样 fail2ban 生成的 iptables 规则就可以正常生效了。
znood
2019-08-02 19:09:45 +08:00
@Phishion 你改成 DOCKER-USER 其他规则可能就无法生效了,改成 PREROUTING
littlewing
2019-08-02 19:14:09 +08:00
楼上说的对
顺便贴一张 iptables 的图

https://i.loli.net/2019/08/02/5d43e5e06f3ff84451.jpg
Phishion
2019-08-02 19:25:20 +08:00
@littlewing
@znood
得,我花时间再看看,目前没啥规则,谢谢大佬指导
Phishion
2019-08-02 19:49:52 +08:00
@znood @littlewing
确实出问题了,改成 DOCKER-USER 的话,SSH 规则就失效了,但改成 PREROUTING 所有规则都不会生效,真是伤脑筋。。。
xduanx
2019-08-02 21:14:11 +08:00
做了端口映射的话,这就说得通了,docker 端口映射是在 nat 的 prerouting 链里配置的,数据包过防火墙的时候会先经过 prerouting 链,nat 把数据包的目的 IP 修改为 docker 的 IP 后,由于数据包目的 IP 不是本机 IP,数据包不会经过 INPUT 链(所以楼主的 INPUT 链虽然配置正确但没有达到效果)而是进入 forward 链,然后匹配 dorward 里的规则,之后数据包进入 docker。对于 INPUT 链里的规则匹配到了数据包,由于知识有限,看不懂源码,无法作出解释。
znood
2019-08-02 21:14:25 +08:00
failban 添加到了 filter 表,转发包不走 filter-INPUT,需要在之前处理,PREROUTING 不在 filter 表里,加到 nat 表试下。
Phishion
2019-08-02 21:25:32 +08:00
最终我还是解决掉了,做法是单独给 nginx404 指定一个动作,2 个规则现在都正确生效,不知道算不算临时解决方案,不过搞定就行。

1. 给 nginxno404 规则指定一个自定义动作
vi /etc/fail2ban/jail.local
[nginxno404]
action = iptables-nginx[name=nginxno404, port=http, protocol=tcp]

2.新建动作页面
复制 /etc/fail2ban/action.d/iptables-common.conf 为 iptables-nginx.conf
承接 iptables.conf,然后将 iptables-common.local 注释掉
再指定 chain name 为 DOCKER-USER

```
vi /etc/fail2ban/action.d/iptables-nginx.conf
[INCLUDES]
before = iptables.conf
after = iptables-blocktype.local
[Init]
chain = DOCKER-USER
```

3. 重启 fail2ban
systemctl restart fail2ban.service
VD
2019-08-05 10:21:53 +08:00
仔细看下这里
https://gist.github.com/tehmoon/b1c3ae5e9a67d66186361d4728bed799#file-iptables-reload-sh

似乎现在也只有这种办法了

阅读下这篇文章
https://medium.com/@ebuschini/iptables-and-docker-95e2496f0b45

安装有 docker 的主机,nat 表第一条就是
-A PREROUTING -m addrtype — dst-type LOCAL -j DOCKER
表示所有流量被路由到 DOCKER 链

如果对 iptables 足够自信,那么直接自己手动配置,而不要启用 docker 的 iptables 规则,譬如 centos 下这个文件 /etc/sysconfig/docker,其中启动 options 加上--iptables=false
然后发挥你自己功力吧,虽然我并不建议这么做

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/588382

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX