我有这个循环来使用 ipset/iptables 阻止 IP 和 CIDR:
# this is just an example. the actual list IPs/CIDR is very large
cat blockip.txt
13.31.0.254
cat blockcidr.txt
13.32.0.0/15
环形:
#!/bin/bash
ipset -F
ipset -N -! blacklist hash:net maxelem 1000000
for ip in $(cat blockip.txt blockcidr.txt); do
ipset -A blacklist $ip
done
iptables -A FORWARD -m set --match-set blacklist dst -j DROP
注意:我一直使用该ipset -A
选项,但我不知道该选项的具体含义,因为它没有出现在“曼·伊普塞特“,此时,我假设与add
相同-A
,因为两种情况下的输出是相同的。
#!/bin/bash
ipset -F
ipset -N -! blacklist hash:net maxelem 1000000
for ip in $(cat blockip.txt blockcidr.txt); do
ipset add blacklist $ip -q
done
iptables -A FORWARD -m set --match-set blacklist dst -j DROP
两种情况均适用:
sudo ipset -L
Name: blacklist
Type: hash:net
Revision: 7
Header: family inet hashsize 1024 maxelem 1000000 bucketsize 12 initval 0xbc0136c8
Size in memory: 552
References: 0
Number of entries: 2
Members:
13.31.0.254
13.32.0.0/15
“它运行良好”,但是我读过了使用添加 IP 和 CIDRipset -A
非常慢。使用哪个更快ipset 保存并恢复。但我不明白如何工作,我的尝试失败了:
注意:我还没有找到解释为什么使用保存/恢复选项比使用add
或更快-A
#!/bin/bash
ipset -F
ipset -N -! blacklist hash:net maxelem 1000000
for ip in $(cat blockip.txt blockcidr.txt); do
ipset add blacklist $ip # ??
ipset save blacklist -f newblacklist.txt # ???
done
ipset restore -! < newblacklist.txt # ??
iptables -A FORWARD -m set --match-set blacklist dst -j DROP # ??
出去:
sudo ipset -L
Name: blacklist
Type: hash:net
Revision: 7
Header: family inet hashsize 1024 maxelem 1000000 bucketsize 12 initval 0xcb0e583b
Size in memory: 552
References: 0
Number of entries: 2
Members:
13.32.0.0/15
13.31.0.254
cat newblacklist.txt # out wrong
create blacklist hash:net family inet hashsize 1024 maxelem 1000000 bucketsize 12 initval 0xcb0e583b
add blacklist 13.32.0.0/15
add blacklist 13.31.0.254
我将不胜感激任何帮助(提供完整的答案,包括建议的循环或对我的循环的更正)
答案1
这对我有用:
# remove any old reference to the ipset
iptables -D FORWARD -m set --match-set blacklist dst -j DROP
ipset destroy
ipset create blacklist hash:net family inet hashsize 1024
ipset save > /tmp/ipset.txt
ipset destroy
cat blockip.txt blockcidr.txt | while read line; do
if [ "${line:0:1}" = "#" ]; then
continue
fi
echo "add blacklist $line" >> /tmp/ipset.txt
done
ipset restore < /tmp/ipset.txt
iptables -A FORWARD -m set --match-set blacklist dst -j DROP
请根据您的需要调整创建语句中的选项 - 根据集合的大小,这些选项非常重要。这进一步假设文件blockcidr.txt
仅包含如下行:
#comment
1.2.3.4/20
此后,恢复工作就正常了。
更新
在这种情况下,这种循环的瓶颈始终是子进程的创建ipset
。如果您有 10000 多个条目,则可执行 ipset 将被加载到内存中,并解析您要添加的每一行的选项……
我的循环仅包含 bash 内部命令,因此无需加载/执行任何可执行文件 - 只需将一些文本写入文件即可。当然 - 一次调用 ipset 比 10000 多次调用 ipset 要快得多...