Linux 连接跟踪 与 conntrack

990 阅读5分钟

连接跟踪模块的术语

  • 协议
  • 连接表
  • 连接
  • tuple

连接跟踪的实现原理

连接跟踪模块的实现基于 netfilter 的 hook 机制而实现。数据包从hook点流经,然后连接跟踪模块基于hook数据包来建立联系。

协议

连接跟踪模块会对哪些协议进行跟踪

TCP、UDP、ICMP、DCCP、SCTP、GRE

连接表

1: 连接表的作用

连接表用来存储连接的信息。

2: 连接表的数据结构

连接表是一个哈希表。键是 利用 tuple 来计算出的一个32位哈希值,不同的协议有不同的计算方式。值是 一个结构体,包含一个tuple属性,以及 一个链表,链表之中的元素是 连接。

3: 连接跟踪表的数据结构设计会影响什么?

会影响查询,会影响写入。 会影响内存的占用。

4: 连接表之中 连接的数据结构?

协议类型 连接的状态,连接状态的定时器, 哈希表项 ....

5: 连接表的容量是多少?

由某个具体的内核参数决定,连接表的容量不是无限制的。 /proc/sys/net/netfilter/nf_conntrack_max

6: 如何查看当前的连接表之中连接的数量?

Linux 内核之中某个内核参数的值 能够表示当前连接跟踪之中的数量。 /proc/sys/net/netfilter/nf_conntrack_count

7: 连接表容量溢出的处理策略?

当连接表容量溢出时,会触发连接的回收,如果连接没有ASSURED标记,会被作为回收的对象。如果连接表之中都是 ASSURED 标记的连接,那么连接跟踪会丢弃传来的新的建立连接的数据包。 这是自己目前的理解,有不完善的地方。

8: 如何查看连接表之中的信息,并采用过滤查询?

使用conntrack 命令,可以操作连接表之中的信息。

9: 为什么有时候,需要手动删除连接表之中的连接信息?

如果nat规则变换之后,如果不删除连接表之中的连接,那么还是会应用原本的nat转换规则,不会应用新的nat转换规则。

10: 命令行手动删除连接跟踪表之中的连接,会导致数据传输过程之中丢包嘛?

自己觉得是不会的。因为连接跟踪表之中的连接仅仅是用作记录而已。一旦被删除,新的数据包会被认为是新的连接,并不会因为连接不存在而丢包。

11: 如何发现连接表满了 出现丢包现象?

从内核看 使用 dmesg -T| grep 'table full' ,可以发现连接表满了。

12: 连接跟踪模块之中的连接 是否就是 tcp之中的连接?

连接是 内核从 流经机器的每个数据包之中提取信息,并为它们建立相应的连接,在具体的协议类型范围内,都会被追踪。不仅仅是tcp协议,所以连接跟踪模块之中的连接 并不等价于 tcp连接。

13: 表示 一个连接 的唯一性 是什么?

连接的唯一性是与协议相关的。

14: 有哪些建立连接的方式?

  • 1: 指定协议内的数据包,在流向本机。
  • 2: 本机向外部发送数据包

15: 一个连接建立的过程

首先new, 放入未确认的连接表,然后confirm,将其放入确认的连接表。

16:连接的回收规则?

后台会有定时的线程来检查连接表之中的项,如果连接的时间耗尽,那么会被回收。当然还会有一些其他的标志位参与连接的回收规则。

17: 数据包 经过 建立的连接 会带来哪些变化?

数据包经过建立的连接,会更新连接的超时时间,将连接的超时时间设置为最初值。

18: 如何查看一个连接的信息?

conntrack -L -s 来源ip地址 命令是根据来源ip来进行搜索显示连接的信息。

连接标记

  • UNREPLIED: 表示这个连接还没有收到任何回应
  • ASSURED: 连接上已经有多个数据包传输,会被标记为 ASSURED。

连接跟踪的客户端 conntrack

参数:

  • -S :显示统计信息
  • -E:显示出连接表之中的每个事件,可以用来查看连接的变化。
  • -o: 显示扩展字段,取值有 extended,xml,timestamp,id,ktimestamp,labels
  • -L : 列举出所有的连接信息
  • -e: 设置被内核产生的时间类型
  • -D: 删除连接

过滤参数

  • -p 按协议显示,取值范围 tcp udp
  • -s 来源ip
  • -d 目的ip
  • --sport 来源端口
  • --dport 目的端口
  • -n. 过滤出snat转换的连接
  • -g 过滤出dnat转换的连接

小需求

1: 查看Linux 内核是否开启 连接跟踪模块

  modinfo nf_conntrack
  输出信息如果有 enable,表示 内核开启了 连接跟踪模块。

2: 如何查看连接跟踪在某次请求之中连接信息的状态变化?

    conntrack -E -o ktimestamp 
    可以显示内核的日志时间,来追踪连接跟踪的变化。

3: 查看tcp协议的所有连接

     conntrack -L -p tcp 

4: 查看连接跟踪表之中 snat转换的连接

    conntrack -L -n 
    注意:连接信息之中会记载未经转换的ip信息。

5: conntrack 连接跟踪表之中 tcp ,udp协议的连接数

   conntrack -L -o extended | awk '{sum[$3]++} END {for(i in sum) print i, sum[i]}' && echo "-----------" && cat proc/net/nf_conntrack | awk '{sum[$3]++} END {for(i in sum) print i, sum[i]}'