Linux

在 shell 腳本中的 iptables 塊之間添加睡眠/延遲

  • August 27, 2013

在一台伺服器上,我們試圖阻止對中國國家的任何訪問。

我們希望使用 iptables 而不是通過 .htaccess 來實現這一點。

但是我們遇到的問題是,當一次添加多個 iptables 時(我們在這里為中國談論超過 1000 個 ip 子網),一個會失敗(錯誤 ‘iptables: Unknown error 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 腳本並不是特別熟悉,並且不確定在這個腳本中的什麼時候我可以在 iptables 處理之間添加某種延遲,如果可能的話。請有人能指出我正確的方向嗎?謝謝。

當與更多規則一起使用時,Netfilter/iptables 不能很好地擴展,因為它們應該按順序匹配。但是從 Linux 核心 2.6.36 開始,有一個稱為IP 集的新特性,它通過使用散列技術幫助消除這些規則。簡而言之,它是如何工作的:

1)創建IP集

ipset create set01 hash:net
  1. 將 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
...
...
  1. 使用 netfilter/iptables 規則連接該集合,該規則拒絕來自集合 set01 的任何具有源 IP 地址的數據包
iptables -A INPUT -m set --match-set set01 src -j REJECT

如您所見,我沒有創建 4 個幾乎相同的 iptables 規則,而是創建了一個 IP 集 set01,然後我添加了一些 IP 範圍(只是一個範例,實際上可能有數百萬個),最後我通過單個 iptables 規則。因此,與其維護一長串類似的 iptables 規則,不如根據區域文件創建一個 IP 集,然後一步阻止它。

請查看相關的 ipset 手冊頁以獲取更多詳細資訊。

引用自:https://serverfault.com/questions/534092