Shell 读取文件的脚本

Shell script to read a file

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

如何避免这种重复?请帮忙

#!/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)

请注意,在这种情况下不需要 grep-E 标志。为了获取 IP 而不是主机名,将 -n 标志传递给 iptables -L 至关重要;它还可以提高性能。我假设您的 INPUT 和 FORWARD 链保持同步,因此我只检查其中之一。如果不是这种情况,当然应该检查两者。

上述脚本的确切语义是:“如果已经在 INPUT 链中的任何地方提到过,则不要插入新的候选 IP”,这与“...如果它已经被阻止”略有不同。基于 iptables -C 的更有效解决方案会查找特定规则,但不会查找链中提及的其他 IP。我可以想到两种方法都更可取的场景。

如果您的 iptables 链中有很多 IP,则扫描整个链以检查候选 IP 是否已经存在可能效率低下。如果这成为一个问题,有多种方法可以构建外部索引以更有效地查找 IP,但是 OTOH 整个系统将变得更加难以维护,所以我会在没有外部索引的情况下开始试验。

你可以试试

#!/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)