用iptables的raw表解決ip_conntrack: table full, dropping packet的問題

來源:互聯網
上載者:User

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的資料包的流程是怎樣的?

(流程介紹來源:http://selboo.com.cn/post/721/)
一個資料包到達時,是怎麼依次穿過各個鏈和表的(圖)。

基本步驟如下:
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

5) iptables raw表的效果測試

我們在一台web server上做測試,先不使用raw表,觀察連結跟蹤表(/proc/net/ip_conntrack)的大小:

先看下iptables配置:
cat /etc/sysconfig/iptables

# Generated by iptables-save v1.3.5 on Wed Aug 18 10:10:52 2010
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [104076:12500201]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p esp -j ACCEPT
-A RH-Firewall-1-INPUT -p ah -j ACCEPT
-A RH-Firewall-1-INPUT -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Wed Aug 18 10:10:52 2010

在另一台機器上用ab測試:

ab -c 1000 -n 5000 http://192.168.20.26/index.html

在web server上查看連結跟蹤表(/proc/net/ip_conntrack)的大小:

[root@mongo html]# wc -l /proc/net/ip_conntrack
5153 /proc/net/ip_conntrack

可以看到跟蹤表內有5153個連結,再大一些的壓力可能就要報ip_conntrack: table full, dropping packet的錯誤了。

下面我們啟用raw表:

先更新iptables:

[root@mongo html]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.3.5 on Wed Aug 18 10:10:52 2010
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [104076:12500201]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p esp -j ACCEPT
-A RH-Firewall-1-INPUT -p ah -j ACCEPT
-A RH-Firewall-1-INPUT -d 224.0.0.251 -p udp -m udp --dport 5353 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED,UNTRACKED -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Wed Aug 18 10:10:52 2010
# Generated by iptables-save v1.3.5 on Wed Aug 18 10:10:52 2010
*raw
:PREROUTING ACCEPT [116163:9327716]
:OUTPUT ACCEPT [104076:12500201]
-A PREROUTING -p tcp -m tcp --dport 80 -j NOTRACK
-A OUTPUT -p tcp -m tcp --sport 80 -j NOTRACK
COMMIT
# Completed on Wed Aug 18 10:10:52 2010

紅色部分是新增的。

重啟iptables:

service iptables restart

可以用iptables命令查看是否啟用成功了:

[root@mongo html]# iptables -t raw -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
NOTRACK tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80

Chain OUTPUT (policy ACCEPT)
target prot opt source destination
NOTRACK tcp -- 0.0.0.0/0 0.0.0.0/0 tcp spt:80

然後再用ab測試:

ab -c 1000 -n 5000 http://192.168.20.26/index.html

查看連結跟蹤表(/proc/net/ip_conntrack)的大小:

[root@mongo html]# wc -l /proc/net/ip_conntrack
1 /proc/net/ip_conntrack

跟蹤表內只跟蹤了一個連結了。

[root@mongo html]# cat /proc/net/ip_conntrack
tcp 6 431999 ESTABLISHED src=192.168.20.26 dst=192.168.20.10 sport=22 dport=50088 packets=85 bytes=10200 src=192.168.20.10 dst=192.168.20.26 sport=50088 dport=22 packets=92 bytes=6832 [ASSURED] mark=0 secmark=0 use=1

可以看到iptables已經不跟蹤進出連接埠為80的連結了。測試結果表明用iptables的raw表可以完美解決ip_conntrack: table full, dropping packet的問題。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.