在 shell 脚本中添加 iptables 块之间的睡眠/延迟

在 shell 脚本中添加 iptables 块之间的睡眠/延迟

在一台服务器上,我们试图阻止中国的任何访问。

我们希望通过 iptables 而不是通过 .htaccess 来实现这一点。

然而,我们遇到的问题是,当一次添加多个 iptables 时(我们这里谈论的是中国的 1000 多个 IP 子网),一个会失败(出现错误“iptables:未知错误 18446744073709551615”,然后之后的所有其他都会失败),这意味着我们必须iptables -F继续添加这些规则。

一些测试得出的结论是,问题似乎在于尝试同时运行很多操作(或者甚至一次运行 10 个以上似乎都会引发错误),而不是服务器不喜欢某些特定规则。

所以我想知道是否尝试在每个 iptables 规则运行之间添加睡眠(或其他延迟)可以改善这个过程?

我们已经尝试了多种方法来实现这些 iptables,但如果可能的话,我们希望使用这个脚本来自 nixCraft如下所示。

#!/bin/bash
### Block all traffic from AFGHANISTAN (af) and CHINA (CN). Use ISO code ###
ISO="af cn"

### Set PATH ###
IPT=/sbin/iptables
WGET=/usr/bin/wget
EGREP=/bin/egrep

### No editing below ###
SPAMLIST="countrydrop"
ZONEROOT="/root/iptables"
DLROOT="http://www.ipdeny.com/ipblocks/data/countries"

cleanOldRules(){
$IPT -F
$IPT -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -P INPUT ACCEPT
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
}

# create a dir
[ ! -d $ZONEROOT ] && /bin/mkdir -p $ZONEROOT

# clean old rules
cleanOldRules

# create a new iptables list
$IPT -N $SPAMLIST

for c  in $ISO
do
    # local zone file
    tDB=$ZONEROOT/$c.zone

    # get fresh zone file
    $WGET -O $tDB $DLROOT/$c.zone

    # country specific log message
    SPAMDROPMSG="$c Country Drop"

    # get 
    BADIPS=$(egrep -v "^#|^$" $tDB)
    for ipblock in $BADIPS
    do
       $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
       $IPT -A $SPAMLIST -s $ipblock -j DROP
    done
done

# Drop everything 
$IPT -I INPUT -j $SPAMLIST
$IPT -I OUTPUT -j $SPAMLIST
$IPT -I FORWARD -j $SPAMLIST

# call your other iptable script
# /path/to/other/iptables.sh

exit 0

但是,我对 shell 脚本不是特别熟悉,并且不确定在这个脚本的哪个位置我可以添加某种延迟,如果可能的话。请问有人能给我指出正确的方向吗?谢谢。

答案1

Netfilter/iptables 在规则数量较多时扩展性不佳,因为它们应该按顺序匹配。但从 Linux 内核 2.6.36 开始,有一项新功能称为IP 集这有助于使用哈希技术消除此类规则。简而言之,它的工作原理如下:

1)创建IP集

ipset create set01 hash:net

2)将 IP 范围添加到集合中

ipset add set01 192.168.1.0/24
ipset add set01 192.168.2.0/24
ipset add set01 192.168.3.0/24
ipset add set01 192.168.4.0/24
...
...

3)将集合与 netfilter/iptables 规则连接起来,该规则拒绝任何源 IP 地址来自集合 set01 的数据包

iptables -A INPUT -m set --match-set set01 src -j REJECT

如您所见,我没有创建 4 条几乎相同的 iptables 规则,而是创建了一个 IP 集 set01,然后向其中添加了一些 IP 范围(仅作为示例,实际上可能有数百万个),最后通过单个 iptables 规则阻止了它们。因此,无需维护一长串类似的 iptables 规则,只需根据区域文件创建一个 IP 集,然后一步即可阻止它。

请查看相关的 ipset 手册页以获取更多详细信息。

答案2

我同意 dsumsky 的观点,你可能需要一种新方法。但要为每加载 4 个条目延迟 1 秒,要插入的代码应如下所示:

i=0  # delay iterator

BADIPS=$(egrep -v "^#|^$" $tDB)
for ipblock in $BADIPS
do
   # delay to help rules load properly.
   if [[ $i == 5 ]]
   then
         sleep 1
         i=0
   fi

   i=$((i+1))

   $IPT -A $SPAMLIST -s $ipblock -j LOG --log-prefix "$SPAMDROPMSG"
   $IPT -A $SPAMLIST -s $ipblock -j DROP
done

您可以使用如下代码块来试验该代码:

 #!/bin/bash
 i=0
 while [ 1 ]
 do
    i=$((i+1))
    if [[ $i == 5 ]]
    then
            sleep 1
            i=0
    fi


    echo hello $i
done

相关内容