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

Mik*_*kov 4 routing iptables openwrt

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

iptables -t mangle -A POSTROUTING -p tcp -m multiport --dports 80,443 -j MARK --set-mark 2
Run Code Online (Sandbox Code Playgroud)

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

ipv4     2 tcp      6 3706 ESTABLISHED ... mark=2
Run Code Online (Sandbox Code Playgroud)

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

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

在此处输入图片说明

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

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

小智 6

目标“-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
Run Code Online (Sandbox Code Playgroud)

但是,如果您在主链(例如 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.
Run Code Online (Sandbox Code Playgroud)

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

  • 在 ctmark 中,清除掩码给出的位:0000 0001 0000 0000 AND NOT 1111 1111 0000 0000 --> 0000 0000 0000 0000
  • XOR值进入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
  • XOR 值进入 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
  • XOR 值进入 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
  • XOR 值进入 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
  • XOR 值进入 ctmark: 0000 0000 0000 0000 XOR ???? ???0000 0000 --> ???? ???0000 0000 --> 0x??00 --> ?
  • 使用这个掩码和这些值,set-xmark 只是替换以前的值

现在,让我们通过链:

  • 预路由跳转到 mwan3_hook。
  • mwan3_hook 将 connmark 恢复为标记
  • mwan3_hook 将新连接(标记 = 0x0)发送到 mwan3_ifaces
  • mwan3_ifaces 将新连接发送到 mwan3_iface_wan
  • 当源地址在 ipset 列表中时,mwan3_iface_wan 将标记 0xff00 设置为来自接口 eth0 的新连接 mwan3_connected
  • mwan3_iface_wan 将标记 0x100 设置为接口 eth0 上的其他新连接
  • mwan3_ifaces 将新连接发送到 mwan3_iface_lte
  • mwan3_iface_lte 将标记 0xff00 设置为来自接口 wwan 的新连接,当源地址在 ipset 列表中时 mwan3_connected
  • mwan3_iface_lte 将标记 0x200 设置为接口 wwan 上的其他新连接
  • 注意:此时,所有传入的连接都被标记
  • mwan3_hook 将连接发送到 mwan3_connected
  • mwan3_connected 当目的地址在 ipset 列表中时设置标记 0xff00 mwan3_connected
  • mwan3_hook 将连接发送到 mwan3_track
  • mwan3_track 将标记0xff00 设置为连接,如果目的ip 在ipset 列表中 mwan3_track_wan,则数据包为32 字节长度的icmp echo
  • mwan3_track 设置标记 0xff00 为连接,如果目的 ip 在 ipset 列表中 mwan3_track_lte,数据包是 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 type 8、tcp/80 或 tcp/443)
  • Prerouting跳转到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 将通过另一个路由表