nf_conntrack连接跟踪模块

2023-10-29 10:10

本文主要是介绍nf_conntrack连接跟踪模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

nf_conntrack连接跟踪模块

在iptables里,包是和被跟踪连接的四种不同状态有关的。它们分别是NEW,ESTABLISHED,RELATED和INVALID。后面我们会深入地讨论每一个状态。使用iptables的state模块可以匹配操作这几种状态,我们能很容易地控制“谁或什么能发起新的会话”。为什么需要这种状态跟踪机制呢?比如你的80端口开启,而你的程序被植入反弹式木马,导致服务器主动从80端口向外部发起连接请求,这个时候你怎么控制呢。关掉80端口,那么你的网站也无法正常运行了。但有了连接跟踪你就可以设置只允许回复关于80端口的外部请求(ESATBLISHED状态),而无法发起向外部的请求(NEW状态)。所以有了连接跟踪就可以做到在这种层面上的限制,慢慢往下看就明白了各状态的意义。

所有在内核中由Netfilter的特定框架做的连接跟踪称作conntrack(connection tracking)。conntrack可以作为模块安装,也可以作为内核的一部分。大部分情况下,我们想要也需要更详细的连接跟踪,这是相比于缺省的conntrack而言。也因为此,conntrack中有许多用来处理TCP,UDP或ICMP协议的部件。这些模块从数据包中提取详细的、唯一的信息,因此能保持对每一个数据流的跟踪。这些信息也告知conntrack流当前的状态。例如,UDP流一般由他们的目的地址、源地址、目的端口和源端口唯一确定。

在以前的内核里,我们可以打开或关闭重组功能。然而连接跟踪被引入内核后,这个选项就被取消了。因为没有包的重组,连接跟踪就不能正常工作。现在重组已经整合入conntrack,并且在conntrack启动时自动启动。不要关闭重组功能,除非你要关闭连接跟踪。

除了本地产生的包由OUTPUT链处理外,所有连接跟踪都是在PREROUTING链里进行处理的,意思就是, iptables会在PREROUTING链里从新计算所有的状态。如果我们发送一个流的初始化包,状态就会在OUTPUT链里被设置为NEW,当我们收到回应的包时,状态就会在PREROUTING链里被设置为ESTABLISHED。如果第一个包不是本地产生的,那就会在PREROUTING链里被设置为NEW状态。综上,所有状态的改变和计算都是在nat表中的PREROUTING链和OUTPUT链里完成的。

conntrack默认最大跟踪65536个连接,查看当前系统设置最大连接数

[root@server ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
65536

查看连接跟踪有多少条目

[root@server ~]# cat /proc/sys/net/netfilter/nf_conntrack_count
1

当服务器连接多于最大连接数时会出现kernel: ip_conntrack: table full, dropping packet的错误。

解决方法,修改conntrack最大跟踪连接数:

[root@server ~]# vim /etc/sysctl.conf
[root@server ~]# sysctl -p
net.nf_conntrack_max = 100000

查看established连接状态最多保留几天,默认是432000秒,就是5天;如果觉得时间太长可以修改。还有各种tcp连接状态的保留时间,都可以修改的。

[root@server ~]# cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
432000  

连接跟踪(conntrack)记录

IP_conntrack模块根据IP地址可以实时追踪本机TCP/UDP/ICMP的连接详细信息并保存在内存中“/proc/net/nf_conntrack”文件中(Centos5中使用的是/proc/net/ip_conntrack)。查看这个文件的记录会有如下信息:

ipv4     2 tcp      6 89  SYN_SENT src=101.81.225.225 dst=112.74.99.130 sport=33952 dport=80 
src=112.74.99.130 dst=101.81.225.225 sport=80 dport=33952 [UNREPLIED] mark=0 secmark=0 use=2
1
2
ipv4     2 tcp      6 89  SYN_SENT src=101.81.225.225 dst=112.74.99.130 sport=33952 dport=80 
src=112.74.99.130 dst=101.81.225.225 sport=80 dport=33952 [UNREPLIED] mark=0 secmark=0 use=2

IP_conntrack模块维护的所有信息都包含在这个例子中了,通过它们就可以知道某个特定的连接处于什么状态。首先显示的是IP类型,然后是协议,这里是tcp,接着是十进制的6(tcp的协议类型代码是6)。之后的89是这条conntrack记录的生存时间(TTL),它会有规律地被消耗,直到收到这个连接的更多的包。那时,这个值就会被设为当时那个状态的缺省值。接下来的是这个连接在当前时间点的状态。上面的例子说明这个包处在状态 SYN_SENT,这个值是iptables显示的,以便我们好理解,而内部用的值稍有不同。SYN_SENT说明我们正在观察的这个连接只在一个方向发送了一TCP SYN包。再下面是源地址、目的地址、源端口和目的端口。最后,是希望接收的应答包的信息,他们的地址和端口和前面是相反的。其中有个特殊的词[UNREPLIED],说明这个连接还没有收到任何回应。

当一个连接在两个方向上都有传输时,conntrack记录就删除[UNREPLIED]标志,然后重置。在末尾有[ASSURED]的记录说明两个方向已没有流量。

ipv4     2 tcp      6 431962 ESTABLISHED src=101.81.225.225 dst=112.74.99.130 sport=33952 dport=80 
src=112.74.99.130 dst=101.81.225.225 sport=80 dport=33952 [ASSURED] mark=0 secmark=0 use=2
1
2
ipv4     2 tcp      6 431962 ESTABLISHED src=101.81.225.225 dst=112.74.99.130 sport=33952 dport=80 
src=112.74.99.130 dst=101.81.225.225 sport=80 dport=33952 [ASSURED] mark=0 secmark=0 use=2

这样的记录是确定的,在连接跟踪表满时,是不会被删除的,没有[ASSURED]的记录就要被删除。连接跟踪表能容纳多少记录是被一个变量控制的,默认值取决于你的内存大小,128MB可以包含8192条目录,256MB是16376条,在拥有较大内存的机器中默认65536条。对于一个高并发的web服务器来说,如果你的请求数大过/proc/sys/net/netfilter/nf_conntrack_max文件中定义的数目,那么就会出现用户连接失败并且报错,报错信息如下:

nf_conntrack: table full, dropping packet.
1
nf_conntrack: table full, dropping packet.

而我们第一时间想到的办法就是关闭防火墙或是增大默认连接数,修改默认最大值,如下:

[root@localhost ~]# echo "100000" > /proc/sys/net/netfilter/nf_conntrack_max
1
[root@localhost ~]# echo "100000" > /proc/sys/net/netfilter/nf_conntrack_max

但不要盲目增大nf_conntrack_max的值-理解Linux内核内存分配

连接追踪模块属于内核的,所以我们知道所有的连接跟踪信息都是保存于内存中的,因此会考虑单纯放大这个nf_conntrack_max参数会占据多少内存,会权衡内存的占用,如果系统没有太大的内存,就不会将此值设置的太高。但是如果你的系统有很大的内存呢?比如有8G的内存,分个1G给连接跟踪也不算什么啊,这是合理的,然而在传统的32位架构Linux中是做不到,为什么?首先32位架构中最大寻址能力是4G,而Linux内存管理是虚拟内存的方式,4G内存分给内存的是1G,其他3G是理论上分给单个进程的,每个进程认为自己有3G内存可用,最后是根据每个进程实际使用的内存映射到物理内存中去。

内存越来越便宜的今天,Linux的内存映射方式确实有点过时了。然而事实就摆在那里,nf_conntrack处于内核空间,它所需的内存必须映射到内核空间,而传统的32位Linux内存映射方式只有1G属于内核,这1G的地址空间中,前896M是和物理内存一一线性映射的,后面的若干空洞之后,有若干vmalloc的空间,这些vmalloc空间和一一映射空间相比,很小很小,算上4G封顶下面的很小的映射空间,一共可以让内核使用的地址空间不超过1G。对于ip_conntrack来讲,由于其使用slab分配器,因此它还必须使用一一映射的地址空间,这就是说,它最多只能使用不到896M的内存!

为何Linux使用如此“落后”的内存映射机制这么多年还不改进?其实这种对内核空间内存十分苛刻的设计在64位架构下有了很大的改观,也可以放心根据内存调整最大连接追踪条目了。但问题依然存在,即使64位架构,内核也无法做到透明访问所有的物理内存,它同样需要把物理内存映射到内核地址空间后才能访问,对于一一映射,这种映射是事先确定的,对于大小有限(实际上很小)非一一映射空间,需要动态创建页表,页目录等。所以条目太多就会消耗性能且会产生内存碎片。另外如果不需要用到连接跟踪功能可以选择在Iptables中关闭,以此来提高系统的网络连接性能(因为开启会产生大量的IO操作)。卸载ip_conntrack模块如下,必须要先关闭防火墙才能卸载。另外注意当你试图查看iptables规则之后,就会激活ip_conntrack模块,无法真正卸载掉哦。

$ service iptables stop
$ modprobe -r nf_conntrack
1
2
$ service iptables stop
$ modprobe -r nf_conntrack

查看实时连接信息

查看ip_conntrack实时连接状态信息,安装iptstate工具

yum -y install iptstate     

执行命令

[root@server ~]# iptstate  

如下所示

相关的内核参数

[root@server ~]# sysctl -a | grep conntrack
net.netfilter.nf_conntrack_acct = 0
net.netfilter.nf_conntrack_buckets = 16384
net.netfilter.nf_conntrack_checksum = 1
net.netfilter.nf_conntrack_count = 1
net.netfilter.nf_conntrack_events = 1
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_expect_max = 256
net.netfilter.nf_conntrack_generic_timeout = 600
net.netfilter.nf_conntrack_helper = 1
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_log_invalid = 0
net.netfilter.nf_conntrack_max = 65536
net.netfilter.nf_conntrack_tcp_be_liberal = 0
net.netfilter.nf_conntrack_tcp_loose = 1
net.netfilter.nf_conntrack_tcp_max_retrans = 3
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 432000
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_timestamp = 0
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180
net.nf_conntrack_max = 65536

也可以使用 dmesg 查看。

[root@server ~]# dmesg | tail -f
[    3.656918] ppdev: user-space parallel port driver
[    3.680022] alg: No test for __gcm-aes-aesni (__driver-gcm-aes-aesni)
[    3.772029] alg: No test for crc32 (crc32-pclmul)
[    3.785294] intel_rapl: no valid rapl domains found in package 0
[    7.120138] EXT4-fs (vda1): resizing filesystem from 786176 to 5242304 blocks
[    7.422160] EXT4-fs (vda1): resized filesystem to 5242304
[ 1994.617368] nf_conntrack version 0.5.0 (16384 buckets, 65536 max)
[ 3657.011241] nr_pdflush_threads exported in /proc is scheduled for removal
[ 4538.293958] Netfilter messages via NETLINK v0.30.
[ 4538.300128] ctnetlink v0.93: registering with nfnetlink.
转自:https://awen.me/post/59062.html?from=timeline

这篇关于nf_conntrack连接跟踪模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/299936

相关文章

java连接opcua的常见问题及解决方法

《java连接opcua的常见问题及解决方法》本文将使用EclipseMilo作为示例库,演示如何在Java中使用匿名、用户名密码以及证书加密三种方式连接到OPCUA服务器,若需要使用其他SDK,原理... 目录一、前言二、准备工作三、匿名方式连接3.1 匿名方式简介3.2 示例代码四、用户名密码方式连接4

MySQL 表的内外连接案例详解

《MySQL表的内外连接案例详解》本文给大家介绍MySQL表的内外连接,结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录表的内外连接(重点)内连接外连接表的内外连接(重点)内连接内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我

Apache 高级配置实战之从连接保持到日志分析的完整指南

《Apache高级配置实战之从连接保持到日志分析的完整指南》本文带你从连接保持优化开始,一路走到访问控制和日志管理,最后用AWStats来分析网站数据,对Apache配置日志分析相关知识感兴趣的朋友... 目录Apache 高级配置实战:从连接保持到日志分析的完整指南前言 一、Apache 连接保持 - 性

电脑蓝牙连不上怎么办? 5 招教你轻松修复Mac蓝牙连接问题的技巧

《电脑蓝牙连不上怎么办?5招教你轻松修复Mac蓝牙连接问题的技巧》蓝牙连接问题是一些Mac用户经常遇到的常见问题之一,在本文章中,我们将提供一些有用的提示和技巧,帮助您解决可能出现的蓝牙连接问... 蓝牙作为一种流行的无线技术,已经成为我们连接各种设备的重要工具。在 MAC 上,你可以根据自己的需求,轻松地

宝塔安装的MySQL无法连接的情况及解决方案

《宝塔安装的MySQL无法连接的情况及解决方案》宝塔面板是一款流行的服务器管理工具,其中集成的MySQL数据库有时会出现连接问题,本文详细介绍两种最常见的MySQL连接错误:“1130-Hostisn... 目录一、错误 1130:Host ‘xxx.xxx.xxx.xxx’ is not allowed

Python logging模块使用示例详解

《Pythonlogging模块使用示例详解》Python的logging模块是一个灵活且强大的日志记录工具,广泛应用于应用程序的调试、运行监控和问题排查,下面给大家介绍Pythonlogging模... 目录一、为什么使用 logging 模块?二、核心组件三、日志级别四、基本使用步骤五、快速配置(bas

Python datetime 模块概述及应用场景

《Pythondatetime模块概述及应用场景》Python的datetime模块是标准库中用于处理日期和时间的核心模块,本文给大家介绍Pythondatetime模块概述及应用场景,感兴趣的朋... 目录一、python datetime 模块概述二、datetime 模块核心类解析三、日期时间格式化与

Python如何调用指定路径的模块

《Python如何调用指定路径的模块》要在Python中调用指定路径的模块,可以使用sys.path.append,importlib.util.spec_from_file_location和exe... 目录一、sys.path.append() 方法1. 方法简介2. 使用示例3. 注意事项二、imp

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

MySQL 多表连接操作方法(INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN)

《MySQL多表连接操作方法(INNERJOIN、LEFTJOIN、RIGHTJOIN、FULLOUTERJOIN)》多表连接是一种将两个或多个表中的数据组合在一起的SQL操作,通过连接,... 目录一、 什么是多表连接?二、 mysql 支持的连接类型三、 多表连接的语法四、实战示例 数据准备五、连接的性