如何获取redirectUDP消息的原始目的端口?

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

如何获得原始目标端口?

Solutions Collecting From Web of "如何获取redirectUDP消息的原始目的端口?"

取决于重定向机制。 如果您使用的是REDIRECT(即NAT下的NAT),则在应用NAT之前,您需要使用SO_ORIGINAL_DST或libnetfilter_conntrack查询连接的原始目标。 但是,由于您可以为同一个侦听器套接字提供多个连接,因此必须对每个数据包进行查找。

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

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

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

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

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

编辑: SO_ORIGINAL_DST与udp

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

这意味着只有在UDP套接字被正确绑定(连接到重定向到的地址/端口)和连接到(有问题的客户端)的情况下才能工作。 您的侦听器套接字可能被绑定到0.0.0.0,并且不仅仅服务于单个,而是多个客户端。

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

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

基于TProxy的方法显然更好。

尝试解析/proc/net/nf_conntrack