2456 字
12 分钟
OVS流表规则之ct_state

Open vSwitch (OVS) 流表中的 ct_state 字段是 ​​ 连接追踪状态 ​​ 的核心标识符。它是 OVS 连接追踪功能的核心组成部分,允许 OVS 感知网络流量的状态,并根据其所属连接的状态做出智能的转发或过滤决策。

ct_state 的作用#

ct_state 的作用就是将连接追踪模块观察到的关于网络流(Connection)的状态信息暴露给 OVS 流表规则,从而使规则能够根据流量所处的不同连接阶段来采取行动。这对于实现有状态的防火墙、NAT(网络地址转换)、策略路由等功能至关重要。

简单来说,ct_state​ 允许 OVS 基于网络连接的生命周期状态(例如:这是一个新连接吗?属于一个已经建立的连接吗?)来决定如何处理数据包。​

ct_state 的主要状态位(Flags)#

ct_state 的值不是一个单一的状态,而是一个 ​​ 位掩码(bitmask)​​,表示多个可能状态的组合。流表规则通常匹配其中一位或多位的组合。关键的标志位包括:

  1. +new (0x01):​
    • ​ 含义:​​ 这个数据包被识别为发起一个新的连接。
    • ​ 作用:​​ 用来匹配一个流的第一个数据包(例如 TCP SYN,UDP 流的第一个包,ICMP 请求包)。常用于执行初始连接策略检查(如防火墙的第一个包检查)。
  2. +est (0x02):​
    • ​ 含义:​​ 这个数据包属于一个已经确立的(established)双向通信的连接。
    • ​ 作用:​​ 用来匹配已经成功完成初始握手(如 TCP SYN-ACK)或者被确认为有效双向流后续的数据包。常用于允许回包(reply traffic)或已建立连接的通信。
  3. +rel (0x04):​
    • ​ 含义:​​ 这个数据包与某个已存在的连接是 ​​ 相关联的(related)​​。
    • ​ 作用:​​ 用来匹配那些不是主连接本身,但逻辑上由其派生出来的连接的数据包。最常见的例子是 FTP 的数据连接(由 FTP 控制连接触发)、ICMP 错误消息(如 Destination Unreachable 响应某个 UDP/TCP 流)、某些 IPsec VPN 协议等。
  4. +trk (0x10):​
    • ​ 含义:​​ 这个数据包已被连接追踪模块 ​​ 追踪(tracked)​​ 且状态有效。
    • ​ 作用:​​ 这是 ​​ 最基础且通常必要的标志 ​​。它表示连接追踪模块已经开始处理这个数据包,并且后续 +new, +est, +rel 等状态是可靠的。在匹配连接状态(new, est, rel)时,几乎总是需要同时匹配 +trk 以确保操作的是有效追踪的连接。
  5. +inv (0x20):​
    • ​ 含义:​​ 连接追踪状态是 ​​ 无效(invalid)​​ 的。
    • ​ 作用:​​ 用于识别异常数据包,例如格式错误、与任何追踪的连接上下文不匹配的数据包。常用于丢弃可疑流量。
  6. +rpl (0x40):​​ (较少直接使用)
    • ​ 含义:​​ 指示数据包是连接追踪状态机中的 ​​ 回复方向(reply direction)​​。
    • ​ 作用:​​ 更底层地标识数据包相对于原始发起的方向。通常由 +new+est 等更高级的语义覆盖。
  7. +snat (0x80):​
    • ​ 含义:​​ 数据包匹配了一个经过源地址转换(SNAT)的连接。
    • ​ 作用:​​ 用于识别出站流量或 DNAT 后的回包。
  8. +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=drop
    priority=0, ct_state=+trk, actions=drop # 或根据策略调整
    • 第一条:匹配连接状态无效(+inv)的流量,直接丢弃。这是常见的安全策略。
    • 第二条:明确匹配所有未被追踪 (ct_state 不含 +trk) 且没有被前面更高优先级规则处理的流量,将其丢弃(或者也可以根据具体安全模型采取不同动作,如记录日志)。注意:简单匹配 ct_state 不等于 +trk 比较复杂,通常用低优先级规则兜底处理。

关键要点总结#

  1. ​ 状态感知:​ct_state 是 OVS 实现状态感知网络功能(如状态防火墙、有状态 NAT)的基石。
  2. ​ 位掩码:​​ 它是多个状态标志 (+new, +est, +rel, +trk, +inv 等) 的组合。
  3. ​ 必备标志 (+trk):​​ 在匹配 +new, +est, +rel 等有效连接状态时,几乎总是需要同时指定 +trk 以确保操作的是有效追踪的连接。+trk 表示连接追踪系统正在处理它。
  4. ​ 连接生命周期:​+new, +est, +rel 标志清晰地划分了连接的不同阶段(初始建立、已建立、相关联)。
  5. ​ 安全与策略:​+inv 用于识别和丢弃异常或无效流量,提升安全性。
  6. ​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​​ 等其他协议,连接追踪也会为流定义“原始方向”和“回复方向”。