天天看點

防火牆的工作原理

防火牆就是一種過濾塞(目前你這麼了解不算錯),你可以讓你喜歡的東西通過這個塞子,别的玩意都統統過濾掉。在網絡的世界裡,要由防火牆過濾的就是承載通信資料的通信包。 

  天下的防火牆至少都會說兩個詞:Yes或者No。直接說就是接受或者拒絕。最簡單的防火牆是以太網橋。但幾乎沒有人會認為這種原始防火牆能管多大用。大多數防火牆采用的技術和标準可謂五花八門。這些防火牆的形式多種多樣:有的取代系統上已經裝備的TCP/IP協定棧;有的在已有的協定棧上建立自己的軟體子產品;有的幹脆就是獨立的一套作業系統。還有一些應用型的防火牆隻對特定類型的網絡連接配接提供保護(比如SMTP或者HTTP協定等)。還有一些基于硬體的防火牆産品其實應該歸入安全路由器一類。以上的産品都可以叫做防火牆,因為他們的工作方式都是一樣的:分析出入防火牆的資料包,決定放行還是把他們扔到一邊。 

  所有的防火牆都具有IP位址過濾功能。這項任務要檢查IP標頭,根據其IP源位址和目标位址作出放行/丢棄決定。看看下面這張圖,兩個網段之間隔了一個防火牆,防火牆的一端有台UNIX計算機,另一邊的網段則擺了台PC客戶機。

  當PC客戶機向UNIX計算機發起telnet請求時,PC的telnet客戶程式就産生一個TCP包并把它傳給本地的協定棧準備發送。接下來,協定棧将這個TCP包“塞”到一個IP包裡,然後通過PC機的TCP/IP棧所定義的路徑将它發送給UNIX計算機。在這個例子裡,這個IP包必須經過橫在PC和UNIX計算機中的防火牆才能到達UNIX計算機。 

  現在我們“指令”(用專業術語來說就是配制)防火牆把所有發給UNIX計算機的資料包都給拒了,完成這項工作以後,“心腸”比較好的防火牆還會通知客戶程式一聲呢!既然發向目标的IP資料沒法轉發,那麼隻有和UNIX計算機同在一個網段的使用者才能通路UNIX計算機了。 

  還有一種情況,你可以指令防火牆專給那台可憐的PC機找茬,别人的資料包都讓過就它不行。這正是防火牆最基本的功能:根據IP位址做轉發判斷。但要上了大場面這種小伎倆就玩不轉了,由于黑客們可以采用IP位址欺騙技術,僞裝成合法位址的計算機就可以穿越信任這個位址的防火牆了。不過根據位址的轉發決策機制還是最基本和必需的。另外要注意的一點是,不要用DNS主機名建立過濾表,對DNS的僞造比IP位址欺騙要容易多了。 

  伺服器TCP/UDP 端口過濾 

  僅僅依靠位址進行資料過濾在實際運用中是不可行的,還有個原因就是目标主機上往往運作着多種通信服務,比方說,我們不想讓使用者采用 telnet的方式連到系統,但這絕不等于我們非得同時禁止他們使用SMTP/POP郵件伺服器吧?是以說,在位址之外我們還要對伺服器的TCP/ UDP端口進行過濾。 

  比如,預設的telnet服務連接配接端口号是23。假如我們不許PC客戶機建立對UNIX計算機(在這時我們當它是伺服器)的telnet連接配接,那麼我們隻需指令防火牆檢查發送目标是UNIX伺服器的資料包,把其中具有23目标端口号的包過濾就行了。這樣,我們把IP位址和目标伺服器TCP/UDP端口結合起來不就可以作為過濾标準來實作相當可靠的防火牆了嗎?不,沒這麼簡單。 

  客戶機也有TCP/UDP端口 

  TCP/IP是一種端對端協定,每個網絡節點都具有唯一的位址。網絡節點的應用層也是這樣,處于應用層的每個應用程式和服務都具有自己的對應“位址”,也就是端口号。位址和端口都具備了才能建立客戶機和伺服器的各種應用之間的有效通信聯系。比如,telnet伺服器在端口23偵聽入站連接配接。同時telnet客戶機也有一個端口号,否則客戶機的IP棧怎麼知道某個資料包是屬于哪個應用程式的呢? 

  由于曆史的原因,幾乎所有的TCP/IP客戶程式都使用大于1023的随機配置設定端口号。隻有UNIX計算機上的root使用者才可以通路1024以下的端口,而這些端口還保留為伺服器上的服務所用。是以,除非我們讓所有具有大于1023端口号的資料包進入網絡,否則各種網絡連接配接都沒法正常工作。 

  這對防火牆而言可就麻煩了,如果阻塞入站的全部端口,那麼所有的客戶機都沒法使用網絡資源。因為伺服器發出響應外部連接配接請求的入站(就是進入防火牆的意思)資料包都沒法經過防火牆的入站過濾。反過來,打開所有高于1023的端口就可行了嗎?也不盡然。由于很多服務使用的端口都大于1023,比如X client、基于RPC的NFS服務以及為數衆多的非UNIX IP産品等(NetWare/IP)就是這樣的。那麼讓達到1023端口标準的資料包都進入網絡的話網絡還能說是安全的嗎?連這些客戶程式都不敢說自己是足夠安全的。 

  雙向過濾 

  OK,咱們換個思路。我們給防火牆這樣下指令:已知服務的資料包可以進來,其他的全部擋在防火牆之外。比如,如果你知道使用者要通路Web伺服器,那就隻讓具有源端口号80的資料包進入網絡: 

  不過新問題又出現了。首先,你怎麼知道你要通路的伺服器具有哪些正在運作的端口号呢? 象HTTP這樣的伺服器本來就是可以任意配置的,所采用的端口也可以随意配置。如果你這樣設定防火牆,你就沒法通路哪些沒采用标準端口号的的網絡站點了!反過來,你也沒法保證進入網絡的資料包中具有端口号80的就一定來自Web伺服器。有些黑客就是利用這一點制作自己的入侵工具,并讓其運作在本機的80端口! 

  檢查ACK位 

  源位址我們不相信,源端口也信不得了,這個不得不與黑客共舞的瘋狂世界上還有什麼值得我們信任呢?還好,事情還沒到走投無路的地步。對策還是有的,不過這個辦法隻能用于TCP協定。 

  TCP是一種可靠的通信協定,“可靠”這個詞意味着協定具有包括糾錯機制在内的一些特殊性質。為了實作其可靠性,每個TCP連接配接都要先經過一個“握手”過程來交換連接配接參數。還有,每個發送出去的包在後續的其他包被發送出去之前必須獲得一個确認響應。但并不是對每個TCP包都非要采用專門的ACK包來響應,實際上僅僅在TCP標頭上設定一個專門的位就可以完成這個功能了。是以,隻要産生了響應包就要設定ACK位。連接配接會話的第一個包不用于确認,是以它就沒有設定ACK位,後續會話交換的TCP包就要設定ACK位了。

  舉個例子,PC向遠端的Web伺服器發起一個連接配接,它生成一個沒有設定ACK位的連接配接請求包。當伺服器響應該請求時,伺服器就發回一個設定了ACK位的資料包,同時在包裡标記從客戶機所收到的位元組數。然後客戶機就用自己的響應包再響應該資料包,這個資料包也設定了ACK位并标記了從伺服器收到的位元組數。通過監視ACK位,我們就可以将進入網絡的資料限制在響應包的範圍之内。于是,遠端系統根本無法發起TCP連接配接但卻能響應收到的資料包了。 

  這套機制還不能算是無懈可擊,簡單地舉個例子,假設我們有台内部Web伺服器,那麼端口80就不得不被打開以便外部請求可以進入網絡。還有,對UDP包而言就沒法監視ACK位了,因為UDP包壓根就沒有ACK位。還有一些TCP應用程式,比如FTP,連接配接就必須由這些伺服器程式自己發起。 

  FTP帶來的困難 

  一般的Internet服務對所有的通信都隻使用一對端口号,FTP程式在連接配接期間則使用兩對端口号。第一對端口号用于FTP的“指令通道”提供登入和執行指令的通信鍊路,而另一對端口号則用于FTP的“資料通道”提供客戶機和伺服器之間的檔案傳送。 

  在通常的FTP會話過程中,客戶機首先向伺服器的端口21(指令通道)發送一個TCP連接配接請求,然後執行LOGIN、DIR等各種指令。一旦使用者請求伺服器發送資料,FTP伺服器就用其20端口 (資料通道)向客戶的資料端口發起連接配接。問題來了,如果伺服器向客戶機發起傳送資料的連接配接,那麼它就會發送沒有設定ACK位的資料包,防火牆則按照剛才的規則拒絕該資料包同時也就意味着資料傳送沒戲了。通常隻有進階的、也就是夠聰明的防火牆才能看出客戶機剛才告訴伺服器的端口,然後才許可對該端口的入站連接配接。 

  UDP端口過濾 

  好了,現在我們回過頭來看看怎麼解決UDP問題。剛才說了,UDP包沒有ACK位是以不能進行ACK位過濾。UDP 是發出去不管的“不可靠”通信,這種類型的服務通常用于廣播、路由、多媒體等廣播形式的通信任務。NFS、DNS、WINS、NetBIOS-over-TCP/IP和 NetWare/IP都使用UDP。 

  看來最簡單的可行辦法就是不允許建立入站UDP連接配接。防火牆設定為隻許轉發來自内部接口的UDP包,來自外部接口的UDP包則不轉發。現在的問題是,比方說,DNS名稱解析請求就使用UDP,如果你提供DNS服務,至少得允許一些内部請求穿越防火牆。還有IRC這樣的客戶程式也使用UDP,如果要讓你的使用者使用它,就同樣要讓他們的UDP包進入網絡。我們能做的就是對那些從本地到可信任站點之間的連接配接進行限制。但是,什麼叫可信任!如果黑客采取位址欺騙的方法不又回到老路上去了嗎? 

  有些新型路由器可以通過“記憶”出站UDP包來解決這個問題:如果入站UDP包比對最近出站UDP包的目标位址和端口号就讓它進來。如果在記憶體中找不到比對的UDP包就隻好拒絕它了!但是,我們如何确信産生資料包的外部主機就是内部客戶機希望通信的伺服器呢?如果黑客詐稱DNS伺服器的位址,那麼他在理論上當然可以從附着DNS的UDP端口發起攻擊。隻要你允許DNS查詢和回報包進入網絡這個問題就必然存在。辦法是采用代理伺服器。 

  所謂代理伺服器,顧名思義就是代表你的網絡和外界打交道的伺服器。代理伺服器不允許存在任何網絡内外的直接連接配接。它本身就提供公共和專用的DNS、郵件伺服器等多種功能。代理伺服器重寫資料包而不是簡單地将其轉發了事。給人的感覺就是網絡内部的主機都站在了網絡的邊緣,但實際上他們都躲在代理的後面,露面的不過是代理這個假面具。 

  小結 

  IP位址可能是假的,這是由于IP協定的源路有機制所帶來的,這種機制告訴路由器不要為資料包采用正常的路徑,而是按照標頭内的路徑傳送資料包。于是黑客就可以使用系統的IP位址獲得傳回的資料包。有些進階防火牆可以讓使用者禁止源路由。通常我們的網絡都通過一條路徑連接配接ISP,然後再進入Internet。這時禁用源路由就會迫使資料包必須沿着正常的路徑傳回。 

  還有,我們需要了解防火牆在拒絕資料包的時候還做了哪些其他工作。比如,防火牆是否向連接配接發起系統發回了“主機不可到達”的ICMP消息?或者防火牆真沒再做其他事?這些問題都可能存在安全隐患。ICMP“主機不可達”消息會告訴黑客“防火牆專門阻塞了某些端口”,黑客立即就可以從這個消息中聞到一點什麼氣味。如果ICMP“主機不可達”是通信中發生的錯誤,那麼老實的系統可能就真的什麼也不發送了。反過來,什麼響應都沒有卻會使發起通信的系統不斷地嘗試建立連接配接直到應用程式或者協定棧逾時,結果最終使用者隻能得到一個錯誤資訊。當然這種方式會讓黑客無法判斷某端口到底是關閉了還是沒有使用。

繼續閱讀