Connmark 是将 iptables 标记持久化到连接层面的机制,确保双向流量携带统一标识以支撑 QoS、审计引流与多出口选路;需先用 MARK 精准匹配业务流量,再通过 CONNMARK save/restore 实现连接级标记同步,最后基于 ctmark 进行策略路由、限速、日志增强及出口选路,并注意 conntrack 启用、掩码使用与容器网络适配等细节。

Connmark 不是自动识别业务逻辑的“智能标签器”,而是把你在 iptables 中定义的业务规则(比如某类 API 请求、特定用户组流量、某个微服务调用链)所打的数据包标记(MARK),持久化到连接层面,确保整个 TCP/UDP 会话的双向流量都携带同一标识——这是实现稳定 QoS、审计引流、多出口选路的前提。
一、先明确你要标记的业务流量
Connmark 本身不判断业务,它只同步状态。所以第一步必须用 MARK 在 mangle 表中精准圈出目标流量:
- 按服务端口:如后端 gRPC 流量走 50051 端口 → iptables -t mangle -A PREROUTING -p tcp --dport 50051 -j MARK --set-mark 0x100
- 按 HTTP 路径特征:如所有 /api/v2/payment 请求 → iptables -t mangle -A PREROUTING -p tcp --dport 8080 -m string --algo bm --string "/api/v2/payment" --from 64 -j MARK --set-mark 0x200
- 按源 IP 分组:如运维网段 10.20.30.0/24 的管理流量 → iptables -t mangle -A PREROUTING -s 10.20.30.0/24 -j MARK --set-mark 0x300
- 按容器或 Pod 标签(需配合 CNI 注入):如 label=env=prod 的入口流量 → 需在宿主机 PREROUTING 中匹配其所在网段或通过 ipset 关联
二、用 CONNMARK 把包标记升维为连接标记
只对进向首包打 MARK,回程响应包会丢失标记,导致策略断裂。必须用 CONNMARK 将标记存入连接跟踪(conntrack)记录,并在后续所有同连接包中恢复:
- 首次进包:打标 + 同步到连接 → iptables -t mangle -A PREROUTING -m mark --mark 0x100 -j CONNMARK --save-mark
- 后续所有包(含回程):从连接中取标 → iptables -t mangle -A PREROUTING -m connmark --ctmark 0x100 -j CONNMARK --restore-mark
- 注意顺序:restore-mark 规则建议放在 save-mark 之前(尤其在 PREROUTING 链开头),避免新连接尚未 save 就 restore 出错;也可加条件限制,如 -m state --state ESTABLISHED,RELATED
三、基于连接标记做业务级调度
CONNMARK 让“一个业务流 = 一个带标连接”,后续模块就能可靠依赖这个标识:
- 策略路由分流:ip rule add fwmark 0x100 table prod_api;再配 table prod_api 的默认网关指向专用审计节点或灰度网关
- tc 做业务限速:tc filter add dev eth0 parent 1: protocol ip u32 match ip mark 0x100 0xffffffff flowid 1:20,绑定独立 HTB class 控制 gRPC 流量带宽
- 日志与监控增强:在 LOG 目标前加 -m connmark --ctmark 0x200,让所有 payment 请求日志自带业务上下文,便于 ELK 关联分析
- 多出口保活选路:对标记为 0x300 的运维流量,强制走专线接口 eth2;同时用 CONNMARK 配合 ip rule,确保 SSH 回包也从 eth2 出,不因默认路由走错出口
四、关键细节与避坑点
业务标记若不稳定,整个链路就失效。这些细节决定成败:
- CONNMARK 必须搭配 conntrack 模块启用,检查:lsmod | grep nf_conntrack;如未加载,modprobe nf_conntrack
- 保存和恢复时建议加掩码,避免干扰其他位:如 --save-mark --nfmask 0x000000ff --ctmask 0x000000ff
- 若使用 Docker/K8s,注意容器网络路径:Host 网络模式下规则生效于 host 的 PREROUTING;Bridge 模式需在 host 的 FORWARD 链处理,且确保 conntrack 能跟踪跨 namespace 连接
- 连接老化后标记丢失,对长连接(如 WebSocket)影响小;但短连接高频建连场景,可适当调大 conntrack 超时:sysctl -w net.netfilter.nf_conntrack_tcp_timeout_established=1800

















