路由策略数据库未检测到标记的数据包

路由策略数据库未检测到标记的数据包

mangle我在实验室服务器中有一个下表规则,1如果目标地址为6.6.6.6

$ sudo iptables -t mangle -L PREROUTING 2 -v -n --line-numbers
2       17   884 MARK       udp  --  ge-0.0.0-Iosv6 *       0.0.0.0/0            6.6.6.6              MARK set 0x1
$

6.6.6.6/32lo在该服务器上配置。每次我执行tracerouteto时6.6.6.6,上面的规则计数器都会增加,这是预期的。换句话说,数据包似乎被标记了。我的路由策略数据库如下所示:

$ ip rule show
0:      from all lookup local
32764:  from all fwmark 0x2 lookup twohundred
32765:  from all fwmark 0x1 lookup threehundred
32766:  from all lookup main
32767:  from all lookup default
$

..表格threehundred如下所示:

$ ip r sh table threehundred
default via 192.168.100.2 dev ge-0.0.0-Iosv6
$

但是,标记的数据包不是根据 table 中的条目进行路由的threehundred,而是根据 table 中的条目进行路由的main。我可以通过 确认tcpdumpUDP 数据包通过 进入服务器ge-0.0.0-Iosv6,但 ICMPport unreachable回复是通过与表eth0中的默认路由关联的发送出去的main。正如我之前提到的,manglePREROUTING规则 #2 在此期间递增。

什么可能导致这种行为?我正在运行 Ubuntu 16.04.6 LTS。

答案1

这是一个Netfilter 和通用网络中的数据包流示意图:

Netfilter 和通用网络中的数据包流

虽然入口数据包在 PREROUTING 中被标记,但本地生成的回复数据包确实通过 OUTPUT 出去:没有规则在那里标记它,所以没有标记并且路线不同。

更改 mangle/OUTPUT 中的数据包(包括更改标记等元信息)会触发重新路由检查。此重新路由应将路由从以太网0ge-0.0.0-Iosv6(注:与nftables代替iptables, 专用的路线需要链式才能达到此效果)。这条规则将做到这一点:

iptables -t mangle -A OUTPUT -s 6.6.6.6 -j MARK --set-mark 1

无需以两种方式用特定规则标记独立的数据包,而是可以自动标记整个流(如连线)。这康马克比赛及其康马克可以使用目标对应物。该博客给出了使用示例:Netfilter康马克

对于这种情况,而不是iptables上面的规则:

  • 应该是 mangle/PREROUTING 中的最后一条规则:

    iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j CONNMARK --save-mark
    
  • 应该是 mangle/OUTPUT 中的第一个规则,因此如果需要它仍然可以更改。这将触发重新路由检查:

    iptables -t mangle -I OUTPUT -m connmark ! --mark 0 -j CONNMARK --restore-mark
    

还有一些需要了解和注意事项,如果不进行测试就很难可靠地预测:

  • 切换fwmark_reflect(例如sysctl -w net.ipv4.fwmark_reflect=1:)对于这种特定情况可能已经足够了,并且可以用来代替上面的规则,但对于更一般的情况没有帮助。同样还有tcp_fwmark_accept以缓解 TCP 情况。其他协议(例如 UDP)没有类似的协议。

  • 有时路线会失败重新路由检查是因为严格反向路径转发并且数据包在有机会被标记和重新路由之前就被提前丢弃。显然,这里的情况并非如此(SRPF 甚至可能未启用),但如果发生这种情况,也应该通过更改来放松检查,在涉及的接口之一上进行松散模式(需要进行测试以确定是哪一个)rp_filter设置(例如:sysctl -w net.ipv4.conf.eth0.rp_filter=2)。

  • 有时还有一些额外的路线主要的表必须在附加表中复制,因为在回退到之前先读取它主要的表并可能不匹配。很难弄清楚何时需要它,尤其是当分数都参与其中。例如:

    ip route add table threehundred 192.168.100.2/32 dev ge-0.0.0-Iosv6
    
  • ip route get ...即使提供了足够的命令,该命令mark似乎也并不总是准确地预测当前发生的情况分数iptables都参与其中。

  • 与标记、路线和预测之间的交互相关的行为ip route get可以通过未记录的内容进行更改src_valid_mark切换(也可通过sysctl)。仅当它看起来可以解决问题时才使用它。

  • 可以发现,策略路由情况下的 UDP 服务器行为与 TCP 服务器行为不同,原因复杂且难以解释。使用分数只能增加复杂性。

相关内容