gpt4 book ai didi

linux - 如何获取重定向 UDP 消息的原始目标端口?

转载 作者:IT王子 更新时间:2023-10-29 00:06:32 27 4
gpt4 key购买 nike

使用 this thing我可以获得 socket(PF_INET, SOCK_DGRAM, 0) 套接字的原始目标 IP 地址。

如何获取原始目的端口?

最佳答案

取决于重定向机制。如果您使用的是 REDIRECT(底层是 NAT),那么您需要使用 SO_ORIGINAL_DST 或 libnetfilter_conntrack 来查询应用 NAT 之前连接的原始目的地。但是,由于您可以使用同一个监听器套接字提供多个连接,因此必须为每个数据包执行此查找。

您可以使用 conntrack 命令行工具试验 libnetfilter_conntrack 及其提供的服务。

另一种方法是使用 TPROXY 进行重定向,这是为了在这种情况下使用。在那里,您可以使用 recvmsg() 使用辅助消息获取数据包的原始目的地。要查找的关键是 IP_RECVORIGDST setsockopt。

有关 TPROXY 的更多信息可以在内核文档目录中的一个名为 tproxy.txt 的文件中找到。它使用起来有点困难,但工作起来更可靠,因为它是由堆栈实现的,而不是包过滤子系统。

已编辑:添加如何使用 TProxy 查询 UDP 目标地址。

  1. 打开一个 UDP 套接字,将其绑定(bind)到 0.0.0.0 或更具体的 IP
  2. 您通过 setsockopt(fd, SOL_IP, IP_RECVORIGDSTADDR, ...) 启用 IP_RECVORIGDST
  3. 您使用 recvmsg() 而不是 recvfrom()/recv() 来接收帧
  4. recvmsg() 将返回数据包和一系列辅助消息,
  5. 迭代辅助消息,并找到级别为 SOL_IP、索引为 IP_ORIGDSTADDR 的 CMSG block
  6. 此 CMSG block 将包含一个包含 IP 和端口信息的 struct sockaddr_in。

已编辑:SO_ORIGINAL_DST 与 udp

SO_ORIGINAL_DST 应该与 udp 套接字一起使用,但是内核不允许您指定连接端点,它将使用您调用 SO_ORIGINAL_DST 的套接字来获取此地址信息。

这意味着只有当 UDP 套接字被正确绑定(bind)(到重定向到的地址/端口)并连接到(到有问题的客户端)时,它才会工作。您的监听器套接字可能绑定(bind)到 0.0.0.0,并且不仅为单个客户端提供服务,而且为多个客户端提供服务。

但是,您不需要使用实际的监听器套接字来查询目标地址。由于 UDP 不在连接建立时传输数据报,因此您可以创建一个新的 UDP 套接字,将其绑定(bind)到重定向地址并将其连接到客户端(自从它向您的监听器发送第一个数据包以来您就知道其地址)。然后你可以使用这个套接字来运行 SO_ORIGINAL_DST,但是有罪魁祸首:

  1. 一旦你打开这样一个套接字,内核会更喜欢客户端在第一个数据包之后发送额外的数据包,而不是你的监听器套接字
  2. 这本质上是活泼的,因为当您的应用程序有机会调用 SO_ORIGINAL_DST 时,conntrack 条目可能已经超时。
  3. 它很慢而且开销很大

基于 TProxy 的方法显然更好。

关于linux - 如何获取重定向 UDP 消息的原始目标端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5615579/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com