用于读取文件的Shell脚本

时间:2016-12-29 11:36:56

标签: bash shell sh iptables

我编写了一个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

如何避免这种重复?任何帮助,请

2 个答案:

答案 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)