用iptables的raw表解决ip_conntrack: table full, dropping packet的问题

本文介绍了iptables中Raw表的功能及使用方法,包括如何通过Raw表避免连接跟踪以提升性能,以及解决ip_conntrack表溢出的问题。

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

也可以编辑文件添加:/etc/sysctl.conf,实现开机自动生效。

net.netfilter.nf_conntrack_max = 1048576
net.netfilter.nf_conntrack_tcp_timeout_established = 3600

修改后,执行sysctl -p 生效

和buckets表开机自动修改

echo "echo 262144 > /sys/module/nf_conntrack/parameters/hashsize" >> /etc/rc.d/rc.local




(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@wh-22-50 ~]# wc -l /proc/net/nf_conntrack
365 /proc/net/nf_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的问题。

<think>好的,我现在需要解决用户关于“nf_conntrack自动助手分配被弃用”的问题,以及如何使用iptables的CT目标来替代。首先,我得理解用户的问题。用户提到nf_conntrack的自动助手分配被弃用了,所以他们可能需要更新配置,使用新的方法。然后,用户想用iptables的CT目标来替代原来的自动分配方式。 首先,我需要回忆一下nf_conntrack的作用。nf_conntrack是Netfilter的连接跟踪模块,用于跟踪网络连接状态,比如TCP/UDP会话。自动助手分配可能是指conntrack自动识别特定协议(如FTP、SIP)并分配helper模块来解析连接,比如FTP需要处理PORT命令中的动态端口。但现在这个自动分配被弃用了,所以用户需要手动指定helper。 接下来,我需要确认弃用的原因。可能出于安全考虑,自动分配可能存在风险,比如不必要的helper加载会增加攻击面,或者导致性能问题。所以内核社区可能决定弃用自动分配,要求显式配置。 然后,解决方案是使用iptables的CT目标来手动指定helper。CT目标允许在规则中设置连接跟踪的参数,比如指定helper模块。用户需要为特定协议(如FTP)手动添加规则,明确指定helper。 接下来,我需要详细步骤。首先,检查当前是否有自动helper加载,可能需要查看系统日志或者/proc/net/nf_conntrack。然后,禁用自动分配,这可能需要设置sysctl参数,比如net.netfilter.nf_conntrack_helper=0。但需要确认具体的参数名称是否正确,可能不同的内核版本参数名不同,可能需要查阅文档。 然后,创建iptables规则,使用CT目标指定helper。例如,对于FTP,加载nf_conntrack_ftp模块,然后添加规则,匹配FTP流量(比如端口21),使用CT --helper ftp。这样,当流量经过该规则时,conntrack会使用指定的helper来处理。 另外,用户可能需要确保相关内核模块已加载,比如modprobe nf_conntrack_ftp。否则,即使规则正确,helper也无法工作。 还需要考虑持久化配置,因为重启后sysctl设置和iptables规则可能会丢失。用户需要将sysctl配置写入/etc/sysctl.conf或相应的配置文件,并将iptables规则保存,比如使用iptables-save > /etc/sysconfig/iptables,具体取决于发行版。 同时,用户可能遇到问题,比如规则不生效,这时候需要检查模块是否加载,规则顺序是否正确,以及日志是否有错误信息。可能需要查看dmesg或/var/log/messages来调试。 最后,总结步骤:禁用自动helper分配,加载所需模块,添加iptables规则指定CT helper,并持久化配置。可能还需要测试配置是否生效,比如通过FTP传输文件,查看连接跟踪是否正确处理动态端口。 另外,用户提供的引用中提到过iptables规则自动生成配置文件,所以可能需要确保保存规则的方式正确,比如使用iptables-save和iptables-restore。 现在,我需要验证这些步骤是否正确,是否有遗漏。比如,是否确实需要设置net.netfilter.nf_conntrack_helper为0,或者是否有其他参数控制自动分配。不同内核版本可能有差异,可能需要查阅最新的文档或社区资源。此外,CT目标的使用是否正确,比如语法是否正确,是否需要指定其他参数。 可能还需要考虑SELinux的影响,如引用[2]中提到的,如果SELinux处于强制模式,可能会阻止某些网络配置,需要调整策略或设置为许可模式进行测试。不过用户的问题主要围绕nf_conntrackiptables,可能SELinux不是主要因素,但可以提醒用户注意。 总结来说,解决方案包括禁用自动helper,手动指定helper模块,并通过iptables规则使用CT目标来关联协议和helper,确保模块加载,并持久化配置。</think>### 解决`nf_conntrack`自动助手分配弃用问题及使用`CT`目标替代方案 #### 问题背景 在较新的Linux内核版本中,`nf_conntrack`模块的**自动助手分配(Automatic Helper Assignment)功能被弃用**。此功能原先用于根据流量类型(如FTP、SIP)自动加载对应的连接跟踪助手模块(如`nf_conntrack_ftp`)以解析协议细节(如FTP动态端口)。弃用原因是自动分配可能导致安全风险(如未授权协议解析)和性能问题[^1]。 #### 解决方案步骤 1. **禁用自动助手分配** 修改内核参数以关闭自动加载功能: ```bash sudo sysctl -w net.netfilter.nf_conntrack_helper=0 ``` 持久化配置需将以下内容添加到`/etc/sysctl.conf`: ``` net.netfilter.nf_conntrack_helper = 0 ``` 2. **手动加载所需助手模块** 例如,为FTP协议加载模块: ```bash sudo modprobe nf_conntrack_ftp ``` 持久化模块加载需在`/etc/modules-load.d/`下创建配置文件(如`nf_conntrack.conf`),并添加模块名: ``` nf_conntrack_ftp ``` 3. **使用`iptables`的`CT`目标显式指定助手** 通过`CT`目标手动关联协议与助手模块。例如,为FTP流量(端口21)指定助手: ```bash sudo iptables -A INPUT -p tcp --dport 21 -j CT --helper ftp ``` **参数说明**: - `--helper ftp`:调用`nf_conntrack_ftp`模块解析FTP协议。 4. **保存`iptables`规则** 生成持久化规则文件(以CentOS为例): ```bash sudo iptables-save > /etc/sysconfig/iptables ``` #### 验证配置 1. 检查连接跟踪是否应用了助手模块: ```bash cat /proc/net/nf_conntrack | grep ftp ``` 若输出包含`helper=ftp`,则配置成功。 2. 测试FTP传输文件,观察是否能正常处理动态端口。 #### 注意事项 - **兼容性**:`CT`目标需内核≥3.6且`iptables`≥1.4.18。 - **SELinux影响**:若SELinux处于强制模式,可能拦截网络操作,可通过`setenforce 0`临时切换为许可模式调试[^2]。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值