Linux - 网络子系统 - CT

引用


一. Overall

CT: 连接跟踪 - connection tracking,conntrack。

     连接跟踪是许多网络应用的基础。例如,Kubernetes Service、ServiceMesh sidecar、 软件四层负载均衡器 LVS/IPVS、Docker network、OVS、iptables 主机防火墙等等,都依赖 连接跟踪功能

例如,上图是一台 IP 地址为 10.1.1.2 的 Linux 机器,我们能看到这台机器上有三条 连接:

  1. 机器访问外部 HTTP 服务的连接(目的端口 80)
  2. 外部访问机器内 FTP 服务的连接(目的端口 21)
  3. 机器访问外部 DNS 服务的连接(目的端口 53)

连接跟踪所做的事情就是发现并跟踪这些连接的状态,具体包括:

  • 从数据包中提取元组(tuple)信息,辨别数据流(flow)和对应的连接(connection)
  • 为所有连接维护一个状态数据库(conntrack table),例如连接的创建时间、发送 包数、发送字节数等等
  • 回收过期的连接(GC)
  • 为更上层的功能(例如 NAT)提供服务

需要注意的是,连接跟踪中所说的“连接”,概念和 TCP/IP 协议中“面向连接”( connection oriented)的“连接”并不完全相同,简单来说:

  • TCP/IP 协议中,连接是一个四层(Layer 4)的概念。
    • TCP 是有连接的,或称面向连接的(connection oriented),发送出去的包都要求对端应答(ACK),并且有重传机制
    • UDP 是无连接的,发送的包无需对端应答,也没有重传机制
  • CT 中,一个元组(tuple)定义的一条数据流(flow )就表示一条连接(connection)。
    • 后面会看到 UDP, 甚至是 ICMP 这种3.5层协议在 CT 中也都是有连接记录的
    • 不是所有协议都会被连接跟踪

本文中用到“连接”一词时,大部分情况下指的都是后者,即“连接跟踪”中的“连接”。

二. 原理

要跟踪一台机器的所有连接状态,就需要

  1. 拦截(或称过滤)流经这台机器的每一个数据包,并进行分析
  2. 根据这些信息建立起这台机器上的连接信息数据库(conntrack table)。
  3. 根据拦截到的包信息,不断更新数据库

例如,

  1. 拦截到一个 TCP SYNC 包时,说明正在尝试建立 TCP 连接,需要创建一条新 conntrack entry 来记录这条连接
  2. 拦截到一个属于已有 conntrack entry 的包时,需要更新这条 conntrack entry 的收发包数等统计信息

三. 设计 - Netfilter

Linux的连接跟踪是在Netfilter中实现的。

Netfilter 是 Linux 内核中一个对数据包进行控制、修改和过滤(manipulation and filtering)的框架。它在内核协议 栈中设置了若干hook 点,以此对数据包进行拦截、过滤或其他处理。

更直白一些,hook 机制就是在数据包的必经之路上设置若干检测点,所有到达这 些检测点的包都必须接受检测,根据检测的结果决定:

  1. 放行:不对包进行任何修改,退出检测逻辑,继续后面正常的包处理
  2. 修改:例如修改 IP 地址进行 NAT,然后将包放回正常的包处理逻辑
  3. 丢弃:安全策略或防火墙功能

CT连接跟踪模块只是完成连接信息的采集和录入功能,并不会修改或丢弃数据包,后者是其他模块(例如 NAT-NetworkAddressTranslation)基于 Netfilter hook 完成的。

四. 设计 - 进一步思考

 现在提到连接跟踪(conntrack),可能首先都会想到 Netfilter。但由上节讨论可知, 连接跟踪概念是独立于 Netfilter 的,Netfilter 只是 Linux 内核中的一种连接跟踪实现

换句话说,只要具备了 hook 能力,能拦截到进出主机的每个包,完全可以在此基础上自 己实现一套连接跟踪

云原生网络方案 Cilium 在 1.7.4+ 版本就实现了这样一套独立的连接跟踪和 NAT 机制 (完备功能需要 Kernel 4.19+)。其基本原理是:

  1. 基于 BPF hook 实现数据包的拦截功能(等价于 netfilter 里面的 hook 机制)
  2. 在 BPF hook 的基础上,实现一套全新的 conntrack 和 NAT

因此,即便卸载 Netfilter ,也不会影响 Cilium 对 Kubernetes ClusterIP、NodePort、ExternalIPs 和 LoadBalancer 等功能的支持 [2]。

由于这套连接跟踪机制是独立于 Netfilter 的,因此它的 conntrack 和 NAT 信息也没有存储在内核的(也就是 Netfilter 的)conntrack table 和 NAT table。所以常规的 conntrack/netstats/ss/lsof 等工具是看不到的,要使用 Cilium 的命令,例如:

$ cilium bpf nat list
$ cilium bpf ct list global

配置也是独立的,需要在 Cilium 里面配置,例如命令行选项 --bpf-ct-tcp-max

另外,本文会多次提到连接跟踪模块NAT模块独立,但出于性能考虑,具体实现中 二者代码可能是有耦合的。例如 Cilium 做 conntrack 的垃圾回收(GC)时就会顺便把 NAT 里相应的 entry 回收掉,而非为 NAT 做单独的 GC。

五. 应用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值