如何在 iptables 中一起添加标记(目标 MARK 和 CONNMARK)

如何在 iptables 中一起添加标记(目标 MARK 和 CONNMARK)

当您想要标记 中的数据包时iptables,通常会将以下行添加到防火墙脚本中:

iptables -t mangle -A POSTROUTING -p tcp -m multiport --dports 80,443 -j MARK --set-mark 2

我知道这个主题有点复杂,但让我们只关注单一规则。当您添加类似上面的内容时,文件中的/proc/net/nf_conntrack某些条目将设置标记:

ipv4     2 tcp      6 3706 ESTABLISHED ... mark=2

该规则的问题在于,当您添加另一个匹配的规则(例如源或目标地址)并设置另一个标记时,前一个标记将被重写为您设置的内容。但有一些方法可以“添加”标记。因此,如果一个规则集mark=2和另一个规则集mark=5,那么结果标记将是mark=7或类似的东西。

我有一个基于的工作示例姆万3,但我不太明白。我知道mangle启动该工具后该表是什么样子,以及添加了哪些规则:

在此输入图像描述

因此,要理解该机制,我必须知道到达的数据包实际发生了什么。但在这个例子中,标记规则是不同的。

我们有两个不同的 WAN 接口。根据标记,数据包将进入不同的路由表。那么,发往端口 443(例如发往端口 1000)的数据包实际上会发生什么情况?谁能帮我分析一下规则吗?

答案1

目标“-j MARK --set-mark 2”将在数据包上设置标记 2,无论之前的值是什么。如果您想避免标记被删除,您可以简单地使用 -j ACCEPT 结束链中的数据包路径。例如 :

iptables -t mangle -A POSTROUTING -p tcp --dport 80 -j MARK --set-mark 10
iptables -t mangle -A POSTROUTING -p tcp --dport 80 -j ACCEPT
iptables -t mangle -A POSTROUTING -d 8.8.8.8 -j MARK --set-mark 20
iptables -t mangle -A POSTROUTING -d 8.8.8.8 --dport 80 -j ACCEPT
# If you open a connection to 8.8.8.8:80, the mark will be 10

不过,如果您位于主链(例如 POSTROUTING)或自定义链中,您必须小心:ACCEPT 将结束主链,而 RETURN 将结束当前链。这取决于您的需求。

关于 mwan3 示例,如果没有过滤器、nat 和原始表,并且没有 tc 配置,则很难确定。

然而,它看起来像这样:

  • “mwan3_rules”链将数据包从 dport 80 或 443 的新连接发送到“mwan3_policy_balanced”链
  • “mwan3_policy_balanced”链在 40% 的数据包上设置标记 200,在其他数据包上设置标记 100
  • “mwan3_rules”链将数据包从不使用 dport 80 或 443 的新连接发送到“mwan3_policy_wan_only”链
  • “mwan3_policy_wan_only”链设置标记 100
  • 我猜标记为 100 的数据包将通过电缆,而标记为 200 的数据包将通过 lte

因此,40% 的 http(s) 流量将通过 lte,60% 通过电缆,其他所有流量将通过电缆。

如果您的目标是对 2 个 ISP 上的连接进行负载平衡,您可能应该从头开始编写自己的 iptables 规则,因为 mwan3 规则很难阅读。

你可以从问题。

祝你好运 !

版:

文档状态:

--set-xmark value[/mask]
    Zero out the bits given by mask and XOR value into the ctmark.

如果您有 0x100 标记,并尝试将 xmark 设置为 0x200/0xff00:

  • 在 ctmark 中,清除掩码给出的位: 0000 0001 0000 0000 AND NOT 1111 1111 0000 0000 --> 0000 0000 0000 0000
  • 将值异或到 ctmark:0000 0000 0000 0000 XOR 0000 0010 0000 0000 --> 0000 0010 0000 0000 --> 0x200 --> 512

如果您有 0x100 标记,并尝试将 xmark 设置为 0x200/0xf000:

  • 在 ctmark 中,清除掩码给出的位: 0000 0001 0000 0000 AND NOT 1111 0000 0000 0000 --> 0000 0001 0000 0000
  • 将值异或到 ctmark:0000 0001 0000 0000 XOR 0000 0010 0000 0000 --> 0000 0011 0000 0000 --> 0x300 --> 768

如果你有0x100标记,并尝试设置xmark 0x100/0xf000:

  • 在 ctmark 中,清除掩码给出的位: 0000 0001 0000 0000 AND NOT 1111 0000 0000 0000 --> 0000 0001 0000 0000
  • 将值异或到 ctmark:0000 0001 0000 0000 XOR 0000 0001 0000 0000 --> 0000 0000 0000 0000 --> 0x000 --> 0

如果你有0x100标记,并尝试设置xmark 0x100/0xff00:

  • 在 ctmark 中,清除掩码给出的位: 0000 0001 0000 0000 AND NOT 1111 1111 0000 0000 --> 0000 0000 0000 0000
  • 将值异或到 ctmark:0000 0000 0000 0000 XOR 0000 0001 0000 0000 --> 0000 0001 0000 0000 --> 0x100 --> 256

在 mwan3 文件中,情况始终是这样的:

  • 你有一个0x0标记,并尝试设置xmark 0x??00/0xff00
  • 在 ctmark 中,清除掩码给出的位: 0000 0000 0000 0000 AND NOT 1111 1111 0000 0000 --> 0000 0000 0000 0000
  • 将值异或到 ctmark: 0000 0000 0000 0000 XOR ???? ???? 0000 0000 --> ???? ???? 0000 0000 --> 0x??00 --> ?
  • 有了这个掩码和这些值,set-xmark 只需替换以前的值

现在,让我们浏览一下链条:

  • 预路由跳转到 mwan3_hook。
  • mwan3_hook 将 connmark 恢复为 mark
  • mwan3_hook 将新连接(标记 = 0x0)发送到 mwan3_ifaces
  • mwan3_ifaces 将新连接发送到 mwan3_iface_wan
  • 当源地址位于 ipset 列表 mwan3_connected 中时,mwan3_iface_wan 将标记 0xff00 设置为来自接口 eth0 的新连接
  • mwan3_iface_wan 将标记 0x100 设置为接口 eth0 上的其他新连接
  • mwan3_ifaces 将新连接发送到 mwan3_iface_lte
  • mwan3_iface_lte 当源地址位于 ipset 列表 mwan3_connected 中时,将标记 0xff00 设置为来自接口 wwan 的新连接
  • mwan3_iface_lte 将标记 0x200 设置为接口 wwan 上的其他新连接
  • 注意:此时,所有传入连接都已标记
  • mwan3_hook 将连接发送到 mwan3_connected
  • 当目标地址在 ipset 列表 mwan3_connected 中时,mwan3_connected 设置标记 0xff00
  • mwan3_hook 将连接发送到 mwan3_track
  • mwan3_track 如果目标 ip 在 ipset 列表 mwan3_track_wan 中,则为连接设置标记 0xff00,该数据包是 32 字节长度的 icmp echo
  • mwan3_track 如果目标 ip 在 ipset 列表 mwan3_track_lte 中,则为连接设置标记 0xff00,数据包是 32 字节长度的 icmp echo
  • mwan3_hook 将连接发送到 mwan3_rules
  • mwan3_rules 将新的 tcp/80 或 tcp/443 连接从内部发送到 mwan3_policy_balanced
  • mwan3_policy_balanced 将标记 0x200 设置为新连接的 40%
  • mwan3_policy_balanced 将标记 0x100 设置给另一个新连接
  • mwan3_hook 将标记恢复为 connmark
  • mwan3_hook 将标记 0xff00 设置为尚未标记的连接(从内部,不是 icmp 类型 8、tcp/80 或 tcp/443)
  • 预路由跳转到 fwmark,但链不在屏幕上
  • 正向修复 mss
  • 输出跳转到mwan3_hook,每一步都重复一遍。

最后,我们有3种状态:

  • 0x100 标记 (256) :来自 wan 的连接,以及 60% 的 http(s) 连接到互联网
  • 0x200 标记 (512):来自 lte 的连接,以及 40% 的 http(s) 连接到互联网
  • 0xff00标记(65280):其他流量

由于我们没有ip规则,我们只能猜测:

  • 0x100标记将经过wan路由表
  • 0x200标记将经过lte路由表
  • 0xff00会经过另一个路由表

相关内容