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