close

iptables四個表與五個鏈間的處理關係

netfilter/iptables IP 信息包過濾系統是一種功能強大的工具,可用於添加、編輯和除去規則,這些規則是在做信息包過濾決定時,防火牆所遵循和組成的規則。這些規則存儲在專用的信息包過濾表中,而這些表集成在 Linux 內核中。在信息包過濾表中,規則被分組放在我們所謂的鏈(chain)中。

      雖然 netfilter/iptables IP 信息包過濾系統被稱為單個實體,但它實際上由兩個組件 netfilter 和 iptables 組成。

      netfilter 組件也稱為內核空間(kernelspace),是內核的一部分,由一些信息包過濾表組成,這些表包含內核用來控制信息包過濾處理的規則集。

      iptables 組件是一種工具,也稱為用戶空間(userspace),它使插入、修改和除去信息包過濾表中的規則變得容易。

      iptables包含4個表,5個鏈。其中表是按照對數據包的操作區分的,鏈是按照不同的Hook點來區分的,表和鏈實際上是netfilter的兩個維度。

      4個表:filter,nat,mangle,raw,默認表是filter(沒有指定表的時候就是filter表)。表的處理優先級:raw>mangle>nat>filter。

          filter:一般的過濾功能

          nat:用於nat功能(端口映射,地址映射等)

           mangle:用於對特定數據包的修改

           raw:有限級最高,設置raw時一般是為了不再讓iptables做數據包的鏈接跟蹤處理,提高性能

      5個鏈:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING。

           PREROUTING:數據包進入路由表之前

           INPUT:通過路由表後目的地為本機

           FORWARDING:通過路由表後,目的地不為本機

           OUTPUT:由本機產生,向外轉發

           POSTROUTIONG:發送到網卡接口之前。如下圖:

image001

    iptables中表和鏈的對應關係如下:

繪圖1.vsd     

數據包在netfilter中的傳遞流程:

1)  什麼是raw表?做什麼用的?

iptables有5個鏈:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING,4個表:filter,nat,mangle,raw.

4個表的優先級由高到低的順序為:raw-->mangle-->nat-->filter

舉例來說:如果PRROUTING鏈上,即有mangle表,也有nat表,那麼先由mangle處理,然後由nat表處理

RAW表只使用在PREROUTING鏈和OUTPUT鏈上,因為優先級最高,從而可以對收到的數據包在連接跟蹤前進行處理。一但用戶使用了RAW表,在某個鏈上,RAW表處理完後,將跳過NAT表和 ip_conntrack處理,即不再做地址轉換和數據包的鏈接跟蹤處理了.

RAW表可以應用在那些不需要做nat的情況下,以提高性能。如大量訪問的web服務器,可以讓80端口不再讓iptables做數據包的鏈接跟蹤處理,以提高用戶的訪問速度。

2)  iptables的數據包的流程是怎樣的?

一個數據包到達時,是怎麼依次穿過各個鏈和表的 :

基本步驟如下: 
1. 數據包到達網絡接口,比如 eth0。 
2. 進入 raw 表的 PREROUTING 鏈,這個鏈的作用是趕在連接跟蹤之前處理數據包。 
3. 如果進行了連接跟蹤,在此處理。 
4. 進入 mangle 表的 PREROUTING 鏈,在此可以修改數據包,比如 TOS 等。 
5. 進入 nat 表的 PREROUTING 鏈,可以在此做DNAT,但不要做過濾。 
6. 決定路由,看是交給本地主機還是轉發給其它主機。 

到了這裡我們就得分兩種不同的情況進行討論了,一種情況就是數據包要轉發給其它主機,這時候它會依次經過: 
7. 進入 mangle 表的 FORWARD 鏈,這裡也比較特殊,這是在第一次路由決定之後,在進行最後的路由決定之前,我們仍然可以對數據包進行某些修改。 
8. 進入 filter 表的 FORWARD 鏈,在這裡我們可以對所有轉發的數據包進行過濾。需要注意的是:經過這裡的數據包是轉發的,方向是雙向的。 
9. 進入 mangle 表的 POSTROUTING 鏈,到這裡已經做完了所有的路由決定,但數據包仍然在本地主機,我們還可以進行某些修改。 
10. 進入 nat 表的 POSTROUTING 鏈,在這裡一般都是用來做 SNAT ,不要在這裡進行過濾。 
11. 進入出去的網絡接口。完畢。 

另一種情況是,數據包就是發給本地主機的,那麼它會依次穿過: 
7. 進入 mangle 表的 INPUT 鏈,這裡是在路由之後,交由本地主機之前,我們也可以進行一些相應的修改。 
8. 進入 filter 表的 INPUT 鏈,在這裡我們可以對流入的所有數據包進行過濾,無論它來自哪個網絡接口。 
9. 交給本地主機的應用程序進行處理。 
10. 處理完畢後進行路由決定,看該往那裡發出。 
11. 進入 raw 表的 OUTPUT 鏈,這裡是在連接跟蹤處理本地的數據包之前。 
12. 連接跟蹤對本地的數據包進行處理。 
13. 進入 mangle 表的 OUTPUT 鏈,在這裡我們可以修改數據包,但不要做過濾。 
14. 進入 nat 表的 OUTPUT 鏈,可以對防火牆自己發出的數據做 NAT 。 
15. 再次進行路由決定。 
16. 進入 filter 表的 OUTPUT 鏈,可以對本地出去的數據包進行過濾。 
17. 進入 mangle 表的 POSTROUTING 鏈,同上一種情況的第9步。注意,這裡不光對經過防火牆的數據包進行處理,還對防火牆自己產生的數據包進行處理。 
18. 進入 nat 表的 POSTROUTING 鏈,同上一種情況的第10步。 
19. 進入出去的網絡接口。完畢。


3)  iptables raw表的使用

增加raw表,在其他表處理之前,-j NOTRACK跳過其它表處理
狀態除了以前的四個還增加了一個UNTRACKED

例如:
可以使用 「NOTRACK」 target 允許規則指定80端口的包不進入鏈接跟蹤/NAT子系統

iptables -t raw -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j NOTRACK
iptables -t raw -A PREROUTING -s 1.2.3.4 -p tcp --sport 80 -j NOTRACK
iptables -A FORWARD -m state --state UNTRACKED -j ACCEPT

4) 解決ip_conntrack: table full, dropping packet的問題


在啟用了iptables web服務器上,流量高的時候經常會出現下面的錯誤:

ip_conntrack: table full, dropping packet


這個問題的原因是由於web服務器收到了大量的連接,在啟用了iptables的情況下,iptables會把所有的連接都做鏈接跟蹤處理,這樣iptables就會有一個鏈接跟蹤表,當這個表滿的時候,就會出現上面的錯誤。

iptables的鏈接跟蹤表最大容量為/proc/sys/net/ipv4/ip_conntrack_max,鏈接碰到各種狀態的超時後就會從表中刪除。

所以解決方法一般有兩個:

(1) 加大 ip_conntrack_max 值

vi /etc/sysctl.conf

net.ipv4.ip_conntrack_max = 393216
net.ipv4.netfilter.ip_conntrack_max = 393216


(2): 降低 ip_conntrack timeout時間

vi /etc/sysctl.conf

net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120


上面兩種方法打個比喻就是燒水水開的時候,換一個大鍋。一般情況下都可以解決問題,但是在極端情況下,還是不夠用,怎麼辦?

這樣就得反其道而行,用釜底抽薪的辦法。iptables的raw表是不做數據包的鏈接跟蹤處理的,我們就把那些連接量非常大的鏈接加入到iptables raw表。

如一台web服務器可以這樣:

iptables -t raw -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j NOTRACK
iptables -A FORWARD -m state --state UNTRACKED -j ACCEPT
 
arrow
arrow

    lyt0112 發表在 痞客邦 留言(0) 人氣()