Open vSwitch (OVS) 流表中的 ct_state 字段是 连接追踪状态 的核心标识符。它是 OVS 连接追踪功能的核心组成部分,允许 OVS 感知网络流量的状态,并根据其所属连接的状态做出智能的转发或过滤决策。
ct_state 的作用
ct_state 的作用就是将连接追踪模块观察到的关于网络流(Connection)的状态信息暴露给 OVS 流表规则,从而使规则能够根据流量所处的不同连接阶段来采取行动。这对于实现有状态的防火墙、NAT(网络地址转换)、策略路由等功能至关重要。
简单来说,ct_state 允许 OVS 基于网络连接的生命周期状态(例如:这是一个新连接吗?属于一个已经建立的连接吗?)来决定如何处理数据包。
ct_state 的主要状态位(Flags)
ct_state 的值不是一个单一的状态,而是一个 位掩码(bitmask),表示多个可能状态的组合。流表规则通常匹配其中一位或多位的组合。关键的标志位包括:
-
+new(0x01):- 含义: 这个数据包被识别为发起一个新的连接。
- 作用: 用来匹配一个流的第一个数据包(例如 TCP SYN,UDP 流的第一个包,ICMP 请求包)。常用于执行初始连接策略检查(如防火墙的第一个包检查)。
-
+est(0x02):- 含义: 这个数据包属于一个已经确立的(established)双向通信的连接。
- 作用: 用来匹配已经成功完成初始握手(如 TCP SYN-ACK)或者被确认为有效双向流后续的数据包。常用于允许回包(reply traffic)或已建立连接的通信。
-
+rel(0x04):- 含义: 这个数据包与某个已存在的连接是 相关联的(related)。
- 作用: 用来匹配那些不是主连接本身,但逻辑上由其派生出来的连接的数据包。最常见的例子是 FTP 的数据连接(由 FTP 控制连接触发)、ICMP 错误消息(如
Destination Unreachable响应某个 UDP/TCP 流)、某些 IPsec VPN 协议等。
-
+trk(0x10):- 含义: 这个数据包已被连接追踪模块 追踪(tracked) 且状态有效。
- 作用: 这是 最基础且通常必要的标志 。它表示连接追踪模块已经开始处理这个数据包,并且后续
+new,+est,+rel等状态是可靠的。在匹配连接状态(new, est, rel)时,几乎总是需要同时匹配+trk以确保操作的是有效追踪的连接。
-
+inv(0x20):- 含义: 连接追踪状态是 无效(invalid) 的。
- 作用: 用于识别异常数据包,例如格式错误、与任何追踪的连接上下文不匹配的数据包。常用于丢弃可疑流量。
-
+rpl(0x40): (较少直接使用)- 含义: 指示数据包是连接追踪状态机中的 回复方向(reply direction)。
- 作用: 更底层地标识数据包相对于原始发起的方向。通常由
+new和+est等更高级的语义覆盖。
-
+snat(0x80):- 含义: 数据包匹配了一个经过源地址转换(SNAT)的连接。
- 作用: 用于识别出站流量或 DNAT 后的回包。
-
+dnat(0x100):- 含义: 数据包匹配了一个经过目标地址转换(DNAT)的连接。
- 作用: 用于识别入站流量或 SNAT 后的回包。
实际流表规则示例与解释
- 允许已建立和相关连接:
actions=ct(commit), normal
ct_state=+trk+est:匹配已被追踪(+trk)且属于已建立连接(+est)的 回包 。ct_state=+trk+rel:匹配已被追踪(+trk)且属于相关连接(+rel)的流量(如 FTP 数据连接)。- 动作:将数据包交由普通转发路径处理 (
normal)。
- 允许内部发起新连接并进行 NAT:
priority=100, in_port=eth0, ip, ct_state=+trk+new, actions=ct(commit, zone=1, nat(src=10.0.0.1)), normal
ct_state=+trk+new:匹配从内部接口 (in_port=eth0) 进来的、已被追踪(+trk)且是发起新连接(+new)的流量。- 动作:提交 (
commit) 到连接追踪表,在特定区域 (zone=1) 执行源 NAT (nat(src=10.0.0.1)),然后正常转发 (normal)。
- 拒绝无效或未追踪流量:
priority=1, ct_state=+inv, actions=droppriority=0, ct_state=+trk, actions=drop # 或根据策略调整
- 第一条:匹配连接状态无效(
+inv)的流量,直接丢弃。这是常见的安全策略。 - 第二条:明确匹配所有未被追踪 (
ct_state不含+trk) 且没有被前面更高优先级规则处理的流量,将其丢弃(或者也可以根据具体安全模型采取不同动作,如记录日志)。注意:简单匹配ct_state不等于+trk比较复杂,通常用低优先级规则兜底处理。
- 第一条:匹配连接状态无效(
关键要点总结
- 状态感知:
ct_state是 OVS 实现状态感知网络功能(如状态防火墙、有状态 NAT)的基石。 - 位掩码: 它是多个状态标志 (
+new,+est,+rel,+trk,+inv等) 的组合。 - 必备标志 (
+trk): 在匹配+new,+est,+rel等有效连接状态时,几乎总是需要同时指定+trk以确保操作的是有效追踪的连接。+trk表示连接追踪系统正在处理它。 - 连接生命周期:
+new,+est,+rel标志清晰地划分了连接的不同阶段(初始建立、已建立、相关联)。 - 安全与策略:
+inv用于识别和丢弃异常或无效流量,提升安全性。 - NAT 方向:
+snat和+dnat帮助识别流量是否经过了特定的地址转换。
理解 ct_state 及其标志位对于在 OVS 中配置复杂的有状态网络策略至关重要。通常需要结合 ct() 动作(尤其是 commit)来让连接追踪系统记录和管理连接状态信息。
补充
-
-操作符: 表示“ 不包含 ”指定的标志位。 -
+操作符: 表示“ 必须包含 ”指定的标志位。
ct_state=-trk
匹配 所有未被连接追踪模块有效追踪的数据包 ,这些包可能是:
- 尚未被连接追踪处理 :数据包是流表规则处理过程中首次进入流水线,尚未到达触发连接追踪的规则点(通常需要显式使用
ct()动作),或者前面的规则根本没尝试让它进入追踪状态。 - 无需或不能被追踪的类型 :例如 ARP 数据包、第 2 层 (L2) 非 IP 数据包、特殊协议包,或者管理员配置了某些 IP 范围/协议不进行追踪。
- 无效包被忽略 :某些严重畸形或完全无法解析的 IP 包也可能不会被追踪。
典型用途: 通常用于流表规则中处理 无状态流量 或 明确需要绕过连接追踪 的流量。例如:
- 在进入连接追踪相关规则链之前,先处理一些二层转发或特定协议(如 ARP)的规则。
- 兜底规则中明确丢弃或允许未被追踪的流量(根据安全策略)。
ct_state=-rpl+trk
-匹配那些已被有效追踪,且被连接追踪模块标记为属于连接“原始请求/发起方向”(Original Direction)的数据包。 简单来说: 这是连接追踪跟踪到的、发起的那个请求包(Request Packet)或者属于原始方向的后续包,而不是回复包。
典型用途: 在需要严格区分流量的 发起方/请求端 和 响应方/服务端 时非常有用,特别是对于 不对称网络策略 或 高级流量整形 :
- 识别出站流量(从内部网络发起访问外部服务)。
- 在配置 DNAT (目的地址转换) 后,识别由外部客户端发起的原始方向流量(外部->经过 DNAT 后的内部服务器),以便在原始方向上应用限速或防火墙策略。
- 在配置 SNAT (源地址转换) 后,识别从内部客户端发往外部服务的原始方向流量(内部->经过 SNAT 地址出去的外部),或者识别从外部服务器回到 SNAT 地址的回包方向(即
+rpl)。
| 匹配表达式 | 核心含义 | 关键用途 |
|---|---|---|
ct_state=-trk | 未被连接追踪有效追踪的包。 (可能是没被处理、无法追踪、无需追踪的类型) | 处理无状态流量;处理二层/ARP;在进入连接追踪前处理特定流量;兜底策略处理未追踪包 |
ct_state=-rpl+trk | 已被追踪且属于连接发起方向(原始方向/请求方向)的包。 (既包括新连接请求包 +new,也包括已建立连接后继续从发起方发出的包 +est) | 严格区分流量方向;识别出站流量/请求流量;在原始方向应用策略(限速、防火墙、QoS);DNAT 后识别外部发往内部服务的流量;SNAT 后识别内部发往外部服务的流量 |
注意:
- 规则的优先级 (
priority) 至关重要。一个匹配ct_state=-trk的高优先级规则会拦截数据包,使其永远无法被后续规则标记为+trk。 ct_state=-rpl通常需要和+trk一起使用 (ct_state=-rpl+trk) 才有明确意义,单独使用-rpl非常罕见且容易引起混淆。- 理解方向:
-rpl(非回复方向) 通常对应“发起连接/客户端 -> 服务器”的方向;+rpl通常对应“服务器 -> 客户端”的回包方向。 - 对 TCP 而言,方向 (
+rpl/-rpl) 在连接建立后是确定的。但对 UDP/ICMP 等其他协议,连接追踪也会为流定义“原始方向”和“回复方向”。