防火墻的工作原理
“黑客會打上我的主意嗎?”這么想就對了,黑客就想鉆雞蛋縫的蒼蠅一樣,看到一絲從系統漏洞發出的光亮就會蠢蠢欲動!好,如何保護你的網絡呢?計算機的高手們也許一張嘴就提議你安裝網絡的防火墻,那么第一個問題就來了:到底什么是防火墻呢?
什么是防火墻?
防火墻就是一種過濾塞(目前你這么理解不算錯),你可以讓你喜歡的東西通過這個塞子,別的玩意都統統過濾掉。在網絡的世界里,要由防火墻過濾的就是承載通信數據的通信包。
天下的防火墻至少都會說兩個詞: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“主機不可達”是通信中發生的錯誤,那么老實的系統可能就真的什么也不發送了。反過來,什么響應都沒有卻會使發起通信的系統不斷地嘗試建立連接直到應用程序或者協議棧超時,結果最終用戶只能得到一個錯誤信息。當然這種方式會讓黑客無法判斷某端口到底是關閉了還是沒有使用。
評論
查看更多