2014-12-29 64 views
2

我使用的是Ubuntu Server 14.04 32bit以下。如何快速從阻止列表中添加規則到iptables?

我正在嘗試使用阻止列表將區域塊(中國,俄羅斯......)添加到我的防火牆規則中,並且正在努力完成腳本完成所需的時間,並瞭解爲什麼不同的腳本無法工作。

我原本用來http://whatnotlinux.blogspot.com/2012/12/add-block-lists-to-iptables-from.html作爲一個例子,收拾了腳本非常接近什麼是下面的/修改的部分:

#!/bin/bash 

# Blacklist's names & URLs array 
declare -A blacklists 
blacklists[china]="http://www.example.com" 
#blacklists[key]="url" 

for key in ${!blacklists[@]}; do 
    #Download blacklist 
    wget --output-document=/tmp/blacklist_$key.gz -w 3 ${blacklists[$key]} 
    iptables -D INPUT -j $key #Delete current iptables chain link 
    iptables -F $key #Flush current iptables chain 
    iptables -X $key #Delete current iptables chain 
    iptables -N $key #Create current iptables chain 
    iptables -A INPUT -j $key #Link current iptables chain to INPUT chain 
    #Read blacklist 
    while read line; do 
    #Drop description, keep only IP range 
    ip_range=`echo -n $line | sed -e 's/.*:\(.*\)-\(.*\)/\1-\2/'` 
    #Test if it's an IP range 
    if [[ $ip_range =~ ^[0-9].*$ ]]; then 
    # Add to the blacklist 
    iptables -A $key -m iprange --src-range $ip_range -j LOGNDROP 
    fi 
    done < <(zcat /tmp/blacklist_$key.gz | iconv -f latin1 -t utf-8 - | dos2unix) 
done 
# Delete files 
rm /tmp/blacklist* 
exit 0 

這似乎短期測試列表做工精細,但手動添加許多( 200,000+)條目到iptables需要一個EXORBITANT時間量,我不知道爲什麼?根據列表我計算了這個需要10個小時才能完成的東西,看起來很愚蠢。

觀看的格式之後iptables-save命令輸出我創建了一個使用iptables-save命令來保存工作iptables規則,然後附加了塊預期的格式文件,如一個新的腳本:-A bogon -m iprange --src-range 0.0.0.1-0.255.255.255 -j LOGNDROP,並最終使用由iptables-restore加載該文件,如下圖所示:

#!/bin/bash 

# Blacklist's names & URLs arrays 
declare -A blacklists 
blacklists[china]="http://www.example.com"       
#blacklists[key]="url" 

iptables -F # Flush iptables chains 
iptables -X # Delete all user created chains 
iptables -P FORWARD DROP # Drop all forwarded traffic 
iptables -N LOGNDROP # Create LOGNDROP chain 
iptables -A LOGNDROP -p tcp -m limit --limit 5/min -j LOG --log-prefix "Denied TCP: " --log-level 7 
iptables -A LOGNDROP -p udp -m limit --limit 5/min -j LOG --log-prefix "Denied UDP: " --log-level 7 
iptables -A LOGNDROP -p icmp -m limit --limit 5/min -j LOG --log-prefix "Denied ICMP: " --log-level 7 
iptables -A LOGNDROP -j DROP # Drop after logging 

# Build first part of iptables-rules 
for key in ${!blacklists[@]}; do 
    iptables -N $key # Create chain for current list 
    iptables -A INPUT -j $key # Link input to current list chain 
done 

iptables-save | sed '$d' | sed '$d' > /tmp/iptables-rules.rules # Save WORKING iptables-rules and remove last 2 liens (COMMIT & comment) 

for key in ${!blacklists[@]}; do 
    #Download blacklist 
    wget --output-document=/tmp/blacklist_$key.gz -w 3 ${blacklists[$key]} 
    zcat /tmp/blacklist_$key.gz | sed '1,2d' | sed s/.*:/-A\ $key\ -m\ iprange\ --src-range\/| sed s/$/\ -j\ LOGNDROP/ >> iptables-rules.rules 
done 
echo 'COMMIT' >> /tmp/iptables-rules.rules 
iptables-restore < /tmp/iptables-rules.rules 
# Delete files 
rm /tmp/blacklist* 
rm /tmp/iptables-rules.rules 
exit 0 

這個偉大工程的試驗檯最名單但也有具體的名單,如果包括將產生的iptables-恢復:行389971失敗錯誤,這總是l ast行(COMMIT)。我讀過,由於iptables的工作方式,每當有問題重新加載規則時,錯誤總是會說最後一行失敗。

真正奇怪的是,在Ubuntu桌面14.04 64位上測試這些相同的列表第二個腳本工作得很好。我曾嘗試在臺式機上運行腳本,然後使用iptables-save保存規則集的「正確」格式化版本,然後使用iptables-restore將該文件加載到服務器上的iptables中,並且仍然收到該錯誤。

我不知道如何解決這個問題,爲什麼初始腳本需要這麼長時間才能將規則添加到iptables中,並且可能會導致第二個腳本中的列表出現問題。

+0

要麼添加一個'echo啓動cmd iptables ....; iptables ...;在你的第一個代碼的內部循環中回聲完成cmd iptables ...或使用'set -vx'來直觀地確認延遲的位置。我可以看到,鑑於您似乎擁有的規則大小,運行所有這些命令可能需要一段時間。對你的第二個想法無能爲力,但考慮到它的速度非常快,試圖解決這個問題是有道理的。鑑於問題空間的SA特性,您可以考慮標記您的問題並將其移至'http:// serverfault.com'。祝你好運。 – shellter

+0

我以前添加了一個回顯來顯示循環當前正在添加的規則,唯一的延遲似乎是這些命令可以運行的速度。 我剛剛運行FRESH 14.04.1 Ubuntu Server 32位安裝的虛擬機上的第二個腳本,它工作得很好。 這使我更新物理測試機器上的所有軟件包,然後重試,仍然失敗! – Seis

+0

嗯。好的,所以你確定慢機的硬盤沒有壞扇區,或者其他問題會導致這種情況?兩臺機器上是否都有相同的磁盤空間?兩臺機器上的RAM配置文件相同? 「擦洗」測試是否顯示磁盤或內存中的任何缺陷?最後,您可以在該機器上添加一個額外的磁盤,或只是將它與一個已知的好磁盤交換出來?似乎你會想到這一切。 +1堅持和耐心!祝你好運! – shellter

回答

1

如果您需要阻止多個IP地址,請改爲使用ipset

步驟1:創建IPSET:

# Adjust the hashsize so that it's roughly 4 x (possible number of addresses to block) 
ipset create BlockAddress hash:ip hashsize 4096 

步驟2:中的地址添加到塊成IPSET:

# Put this in a loop, the loop reading a file containing list of addresses to block 
ipset add BlockAddress $IP_TO_BLOCK 

最後,更換所有這些行以只是一個到框line in netfilter:

iptables -t raw -A PREROUTING -m set --match-set BlockAddress src -j DROP 

完成。 iptables-restore將會很快。

重要提示:強烈建議不要使用域名被添加到網絡過濾; netfilter需要先執行DNS解析,並且如果DNS配置不正確和/或速度太慢,則會失敗。而是對域名進行預先解析(或定期解析)以阻止,並將找到的IP地址提供給「包含要阻止的地址列表的文件」。它應該是一個簡單的腳本,每5分鐘左右從crontab中調用。


編輯1:

這是一個cronjob我用得到facebook.com的地址的例子,每5分鐘調用:

#!/bin/bash 
fbookfile=/etc/iptables.d/facebook.ip 
for d in www.facebook.com m.facebook.com facebook.com; do 
    dig +short "$d" >> "$fbookfile" 
done 
sort -n -u "$fbookfile" -o "$fbookfile" 

每半小時,另一個cronjob將這些地址提供給ipset

#!/bin/bash 
ipset flush IP_Fbook 
while read ip; do 
    ipset add IP_Fbook "$ip" 
done < /etc/iptables.d/facebook.ip 

注意:我必須這樣做,因爲做dig +short facebook.com,例如,返回只是一個的IP地址。經過一番觀察,返回的IP地址每5分鐘更換一次。由於我也是懶惰被佔用來做一個優化版本,我花了簡單的方法,並每30分鐘做一次刷新/重建,以最大限度地減少CPU峯值。

1

以下是我最終如何使用ipsets解決此問題。

#!/bin/bash 

# Blacklist names & URLs array 
declare -A blacklists 
blacklists[China]="url" 
# blacklists[key]="url" 
# etc... 

for key in ${!blacklists[@]}; do 
    # Download blacklist 
    wget --output-document=/tmp/blacklist_$key.gz -w 3 ${blacklists[$key]} 

    # Create ipset for current blacklist 
    ipset create $key hash:net maxelem 400000 
    # TODO method for determining appropriate maxelem 

    while read line; do 
    # Add addresses from list to ipset 
    ipset add $key $line -quiet 
    done < <(zcat /tmp/blacklist_$key.gz | sed '1,2d' | sed s/.*://) 

    # Add rules to iptables 
    iptables -D INPUT -m set --match-set $key src -j $key # Delete link to list chain from INPUT 
    iptables -F $key # Flush list chain if existed 
    iptables -X $key # Delete list chain if existed 
    iptables -N $key # Create list chain 
    iptables -A $key -p tcp -m limit --limit 5/min -j LOG --log-prefix "Denied $key TCP: " --log-level 7 
    iptables -A $key -p udp -m limit --limit 5/min -j LOG --log-prefix "Denied $key UDP: " --log-level 7 
    iptables -A $key -p icmp -m limit --limit 5/min -j LOG --log-prefix "Denied $key ICMP: " --log-level 7 
    iptables -A $key -j DROP # Drop after logging 
    iptables -A INPUT -m set --match-set $key src -j $key 
done 

我對ipsets並不十分熟悉,但是這使得下載,解析和添加塊的速度更快。

我已經爲每個列表添加了更多詳細日誌記錄的單獨鏈,它將記錄丟棄的ip來自哪個blocklist,如果您有多個日誌記錄。在我的實際框中,我使用了大約10個列表,並添加了幾十萬個地址,沒有任何問題!