一、狀態監測應該如何工作
無論何時,一個防火牆接收到一個初始化TCP連接的SYN包,這個帶有SYN的數據包被防火牆的規則庫檢查。該包在規則庫裡依次序比較。如果在檢查了所有的規則後,該包都沒有被接受,那麼拒絕該次連接。一個RST的數據包發送到遠端的機器。如果該包被接受,那麼本次會話被記錄到狀態監測表裡。該表是位於內核模式中的。隨後的數據包(沒有帶有一個SYN標志)就和該狀態監測表的內容進行比較。如果會話是在狀態表內,而且該數據包是會話的一部分,該數據包被接受。如果不是會話的一部分,該數據包被丟棄。這種方式提高了系統的性能,因為每一個數據包不是和規則庫比較,而是和狀態監測表比較。只有在SYN的數據包到來時才和規則庫比較。所有的數據包與狀態檢測表的比較都在內核模式下進行所以應該很快。
二、狀態監測表建立?
那麼初始化一個連接時使用ACK行不行?它又會出現什麼問題呢?
如果防火牆的狀態檢測表使用ACK來建立會話,將會是不正確的。
如果一個包不在狀態檢測表中時,那麼該包使用規則庫來檢查,而不考慮它是否是SYN、ACK或其他的什麼包。如果規則庫通過了這個數據包,本次會話被添加狀態檢測表中。所有後續的包都會和狀態檢測表比較而被通過。因為在狀態監測表中有入口,後續的數據包就沒有進行規則檢查。而且我們在做狀態監測表項時,也需要考慮時間溢出的問題。使用這種方法,一些簡單的DOS攻擊將會非常有效地摧毀防火牆系統。
那麼狀態檢測表建立應該怎麼進行呢?
首先,對於一個會話我們使用什麼來區分。從最簡單的角度出發,我們可以使用源地址、目的地址和端口號來區分是否是一個會話。
當通過使用一個SYN包來建立一個會話時,防火牆先將這個數據包和規則庫進行比較。如果通過了這個數據連接請求,它被添加到狀態檢測表裡。這時需要設置一個時間溢出值,參考CHECK-POINT FW-1的時間值,將其值設定為60秒。然後防火牆期待一個返回的確認連接的數據包,當接收到如此的包的時候,防火牆將連接的時間溢出值設定為3600秒。對於返回的連接請求的數據包的類型需要做出判斷,已確認其含有SYN/ACK標志。(注:對於時間溢出值,應該可以由用戶自行設定。)
在進行狀態監測時,對於一個會話的確認可以只通過使用源地址、目的地址和端口號來區分,在性能設計上如果能滿足要求,也應該考慮對於TCP連接的序列號的維護,雖然這樣可能需要消耗比較多的資源
三、連接的關閉
在連接被通訊雙方關閉後,狀態監測表中的連接應該被維護一段時間。
下面的處理方法可以作為在連接關閉後狀態檢測行為的參考。
當狀態監測模塊監測到一個FIN或一個RST包的時候,減少時間溢出值從我們缺省設定的值3600秒減少到50秒。如果在這個周期內沒有數據包交換,這個狀態檢測表項將會被刪除,如果有數據包交換,這個周期會被重新設置到50秒。如果繼續通訊,這個連接狀態會被繼續地以50秒的周期維持下去。這種設計方式可以避免一些DOS攻擊,例如,一些人有意地發送一些FIN或RST包來試圖阻斷這些連接。
四、UDP的連接維護
雖然UDP連接是無狀態的,但是仍然可以用類似的方法來維護這些連接。當一個完成規則檢查的數據包通過防火牆時,這次會話被添加到狀態檢測表內,並設置一個時間溢出值,任何一個在這個時間值內返回的包都會被允許通過,當然它的SRC/DST的IP地址和SRC/DST的端口號是必須匹配的。
五、ICMP的狀態檢測問題
對於一些ICMP包的分析,在許多防火牆系統中都是做的很不夠的,在對做狀態檢測時是需要對ICMP的內容進行分析的。對於什麼樣的ICMP可以發出和放入在狀態監測模塊中如何確定是關鍵。
六、IP分幀的問題
在路由時,如果IP數據包的內容大於MTU的大小,數據包將會被分幀,被分成幾個更小的IP數據包。雖然分幀沒有直接地應用於狀態檢測表,但是它仍然是非常重要的。
那麼是否在截獲數據包後,發向系統的TCP/IP協議站之前,對收到的分幀後的數據包進行組裝呢?
在大多數情況下,作為一個狀態檢測防火牆,對於一些類型的分幀的IP數據包進行重組是需要的。防火牆都監測TCP的頭部信息作為對一次會話的監測。然而,在所有被分幀後的IP數據包中只有第一個分幀包含了完整的信息,其他分幀只有IP地址信息。如果一些分幀沒有被重組,那麼狀態監測模塊將沒有辦法識別後續的分幀的數據包是否屬於一個會話的一部分。通過重組,防火牆的狀態檢測模塊就能識別整個的被分幀的數據包。
然而,如果是重組完成後才對數據包進行檢查,那麼防火牆對於使用分幀攻擊(使用不完整的或者是非法的)就表現出很大的弱點。因為它們可能根本不會被重組完成。當然它們也不會被日志記錄下來。防火牆系統很快就會由於試圖繼續重組這些根本不可能完成的數據包,而將系統的資源耗盡。那麼對於如果需要實現分幀重組,那就必須采用十分好的重組方式。對於具體應用來說,過小的分幀包應該被丟棄。