如何使用 iptables/ipset 阻止 ipv4 列表,但排除某些端口

如何使用 iptables/ipset 阻止 ipv4 列表,但排除某些端口

我在 bash 中有以下规则(按顺序):

# blocklist.txt contains:
#192.168.1.39

for ip in $(cat blocklist.txt); do
    iptables -I INPUT -s $ip -p tcp -m multiport --dports 137:139,445 -j ACCEPT
    iptables -I FORWARD -d $ip -p tcp -m multiport --dports 137:139,445 -j ACCEPT
done

ipset flush banip
ipset -N -! banip hash:ip maxelem 1000000
for ip in $(cat blocklist.txt); do
    ipset -A banip "$ip"
done
iptables -I INPUT -m set --match-set banip src,dts -j DROP
iptables -I FORWARD -m set --match-set banip src,dts -j DROP

其中“blocklist”包括 ipv4 地址。但我的规则阻止了该列表并且不允许访问 ALLOW 规则中排除的那些端口。

注 1:我尝试过hash:iphash:net,结果相同

注2:如果我为-p udp添加ACCEPT规则,端口仍然被阻止。

根据这里您应该这样做,但这也不会打开该列表所需的端口:

ipset flush banip
ipset -N -! banip hash:ip maxelem 1000000
for ip in $(cat blocklist.txt); do
    ipset -A banip "$ip"
done
iptables -I INPUT -p tcp -m multiport --dports 137:139,445 -m set --match-set banip src,dts -j ACCEPT
iptables -I INPUT -m set --match-set banip src,dts -j DROP
iptables -I FORWARD -p tcp -m multiport --dports 137:139,445 -m set --match-set banip src,dts -j ACCEPT
iptables -I FORWARD -m set --match-set banip src,dts -j DROP

并根据这里你应该这样做,但同样的情况会发生:

ipset flush banip
ipset -N -! banip hash:ip maxelem 1000000
for ip in $(cat blocklist.txt); do
    ipset -A banip "$ip"
done
iptables -I INPUT -m set --match-set banip src,dts -p tcp -m multiport --dport 137:139,445 -j ACCEPT
iptables -I INPUT -m set --match-set banip src,dts -j DROP
iptables -I FORWARD -m set --match-set banip src,dts -p tcp -m multiport --dport 137:139,445 -j ACCEPT
iptables -I FORWARD -m set --match-set banip src,dts -j DROP

我的数据:

  • iptables v1.8.7
  • ipset v7.15
  • Ubuntu 22.04

ipset -L banip

Name: banip
Type: hash:ip
Revision: 5
Header: family inet hashsize 1024 maxelem 1000000 bucketsize 12 initval 0xebeb2f5c
Size in memory: 240
References: 16
Number of entries: 1
Members:
192.168.1.39

iptables -L -v -n

Chain INPUT (policy ACCEPT 4185 packets, 7480K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst multiport dports 137:139,445
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src multiport dports 137:139,445
Chain FORWARD (policy ACCEPT 170 packets, 29238 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst multiport dports 137:139,445
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src multiport dports 137:139,445

我的规则有什么问题?谢谢

更新:

我还创建了一个包含端口的新列表,并在阻止列表之前允许它,但没有结果。

# allowports.txt contains:
# 137
# 138
# 139
# 445

ipset flush allowports
ipset -N -! allowports bitmap:port range 0-65535
for ports in $(cat allowports.txt); do
    ipset -A allowports "$ports"
done
iptables -I INPUT -m set --match-set allowports src,dts -j ACCEPT
iptables -I FORWARD -m set --match-set allowports src,dts -j ACCEPT

ipset flush banip
ipset -N -! banip hash:ip maxelem 1000000
for ip in $(cat blocklist.txt); do
    ipset -A banip "$ip"
done
iptables -I INPUT -m set --match-set banip src,dts -j DROP
iptables -I FORWARD -m set --match-set banip src,dts -j DROP

ipset -L 允许端口

Name: allowports
Type: bitmap:port
Revision: 3
Header: range 0-65535
Size in memory: 8264
References: 16
Number of entries: 4
Members:
137
138
139
445

新的 iptables -L -v -n

Chain INPUT (policy ACCEPT 757 packets, 619K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
   42  3883 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set allowports dst
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set allowports src
Chain FORWARD (policy ACCEPT 197 packets, 11983 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip dst
    0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set banip src
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set allowports dst
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            match-set allowports src

解决了!

按照@MarkWagner的建议,我反转了规则,问题就解决了。这是因为iptables规则是按顺序执行的。但是,--insert(-I)规则放在标题中,在--append(-A)规则之上,但如果有两个“--insert”规则,则最后一个将是标题中的规则(第一个)。所以正确的方法是:

ipset flush banip
ipset -N -! banip hash:ip maxelem 1000000
for ip in $(cat blocklist.txt); do
    ipset -A banip "$ip"
done
iptables -I INPUT -m set --match-set banip src,dts -j DROP
iptables -I FORWARD -m set --match-set banip src,dts -j DROP
for protocol in $(echo udp tcp); do
   iptables -I INPUT -m set --match-set banip src,dts -$protocol -m multiport --dports 137,138,139,445 -j ACCEPT
   iptables -I FORWARD -m set --match-set banip src,dts -$protocol -m multiport --dports 137,138,139,445 -j ACCEPT
done

相关内容