V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Phishion
V2EX  ›  程序员

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

  •  
  •   Phishion · Aug 2, 2019 · 6147 views
    This topic created in 2470 days ago, the information mentioned may be changed or developed.

    之前使用 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           
    
    Supplement 1  ·  Aug 2, 2019
    输入 iptables -I INPUT -s 182.254.74.167 -j DROP 之后,SSH 会被立即断开,但是 web 依然可以正常访问,应该不是 iptable 没有启动,肯定不是缓存的问题,也没有 CDN,我推测会不会是 fail2ban 里面规则的顺序问题。
    Supplement 2  ·  Aug 2, 2019
    目前没启用 https,访问都是 80 端口
    Supplement 3  ·  Aug 2, 2019
    问题已经解决,排查出是 Docker 的问题,因为宿主机的端口映射到容器的端口,所以无论怎么配置 iptables,80 端口都不会受到影响。

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

    解决方法如下:
    编辑 /etc/fail2ban/action.d/iptables-common.conf 文件
    将 chain = INPUT 改成 chain = DOCKER-USER 这样 fail2ban 生成的 iptables 规则就可以正常生效了。

    关键词:Docker Linux fail2ban iptables nginx 80 端口 不生效
    32 replies    2019-08-05 10:21:53 +08:00
    Dragonish3600
        1
    Dragonish3600  
       Aug 2, 2019 via iPhone   ❤️ 1
    顺序很重要,drop 部分要放在最上面
    ik
        2
    ik  
       Aug 2, 2019 via iPhone   ❤️ 1
    iptables -I INPUT -s 182.254.74.167 -j DROP
    xmgit
        3
    xmgit  
       Aug 2, 2019   ❤️ 1
    什么情况
    INPUT 引用 f2b-nginxno404 链,然后 f2b-nginxno404 中 针对 182.254.74.167 reject 了

    暴力破解 ssh 的,在 f2b-SSH 链中 reject 了
    xduanx
        4
    xduanx  
       Aug 2, 2019   ❤️ 1
    @Bardon 理论上,这样操作没问题吧,但 LZ 说不生效,大佬是否看出哪里不对么
    lpvekk
        5
    lpvekk  
       Aug 2, 2019   ❤️ 1
    iptables service start
    skylancer
        6
    skylancer  
       Aug 2, 2019   ❤️ 1
    @lpvekk 回帖前请看清楚人家写了什么,谢谢茄子
    omph
        7
    omph  
       Aug 2, 2019   ❤️ 1
    网页有缓存吗?
    laminux29
        8
    laminux29  
       Aug 2, 2019   ❤️ 1
    开 debug 模式,规则全删,一条条地加进去,加一条测一条。当加到某条,发生测试结果与预计不符的情况时,调换顺序,或者随机删除某几项。
    Phishion
        9
    Phishion  
    OP
       Aug 2, 2019
    @ik @omph @lpvekk @xduanx @Bardon @ladypxy

    报告各位大佬:
    输入 iptables -I INPUT -s 182.254.74.167 -j DROP 之后,SSH 会被立即断开,但是 web 依然可以正常访问,应该不是 iptable 没有启动,肯定不是缓存的问题,也没有 CDN,我推测会不会是 fail2ban 里面规则的顺序问题。
    znood
        10
    znood  
       Aug 2, 2019   ❤️ 1
    是不是只 REJECT 了 80 端口,依然可以通过 443 访问?
    Phishion
        11
    Phishion  
    OP
       Aug 2, 2019
    @znood 我开没启用 https,目前访问都是 80 的
    VD
        12
    VD  
       Aug 2, 2019
    -I 是插入到指定位置,然而你没有指定行位置,所以还是插入到 INPUT 最后一行了


    如果你就是想对 INPUT 操作,不论 f2b-SSH 还是 f2b-nginxno404 都要生效,注意顺序,譬如放在 INPUT 中的第一行,iptables 是从上到下匹配。
    iptables -I INPUT 1 -s 182.254.74.167 -j DROP
    VD
        13
    VD  
       Aug 2, 2019
    说错了,不指定行数,默认就是第一行...

    那就不可能了呀,对方访问的是缓存数据?你确定对方 web 访问后,你的 nginx 中有对应的日志产生?
    VD
        14
    VD  
       Aug 2, 2019   ❤️ 1
    一般而言,iptables 的 input 默认 drop

    然后第一条放行 ping,禁 ping 的忽略
    -A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT
    第二条放行以连接的,譬如 ssh 目前连接着,防止被立即 drop 掉
    -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    第三条放行 lo 回环
    -A INPUT -i lo -j ACCEPT
    ......
    中间放具体规则
    ......
    末尾收尾
    -A INPUT -m conntrack --ctstate INVALID -j DROP
    -A INPUT -j REJECT --reject-with icmp-host-prohibited
    VD
        15
    VD  
       Aug 2, 2019   ❤️ 1
    问下 182.254.74.167 是你的外网吧,你在内网测试?流量通过网关直接走了内网。
    Phishion
        16
    Phishion  
    OP
       Aug 2, 2019
    @VD 感谢你的回复,IP 是我的外网 IP,iptables -I INPUT 1 -s 182.254.74.167 -j DROP 之后,SSH 会立即断开,但是网页竟然还是正常的,不是内网,我是电信宽带,服务器在美国。

    iptables -L -n

    ```
    Chain INPUT (policy ACCEPT)
    target prot opt source destination
    DROP all -- 182.254.74.167 0.0.0.0/0
    f2b-nginxno404 tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
    DROP all -- 182.254.74.167 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
    INPUT_direct all -- 0.0.0.0/0 0.0.0.0/0
    INPUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0
    INPUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0
    DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
    REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

    Chain FORWARD (policy DROP)
    target prot opt source destination
    DOCKER-USER all -- 0.0.0.0/0 0.0.0.0/0
    DOCKER-ISOLATION-STAGE-1 all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
    DOCKER all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
    DOCKER all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
    ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
    FORWARD_direct all -- 0.0.0.0/0 0.0.0.0/0
    FORWARD_IN_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0
    FORWARD_IN_ZONES all -- 0.0.0.0/0 0.0.0.0/0
    FORWARD_OUT_ZONES_SOURCE all -- 0.0.0.0/0 0.0.0.0/0
    FORWARD_OUT_ZONES all -- 0.0.0.0/0 0.0.0.0/0
    DROP all -- 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
    REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

    Chain OUTPUT (policy ACCEPT)
    target prot opt source destination
    OUTPUT_direct all -- 0.0.0.0/0 0.0.0.0/0

    Chain DOCKER (2 references)
    target prot opt source destination
    ACCEPT tcp -- 0.0.0.0/0 172.19.0.2 tcp dpt:8080
    ACCEPT tcp -- 0.0.0.0/0 172.19.0.2 tcp dpt:8000
    ACCEPT tcp -- 0.0.0.0/0 172.19.0.3 tcp dpt:80
    ACCEPT tcp -- 0.0.0.0/0 172.19.0.4 tcp dpt:5432

    Chain DOCKER-ISOLATION-STAGE-1 (1 references)
    target prot opt source destination
    DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
    DOCKER-ISOLATION-STAGE-2 all -- 0.0.0.0/0 0.0.0.0/0
    RETURN all -- 0.0.0.0/0 0.0.0.0/0

    Chain DOCKER-ISOLATION-STAGE-2 (2 references)
    target prot opt source destination
    DROP all -- 0.0.0.0/0 0.0.0.0/0
    DROP all -- 0.0.0.0/0 0.0.0.0/0
    RETURN all -- 0.0.0.0/0 0.0.0.0/0

    Chain DOCKER-USER (1 references)
    target prot opt source destination
    RETURN all -- 0.0.0.0/0 0.0.0.0/0

    Chain FORWARD_IN_ZONES (1 references)
    target prot opt source destination
    FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
    FWDI_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]

    Chain FORWARD_IN_ZONES_SOURCE (1 references)
    target prot opt source destination

    Chain FORWARD_OUT_ZONES (1 references)
    target prot opt source destination
    FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
    FWDO_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]

    Chain FORWARD_OUT_ZONES_SOURCE (1 references)
    target prot opt source destination

    Chain FORWARD_direct (1 references)
    target prot opt source destination

    Chain FWDI_public (2 references)
    target prot opt source destination
    FWDI_public_log all -- 0.0.0.0/0 0.0.0.0/0
    FWDI_public_deny all -- 0.0.0.0/0 0.0.0.0/0
    FWDI_public_allow all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0

    Chain FWDI_public_allow (1 references)
    target prot opt source destination

    Chain FWDI_public_deny (1 references)
    target prot opt source destination

    Chain FWDI_public_log (1 references)
    target prot opt source destination

    Chain FWDO_public (2 references)
    target prot opt source destination
    FWDO_public_log all -- 0.0.0.0/0 0.0.0.0/0
    FWDO_public_deny all -- 0.0.0.0/0 0.0.0.0/0
    FWDO_public_allow all -- 0.0.0.0/0 0.0.0.0/0

    Chain FWDO_public_allow (1 references)
    target prot opt source destination

    Chain FWDO_public_deny (1 references)
    target prot opt source destination

    Chain FWDO_public_log (1 references)
    target prot opt source destination

    Chain INPUT_ZONES (1 references)
    target prot opt source destination
    IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]
    IN_public all -- 0.0.0.0/0 0.0.0.0/0 [goto]

    Chain INPUT_ZONES_SOURCE (1 references)
    target prot opt source destination

    Chain INPUT_direct (1 references)
    target prot opt source destination

    Chain IN_public (2 references)
    target prot opt source destination
    IN_public_log all -- 0.0.0.0/0 0.0.0.0/0
    IN_public_deny all -- 0.0.0.0/0 0.0.0.0/0
    IN_public_allow all -- 0.0.0.0/0 0.0.0.0/0
    ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0

    Chain IN_public_allow (1 references)
    target prot opt source destination
    ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 ctstate NEW

    Chain IN_public_deny (1 references)
    target prot opt source destination

    Chain IN_public_log (1 references)
    target prot opt source destination

    Chain OUTPUT_direct (1 references)
    target prot opt source destination

    Chain f2b-nginxno404 (1 references)
    target prot opt source destination
    REJECT all -- 182.254.74.167 0.0.0.0/0 reject-with icmp-port-unreachable
    RETURN all -- 0.0.0.0/0 0.0.0.0/0
    ```
    daviswei
        17
    daviswei  
       Aug 2, 2019
    目测你这 INPUT 链没有啥问题,要不看看 mangle 表,是不是这里也配置了 INPUT 链啊?
    daviswei
        18
    daviswei  
       Aug 2, 2019
    daviswei
        19
    daviswei  
       Aug 2, 2019   ❤️ 1
    @Phishion 还有个可能,你访问网页的时候 ,浏览器是不是有代理?
    Phishion
        20
    Phishion  
    OP
       Aug 2, 2019
    @daviswei 感谢你的帮助
    我试了一下,不是代理的问题,我关掉代理也可以访问,和我同一个局域网的手机也可以正常访问,而且 IP 地址实际上是服务端 fail2ban 捕获的,跟我本地的 IP 也吻合。
    我不是专业运维,所以不太懂 mangle 这样的问题
    Phishion
        21
    Phishion  
    OP
       Aug 2, 2019
    @daviswei 我在想是不是 Docker 的问题,我的 nginx 是容器,宿主机上的 80 端口实际上是映射到 nginx 容器的 80 端口,是不是因为 Docker 导致所有 80 端口无视 iptable 无条件转发给 nginx
    littlewing
        22
    littlewing  
       Aug 2, 2019 via iPhone   ❤️ 1
    @Phishion 很有可能,如果流量在进入 input 链之前就被截获然后发到 docker 的话,iptables 根本就不起作用了
    artandlol
        23
    artandlol  
       Aug 2, 2019 via Android   ❤️ 1
    iptable 有两种模式,一个默认 drop 一个默认 accept, docker 默认会把局域网的特定网段都打通
    Phishion
        24
    Phishion  
    OP
       Aug 2, 2019
    @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
        25
    znood  
       Aug 2, 2019   ❤️ 1
    @Phishion 你改成 DOCKER-USER 其他规则可能就无法生效了,改成 PREROUTING
    littlewing
        26
    littlewing  
       Aug 2, 2019   ❤️ 2
    楼上说的对
    顺便贴一张 iptables 的图

    https://i.loli.net/2019/08/02/5d43e5e06f3ff84451.jpg
    Phishion
        27
    Phishion  
    OP
       Aug 2, 2019
    @littlewing
    @znood
    得,我花时间再看看,目前没啥规则,谢谢大佬指导
    Phishion
        28
    Phishion  
    OP
       Aug 2, 2019
    @znood @littlewing
    确实出问题了,改成 DOCKER-USER 的话,SSH 规则就失效了,但改成 PREROUTING 所有规则都不会生效,真是伤脑筋。。。
    xduanx
        29
    xduanx  
       Aug 2, 2019 via iPhone   ❤️ 1
    做了端口映射的话,这就说得通了,docker 端口映射是在 nat 的 prerouting 链里配置的,数据包过防火墙的时候会先经过 prerouting 链,nat 把数据包的目的 IP 修改为 docker 的 IP 后,由于数据包目的 IP 不是本机 IP,数据包不会经过 INPUT 链(所以楼主的 INPUT 链虽然配置正确但没有达到效果)而是进入 forward 链,然后匹配 dorward 里的规则,之后数据包进入 docker。对于 INPUT 链里的规则匹配到了数据包,由于知识有限,看不懂源码,无法作出解释。
    znood
        30
    znood  
       Aug 2, 2019   ❤️ 1
    failban 添加到了 filter 表,转发包不走 filter-INPUT,需要在之前处理,PREROUTING 不在 filter 表里,加到 nat 表试下。
    Phishion
        31
    Phishion  
    OP
       Aug 2, 2019
    最终我还是解决掉了,做法是单独给 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
        32
    VD  
       Aug 5, 2019
    仔细看下这里
    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
    然后发挥你自己功力吧,虽然我并不建议这么做
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5499 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 68ms · UTC 05:57 · PVG 13:57 · LAX 22:57 · JFK 01:57
    ♥ Do have faith in what you're doing.