nftables:特定目标 IP:端口到(第二个)目标 IP:端口的重复 UDP 数据包

nftables:特定目标 IP:端口到(第二个)目标 IP:端口的重复 UDP 数据包

我只想将发往单个 IP 和 UDP 端口的非常有限的数据包流量镜像到同一 IP 但第二个端口。我已经锁定在https://superuser.com/questions/1593995/iptables-nftables-forward-udp-data-to-multiple-targets但似乎 nftable 的 dup 语句只允许复制到另一个 IP,但不允许复制到相同的 IP 和不同的端口。

例如,流向 127.0.0.1 端口 123 的流量应复制到 127.0.0.1 端口 456。由于这是唯一的一次重复,因此我不会遇到原始端口号丢失的任何问题。现在我想知道这种复制是否可能,因为 127.0.0.1 不是“排水”/传出接口,而是复制的最终目的地。是否有某种方法可以将其与 DNAT 结合起来?

除了将 eBPF 探针附加到带有传入 UDP 流量的 netdev 之外,是否还有其他可用的机制?

答案1

这可以通过以下方式完成nftables网络开发者家庭与入口链条和一个重复陈述。它需要使用标记来避免无限循环。根据具体的用例,复制也可以在出口(因为它位于环回界面,重复的出口数据包将显示为入口)但这需要内核 >= 5.17 才能支持,而入口已经可用很长时间了。

需要内核 >= 4.10(用于无状态 UDP 更改正确校验和支持)。

# nft -f - <<'EOF'
table netdev t_dup        # for idempotency
delete table netdev t_dup # for idempotency

table netdev t_dup {
    chain c_ingress {
        type filter hook ingress device "lo" priority filter; policy accept;
        iif lo udp dport 123 meta mark != 1 meta mark set 1 dup to lo udp dport set 456
    }
}
EOF
  • 检查候选数据包是否有标记,只有在没有标记的情况下才进行处理,首先设置标记:这将防止稍后出现循环。

  • 它是重复的。该标记是复制品的一部分sk_buff, 也是重复的

    重复的数据包实际上是未更改的数据包:发送到同一位置 ( lo) 以及端口 123

  • dup声明,与任何相反iptables' 目标,包括它的TEE目标,不是一个规则终止语句。规则继续对数据包进行无状态更改:UDP 端口更改为 456

  • 重复的数据包也到达入口但正如它所标记的,规则会忽略它:循环被阻止

可以使用以下命令测试重复的端口索卡特

socat -u udp4-recv:456,bind=127.0.0.1 -

笔记:

  • 如果复制的端口上没有任何监听,则会发出 ICMP 端口不可达,但由于此端口 (456) 与发送应用程序发送到的端口 (123) 不匹配,因此网络堆栈将忽略它。

  • 网络过滤器入口发生在 AF_PACKET 之后,tcp转储不会捕获更改的端口或重复的数据包。

答案2

我需要对 netflow/IPFix 数据包执行此操作。我尝试了你的解决方案,但它对我来说不起作用。

然而,受到你的启发和另一个答案,我最终得到了一个可以工作的。经测试可在内核 5.10 的 Debian 11 上运行:

table ip mangle
delete table ip mangle

table ip mangle {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;
        iifname "eth0" udp dport 6660 \
      dup to 127.0.0.1 device lo udp dport set 6666 notrack \
      dup to 127.0.0.1 device lo udp dport set 6667 notrack \
      dup to 127.0.0.1 device lo udp dport set 6668 notrack
    }

    chain input {
        type filter hook input priority mangle; policy accept;
        iifname lo udp dport 6666 ip daddr set 127.0.0.1 notrack
        iifname lo udp dport 6667 ip daddr set 127.0.0.1 notrack
        iifname lo udp dport 6668 ip daddr set 127.0.0.1 notrack
    }
}

这会将到达 eth0 的 UDP/6660 的任何内容复制到本地主机 UDP 端口 6666、6667 和 6668,并将目标设置为 127.0.0.1。需要后者是因为有些软件不喜欢它。

我已经测试过这个Fastnetmon,转储文件/nfsen 和AS统计

相关内容