在 Netfilter 上,您可以选择--set-mark
通过该mangle
表的数据包。
互联网上的大多数教程和示例都说这只是在数据包上添加了一个标记,如下所示,但没有关于设置什么标记以及它位于数据包上的位置的其他详细信息:
iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1
我的问题是:
- 设置了什么样的标记以及该标记到底位于数据包中的什么位置?
答案1
标记是附加在网络数据包上的 32 位整数值。与之交互的一些网络部分(见下文)可以对此值进行按位运算,然后可以在一个 32 位值到 32 个标志的集合或标志和较小值的混合之间进行解释,具体取决于如何处理选择组织其使用(tc
不能这样做)。当然这个标记仅当由 Linux 内核处理时才存在。它只是纯粹的虚拟和内部的,因为它在线路上不存在。根据使用地点的不同,它可能被称为防火墙标记、fwmark 或简称为标记。
内核处理的每个网络数据包都由一个名为sk_buff
,定义于linux/include/linux/skbuff.h
。该结构包括与数据包相关的各种元数据(如果适用),例如 IPsec 信息(如果有)、查找到的相关 conntrack 条目……及其标记。
网络堆栈的各个部分可以与此标记交互或更改此标记,例如:
tc
,- 路由堆栈可以设置特殊规则
ip rule
(例如ip rule add fwmark 1 lookup 42
),使用此 fwmark 更改其路由决策(例如,使用路由表将这些数据包发送到默认接口之外的其他接口), - 当然
iptables
, - 其候选继任者nftables,
- 各种(通常是隧道)接口类型可以设置标记或与其交互,例如瓦特、 erspan、gre、gretap、ipip、坐、线卫...或 XFRM 转换 (
ip xfrm state/policy
)。根据类型的不同,该标记可以设置在有效负载或信封上(例如:WireGuard),有时可以在解封装/封装过程中继承, - 插座选项
SO_MARK
, - 电子BPF,
可能还有其他一些地方......
该标记的主要目标是让所有这些网络部分通过将其用作一种消息来相互交互。这Netfilter 和通用网络中的数据包流可以帮助查看这些元素将以什么顺序接收数据包的处理及其标记。
除了fwmark之外,还有其他相关标记:
connmark
,它不存储在数据包的 sk_buff 中,而是存储在 conntrack 条目跟踪数据包中流量。它的 connmark 当然可以被 iptables 使用connmark
匹配和CONNMARK
目标,其中有一个使用示例:Netfilter Connmark 到 Linux 及更高版本!。它允许记忆基于单个数据包做出的决策,然后应用于同一连接的所有数据包。secmark
同样,它的相关connsecmark
旨在与 Linux 安全模块交互,例如SELinux。