動態 iptables 防火牆(轉)

post0發表於2007-08-10
動態 iptables 防火牆(轉)[@more@]

內容:

響應攻擊

ipdrop

ipdrop:說明

tcplimit

host-tcplimit

user-outblock

參考資料

關於作者

靈活(有趣)的網路安全性

Daniel Robbins (drobbins@gentoo.org)

總裁兼 CEO,Gentoo Technologies, Inc.

2001 年 4 月

防火牆非常有趣,但在需要對防火牆規則進行快速且複雜的更改時,您會做些什麼?很簡單。請使用本文中演示的 Daniel Robbins 的動態防火牆指令碼。可以使用這些指令碼來增加網路安全性和響應性,並激發您自己的創造性設計。

瞭解動態防火牆指令碼好處的最佳方法是在執行時檢視它們。要這樣做,讓我們假設我是一家 ISP 的系統管理員,最近我建立了基於 Linux 的防火牆,用於保護我的客戶和內部系統免遭因特網上惡意使用者的攻擊。為了實現這個目的,我的防火牆使用新的 Linux 2.4 iptables 有狀態功能,以允許我的客戶和伺服器建立新的外出連線,當然還允許新的進入連線,但僅限於“公共”服務,如 web、ftp、ssh 和 SMTP。由於我使用了預設拒絕設計,因此會自動拒絕任何從因特網到非公共服務(如 squid 代理快取或 Samba 伺服器)的連線。現在,我有一個非常不錯的防火牆,它為我公司的所有客戶提供了非常好的保護。

在第一個星期左右,防火牆的工作非常出色,但在這之後卻發生了件討厭的事:我最大的對手 Bob(他為另一家 ISP 工作,是我們的競爭對手)決定用大量資訊包攻擊我的網路,試圖阻止我向客戶提供服務。糟糕的是,Bob 已經仔細研究了我的防火牆,他知道我在保護內部服務時,埠 25 和 80 必定是可以公開訪問的,這樣我才可以接收郵件和響應 HTTP 請求。Bob 決定利用這一點,他想用吸乾頻寬的方法來攻擊我的 Web 和郵件伺服器。

大約在 Bob 實施攻擊一分鐘之後,我注意到資訊包逐漸佔滿了上行鏈路。在檢視了 tcpdump 的情況之後,我確定這還是 Bob 實施的另一次攻擊,我推算出他用於發起攻擊的 IP 地址。現在我已經有了這個資訊,我需要做的就是阻止這些 IP 地址,我想這大概能解決問題 -- 很簡單的解決方案。

響應攻擊

我迅速使用 vi 開啟防火牆設定指令碼,並開始改動 iptables 規則、修改防火牆,這樣它就可以阻止那些 Bob 發出的惡意進入資訊包。大約一分鐘左右,我找到了新增合適 DROP 規則的確切位置,並新增了這些規則。然後,我啟動防火牆,但又馬上停止了它……哎,我在新增規則時犯了一個小錯。我再次裝入防火牆指令碼,改正問題,30 秒之後,將已將防火牆調整成阻止這個月內 Bob 發起的所有攻擊。起先,它似乎成功地挫敗了攻擊……直到問訊臺的電話鈴聲響起。顯然,Bob 已經中斷我的網路大約 10 分鐘,現在我的客戶打電話來詢問究竟發生了什麼情況。更遭的是,幾分鐘後,我發現上行鏈路又被佔滿了。看來 Bob 這次使用了一組全新的 IP 地址來實施攻擊。我也做出響應,立即開始修改防火牆指令碼,只不過這次我有一點驚慌 -- 也許我的解決方案還不那麼完美。

以下就是上述情況中出錯的原因。雖然我有一個不錯的防火牆,還迅速標識了網路問題的原因,但我無法修改防火牆的行為以使它能夠及時應付威脅。當然,當網路受到攻擊時,您希望能夠立即響應,在緊急狀態下被迫修改主防火牆設定指令碼不僅在時間上很緊迫,而且效率非常低。

ipdrop

如果有一個特別設計的特殊 "ipdrop" 指令碼,它可以插入阻止我指定的 IP 地址所需的規則,那麼情況會好多了。有了這樣的指令碼,阻止防火牆就不再是兩分鐘的折磨;它只需 5 秒鐘。由於這個指令碼可以讓我不必手工編輯防火牆規則,這就消除了出錯的主要根源。我所要做的只是確定要阻止的 IP 地址,然後輸入:

# ipdrop 129.24.8.1 on

IP 129.24.8.1 drop on.

ipdrop 指令碼會立即阻止 129.24.8.1,這是本週 Bob 的當前惡意 IP 地址。這個指令碼明顯提高了您的防禦能力,因為現在阻止 IP 並不是件費神的事。現在,讓我們看一下 ipdrop 指令碼的實現:

ipdrop bash 指令碼

#!/bin/bash

source /usr/local/share/dynfw.sh

args 2 $# "${0} IPADDR {on/off}" "Drops packets to/from IPADDR. Good for obnoxious

networks/hosts/DoS"

if [ "$2" == "on" ]

then

#rules will be appended or inserted as normal

APPEND="-A"

INSERT="-I"

rec_check ipdrop $1 "$1 already blocked" on

record ipdrop $1

elif [ "$2" == "off" ]

then

#rules will be deleted instead

APPEND="-D"

INSERT="-D"

rec_check ipdrop $1 "$1 not currently blocked" off

unrecord ipdrop $1

else

echo "Error: "off" or "on" expected as second argument"

exit 1

fi

#block outside IP address thats causing problems

#attackers incoming TCP connections will take a minute or so to time out,

#reducing DoS effectiveness.

iptables $INSERT INPUT -s $1 -j DROP

iptables $INSERT OUTPUT -d $1 -j DROP

iptables $INSERT FORWARD -d $1 -j DROP

iptables $INSERT FORWARD -s $1 -j DROP

echo "IP ${1} drop ${2}."

ipdrop:說明

如果留意最後突出顯示的四行,您會看到將適當規則插入防火牆表的真正命令。可以看到,$INSERT 環境變數的定義隨著執行方式是 "on" 還是 "off" 而變化。iptables 行執行時,會適當插入或刪除特定規則。

現在,讓我們看一下規則本身的功能,規則應該與任何型別的現有防火牆或甚至在沒有防火牆的系統上正常工作;您所需要的只是 2.4 核心中的內建 iptables 支援。我們阻止來自惡意 IP(第一個以 iptables 開頭的行)的進入資訊包,阻止標題為惡意 IP(下一個以 iptables 開頭的行)的外出資訊包,然後關閉涉及這個特殊 IP(最後兩個以 iptables 開頭的行)的轉發。一旦這些規則就位,系統就只廢棄任何屬於其中一個類別的資訊包。

另一個簡短註釋:您還會注意到對 "rec_check"、"unrecord"、"record" 和 "args" 的呼叫。這些是在 "dynfw.sh" 中定義的 helper bash 函式。"record" 函式將被阻止的 IP 記錄到 /root/.dynfw-ipdrop 檔案中,而 "unrecord" 從 /root/.dynfw-ipdrop 中除去記錄項。如果要重新阻止一個已被阻止的 IP,或者取消阻止當前未阻止的 IP,可以使用 "rec_check" 函式來放棄帶錯誤訊息的指令碼。"args" 函式負責確保我們接收到正確數量的命令列自變數,它還負責列印有幫助的用法資訊。我已經建立了包含所有這些工具的 dynfw-1.0.tar.gz;有關詳細資訊,請參閱本文結尾的參考資料部分。

tcplimit

如果需要限制使用某個特定基於 TCP 的網路服務,可能是某些會在終端上產生大量 CPU 負載的服務,那麼下一個動態防火牆指令碼會非常有用。這個指令碼稱作 "tcplimit",它使用一個 TCP 埠、一個速率、一個比例和 "on" 或 "off" 作為自變數:

# tcplimit 873 5 minute on

Port 873 new connection limit (5/minute, burst=5) on.

tcplimit 使用新的 iptables "state" 模組(確保已經在核心中啟用了這個模組或已經裝入了這個模組),以在某個特定時間週期內只允許一定數量的新進入連線。在本示例中,防火牆只允許每分鐘有 5 個新連線到 rsync 伺服器(埠 873) -- 如有必要,可以指定您希望每秒/分鐘/小時或每天有多少連線。

tcplimit 為限制非基本服務提供了一個好方法 -- 因此對非基本服務的大量通訊量不會中斷網路或伺服器。在我遇到的情況中,我使用 tcplimit 來設定使用 rsync 的最大上限,以防止太多 rsync 連線佔據我的 DSL 線路。限制了連線的服務都記錄在 /root/.dynfw-tcplimit 中,如果我要關閉新連線限制,只要輸入:

# tcplimit 873 5 minute off

Port 873 new connection limit off.

tcplimit 執行時會在 "filter" 表中建立一個全新的鏈。這個新的鏈將拒絕所有超出指定限度的資訊包。然後,一個規則將插入 INPUT 鏈,該 INPUT 鏈將要傳送到目標埠(本例中是 873)的所有進入 NEW 連線資訊包重定向到這個特定鏈,這樣便有效地限制了新的進入連線,但又不會影響所建立連線中的資訊包。

關閉 tcplimit 時,INPUT 規則和該特定鏈將被刪除。這是件奇妙的事,它真正體現了讓經過精心測試的、可靠的指令碼來為您管理防火牆規則的重要性。由於使用了 ipblock,tcplimit 指令碼將與任何型別的防火牆,甚至沒有防火牆的系統相容,只要您在核心中啟用了正確的 iptables 功能。

host-tcplimit

host-tcplimit 非常類似於 tcplimit,但它限制某些新的 TCP 連線,這些連線來自某個特定 IP 地址並且指向您的伺服器上某個特定 TCP 埠。host-tcplimit 特別適用於防止某個人濫用您的網路資源。例如,假設您在執行 CVS 伺服器,而您發現某個新的開發人員似乎建立了一個指令碼來每隔 10 分鐘就用資源庫更新它的原始碼,這樣每天就消耗了大量的多餘網路資源。然而,當您給他傳送電子郵件以指出他的錯誤行為時,卻會收到一條進入訊息,全文如下:

嗨,夥計!

我很榮幸能參與您的開發專案。我剛建立了一個指令碼,

用來每隔 10 分鐘更新一次程式碼的本地副本。我將出去

旅遊兩個星期,但等到回來之後,我將會得到最新的源

程式碼,那時我就可以交差了!現在我要出門了……兩週

後再見!

謹啟,

Newbie(新手)

對於這種情況,一個簡單的 host-tcplimit 命令就可以解決問題:

# host-tcplimit 1.1.1.1 2401 1 day on

現在,限定了 Newbie 先生(IP 地址 1.1.1.1)每天只能有一個 CVS 連線(埠 2401),這樣就節省了許多網路頻寬。

user-outblock

最後一個,也可能是所有動態防火牆指令碼中最有趣的一個就是 user-outblock。這個指令碼提供了一種理想的方式,它允許特定使用者 telnet 或 ssh 到您的系統中,但不允許這個使用者從命令列建立任何新的外出連線。以下的示例適合於使用 user-outblock。假設有一個特殊家庭在我的 ISP 擁有帳戶。父母使用圖形電子郵件客戶機來閱讀他們的郵件,偶爾也會在網上衝浪,但他們的兒子恰巧是位狂熱的駭客,他經常使用 shell 訪問來對他人的計算機搞一些惡作劇。

一天,您發現他與一些系統建立了 ssh 連線,而那些系統似乎屬於巴基斯坦武裝力量 -- 啊,天哪!您想要引導這個年輕人參加更有益的活動,所以應執行以下操作:

首先,應檢查系統,確保已除去了所有網路二進位制程式(如 ssh)中的 suid 位:

# chmod u-s /usr/bin/ssh

現在,他試圖用來與網路互動的任何程式都屬於他自己的使用者標識。現在您可以使用 user-outblock 阻止這個使用者標識(恰巧是 2049)啟動的所有外出 TCP 連線:

# user-outblock 2049 on

UID 2049 block on.

現在,他可以登入和閱讀郵件,但不能使用您的伺服器來建立 ssh 連線以及類似連線。現在,他可以在自己家的個人計算機上安裝 ssh 客戶機。然而,如果要限制他家的個人電腦到 Web、郵件和外出 ssh 連線(僅限於到您的伺服器),建立這樣的動態防火牆指令碼也不太難。

參考資料

由於我發現這些動態防火牆指令碼如此實用,我已經建立了一個小巧的 tarball (dynfw-1.0.tar.gz) 檔案,您可以將它下載並安裝到您的機器上。

如果要安裝,解開 tarball,執行其中的 install.sh 指令碼。此指令碼將一個共享的 bash 指令碼安裝到 /usr/local/share/dynfw.sh 中,並將動態防火牆指令碼安裝到 /usr/local/sbin。如果希望將它們安裝到 /usr/share 和 /usr/sbin 中,在執行 install.sh 之前只要輸入以下命令:

# export PREFIX=/usr

我還將動態防火牆指令碼程式碼部分新增到 Gentoo Linux 網站上,您可以訪問這個網站以獲取最新版本的 tar 檔案。我還要繼續改進,並新增到這個集合中,以使全世界的系統管理員可以使用真正實用的資源。在我們的核心中已經有了 iptables,應該開始利用它!

tcpdump 是研究低階資訊包交換和驗證防火牆是否正常工作的必備工具。如果您還沒有,想方法弄到它。如果已經有了,則應該使用它。如果已經使用它了……幹得好!:)

netfilter 小組的主頁上有許多優秀的資源,包括 iptables 原始碼,有 Rusty 的優秀作品 "unreliable guides"。這些作品包括基本網路概念 HOWTO、netfilter (iptables) HOWTO、NAT HOWTO 和適合於開發人員的 netfilter 修改 HOWTO。該網站上還有 netfilter 常見問題解答以及其它內容。

網上還有許多好的 netfilter 資源;但是,不要忘了基礎知識。iptables man 頁面非常詳細,並且它是 man 頁面的範例。

現在可以使用高階 Linux 路由和流量控制 HOWTO。它很好地顯示瞭如何使用 iptables 來標記資訊包,然後根據這些標記來使用 Linux 路由功能傳送資訊包。

可以使用 netfilter (iptables) 郵件列表,而且有一個適用於 netfilter 開發人員。使用這些 URL 還可以訪問郵件列表檔案。

關於作者

Daniel Robbins 居住在新墨西哥州的 Albuquerque。他是 Gentoo Technologies, Inc. 的總裁兼 CEO,Gentoo Linux(用於 PC 的高階 Linux)和 Portage 系統(Linux 的下一代移植系統)的創始人。他還是 Macmillan 書籍 Caldera OpenLinux Unleashed、SuSE Linux Unleashed 和 Samba Unleashed 的合作者。Daniel 自二年級起就與計算機結下不解之緣,那時他首先接觸的是 Logo 程式語言,並沉溺於 Pac-Man 遊戲中。這也許就是他至今仍擔任 SONY Electronic Publishing/Psygnosis 的首席圖形設計師的原因所在。Daniel 喜歡與妻子 Mary 和新出生的女兒 Hadassah 一起共度時光。可透過 drobbins@gentoo.org 與 Daniel 聯絡

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-940692/,如需轉載,請註明出處,否則將追究法律責任。

相關文章