Iptables 无法阻止来自特定 ip 的入站

den*_*n0n 5 networking tcp iptables centos-7

你好,我有一个在线服务器,我使用它,比如网关,而 iptables 表现得很奇怪

-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 443 -j BLOCK_CHAIN
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j BLOCK_CHAIN
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -o tun+ -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o tun+ -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o tun+ -p tcp -m tcp --dport 443 --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
-A BLOCK_CHAIN -s 173.230.154.149/32 -j REJECT --reject-with icmp-host-prohibited
-A BLOCK_CHAIN -m state --state NEW -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

但 173.230.154.149 仍然可以在 80 或 443 中访问 apache 服务器,它不应该被阻止

-A INPUT -i eth0 -p tcp -m tcp --dport 443 -j BLOCK_CHAIN
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j BLOCK_CHAIN
Run Code Online (Sandbox Code Playgroud)

-A BLOCK_CHAIN -s 173.230.154.149/32 -j REJECT --reject-with icmp-host-prohibited
Run Code Online (Sandbox Code Playgroud)

是的,它是一个在线服务器,通过 VPN 和 openvpn 将所有 Web 服务路由到个人更大的服务器

一切都按预期工作,只是我无法阻止来自某些 ip 的传入连接,女巫显然正在攻击服务器

网络的类型是

外部 IP XX.XX.X.XX VPN 10.0.0.0/24

-A PREROUTING -i eth0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.0.100
-A PREROUTING -i eth0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 10.0.0.100
Run Code Online (Sandbox Code Playgroud)

A.B*_*A.B 9

正在路由而不是由本地进程接收的数据包会遍历过滤器/FORWARD 链,而不是过滤器/INPUT 链,即使这是由使用 NAT 引起的。所以当前filter/INPUT中的阻止规则不起作用。这些规则:

-A INPUT -i eth0 -p tcp -m tcp --dport 443 -j BLOCK_CHAIN
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j BLOCK_CHAIN
Run Code Online (Sandbox Code Playgroud)

应该简单地替换为:

-A FORWARD -i eth0 -p tcp -m tcp --dport 443 -j BLOCK_CHAIN
-A FORWARD -i eth0 -p tcp -m tcp --dport 80 -j BLOCK_CHAIN
Run Code Online (Sandbox Code Playgroud)

显然,它们应该添加在允许访问 Web 服务器的规则之前,这样它们才能发挥作用。因此,至少在这些之前添加它们:

-A FORWARD -i eth0 -o tun+ -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o tun+ -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
-A FORWARD -i eth0 -o tun+ -p tcp -m tcp --dport 443 --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

因为一旦初始连接被接受,所有进一步的数据包将被此规则短路:

-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Run Code Online (Sandbox Code Playgroud)

所以第一时间看到他们就必须被阻止。


附加说明:

  • 冗余规则

    -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -i tun+ -j ACCEPT
    -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    
    Run Code Online (Sandbox Code Playgroud)

    上面的第一条规则,还有第二条规则,每条规则都是单独的,使得第三条规则变得多余。

    同样地:

    -A FORWARD -i eth0 -o tun+ -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
    -A FORWARD -i eth0 -o tun+ -p tcp -m tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
    -A FORWARD -i eth0 -o tun+ -p tcp -m tcp --dport 443 --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j ACCEPT
    
    Run Code Online (Sandbox Code Playgroud)

    第一条规则使以下两条规则变得多余。

    但这一切可能都是为了测试当前的问题。

  • 除非运行最新的内核(问题已修复),否则任何 REJECT 规则都不允许拒绝处于 INVALID 状态的数据包。此类数据包应该“仅”被丢弃,否则可能会发生合法流量的罕见随机连接失败。

    这现在记录在iptables-extensions(8)

    警告:您不应不加区别地将 REJECT 目标应用于连接状态分类为 INVALID 的数据包;相反,你应该只删除这些。

    (手册页随后提供了进一步的理由。)

    所以通常情况下,

    -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
    
    Run Code Online (Sandbox Code Playgroud)

    后面应该是:

    -A FORWARD -m conntrack --ctstate INVALID -j DROP
    
    Run Code Online (Sandbox Code Playgroud)