我编写了一个shell脚本来读取由IP地址组成的文件,然后在iptables的帮助下阻止它们。它工作正常,但是当我第二次运行脚本时,它再次写入规则(重复)。我希望它检查IP是否已被阻止然后忽略它否则阻止。这是脚本:
#!/bin/bash
ipadds="/home/asad/Downloads/blacklist"
dropit=$(grep -Ev "^#" $ipadds)
for i in $dropit; do
iptables -A INPUT -s $i -j DROP
iptables -A FORWARD -s $i -j DROP
done
首次运行脚本后的输出:
root@ubuntu:/home/asad/Downloads# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.248.2 anywhere
DROP all -- 192.168.232.20 anywhere
DROP all -- 192.168.232.5 anywhere
DROP all -- 192.168.232.190 anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.248.2 anywhere
DROP all -- 192.168.232.20 anywhere
DROP all -- 192.168.232.5 anywhere
DROP all -- 192.168.232.190 anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
第二次运行脚本后的输出:
root@ubuntu:/home/asad/Downloads# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.248.2 anywhere
DROP all -- 192.168.232.20 anywhere
DROP all -- 192.168.232.5 anywhere
DROP all -- 192.168.232.190 anywhere
DROP all -- 192.168.248.2 anywhere
DROP all -- 192.168.232.20 anywhere
DROP all -- 192.168.232.5 anywhere
DROP all -- 192.168.232.190 anywhere
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.248.2 anywhere
DROP all -- 192.168.232.20 anywhere
DROP all -- 192.168.232.5 anywhere
DROP all -- 192.168.232.190 anywhere
DROP all -- 192.168.248.2 anywhere
DROP all -- 192.168.232.20 anywhere
DROP all -- 192.168.232.5 anywhere
DROP all -- 192.168.232.190 anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
如何避免这种重复?任何帮助,请
答案 0 :(得分:1)
#!/bin/bash
ipadds=/home/asad/Downloads/blacklist
grep -v "^#" $ipadds | while read i; do
if ! iptables -nL INPUT | grep -Fq "$i" ; then
iptables -A INPUT -s "$i" -j DROP
iptables -A FORWARD -s "$i" -j DROP
fi
done
或者(也许这对你没什么影响)
#!/bin/bash
ipadds=/home/asad/Downloads/blacklist
while read i; do
if ! iptables -nL INPUT | grep -Fq "$i" ; then
iptables -A INPUT -s "$i" -j DROP
iptables -A FORWARD -s "$i" -j DROP
fi
done < <(grep -v "^#" $ipadds)
请注意,在这种情况下,不需要-E
的{{1}}标记。将grep
标志传递给-n
以获取IP而非主机名至关重要;它还可以提高性能。我假设您的INPUT和FORWARD链保持同步,因此我只检查其中一个。如果不是这种情况,当然应该检查两者。
上述脚本的确切语义是:“如果已经在INPUT链中的任何地方提到过,请不要插入新的候选IP”,这与“......如果它已被阻止”略有不同。基于iptables -L
的更有效的解决方案将寻找特定规则,但不会针对链中的其他IP提及。我可以想到两种方法都更可取的情况。
如果您的iptables链中有很多IP,扫描整个链以检查候选IP是否已经存在可能效率低下。如果这成为一个问题,有多种方法可以构建外部索引以实现更高效的IP查找,但OTOH整个系统将变得更难维护,因此我将在没有外部索引的情况下进行实验。
答案 1 :(得分:0)
你可以尝试
#!/bin/bash
ipadds="/home/asad/Downloads/blacklist"
while IFS='' read -r
do
# check if the rule already exists - if not add it - and
# silently ignore warnings for rules that dont exist
if ! iptables -C INPUT -s "$REPLY" -j DROP 2> /dev/null
then
iptables -A INPUT -s "$REPLY" -j DROP
fi
if ! iptables -C FORWARD -s "$REPLY" -j DROP 2> /dev/null
then
iptables -A FORWARD -s "$REPLY" -j DROP
fi
# Please note proper syntax for process substitution
done < <(grep -Ev "^#" $ipadds)