如何获取重定向的UDP消息的原始目标端口? [英] How to get original destination port of redirected UDP message?

查看:629
本文介绍了如何获取重定向的UDP消息的原始目标端口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用这东西我可以获取原始内容socket(PF_INET, SOCK_DGRAM, 0)套接字的目标IP地址.

Using this thing I can obtain original destination IP address of socket(PF_INET, SOCK_DGRAM, 0) socket.

如何获取原始目标端口?

How to get original destination port?

推荐答案

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

Depends on the redirection mechanism. If you are using REDIRECT (which is NAT under the hood), then you need to use SO_ORIGINAL_DST, or libnetfilter_conntrack to query the original destination of the connection before NAT was applied. However since you can serve several connections with the same listener socket, this lookup has to be done for every packet.

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

You can experiment with libnetfilter_conntrack and the services it provides using the conntrack command line tool.

一种替代方法是使用TPROXY进行重定向,这是在这种情况下使用的.在那里,您可以使用recvmsg()使用辅助消息获得数据包的原始目标.寻找的关键是IP_RECVORIGDST设置ockock.

An alterntive is to use TPROXY for the redirection, which was meant to be used in cases like this. There you can get the original destination of the packet using an ancillirary message using recvmsg(). The key to look for is the IP_RECVORIGDST setsockopt.

有关TPROXY的更多信息可以在内核文档目录的tproxy.txt文件中找到.它有点难用,但由于它是由堆栈而不是数据包筛选子系统实现的,因此工作更可靠.

More information on TPROXY can be found in the kernel Documentation directory, in a file called tproxy.txt. It is a bit difficult to use, but works more reliably as it is implemented by the stack, rather than the packet filtering subsystem.

已编辑:添加使用TProxy查询UDP目标地址的方法.

Edited: to add how to query UDP destination addresses with TProxy.

  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,索引为IP_ORIGDSTADDR的CMSG块
  6. 此CMSG块将包含一个结构sockaddr_in,其中包含IP和端口信息.

已编辑:SO_ORIGINAL_DST与udp

Edited: SO_ORIGINAL_DST vs. udp

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

SO_ORIGINAL_DST should work with udp sockets, however the kernel doesn't let you specify the connection endpoints, it'll use the socket that you call SO_ORIGINAL_DST on to get this address information.

这意味着,仅当UDP套接字正确绑定(绑定到重定向到的地址/端口)并连接(连接到有关的客户端)时,它才起作用.您的侦听器套接字可能已绑定到0.0.0.0,并且不仅为单个客户端提供服务,而且还为多个客户端提供服务.

This means that it'll only work, if the UDP socket is properly bound (to the redirected-to address/port) and connected (to the client in question). Your listener socket is probably bound to 0.0.0.0 and is servicing not just a single, but mulitple clients.

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

However, you don't need to use your actual listener socket to query the destination address. Since since UDP doesn't transmit datagrams on connection establishment, you can create a new UDP socket, bind it to the redirect address and connect it to the client (whose address you know since it sent the first packet to your listener anyway). Then you could use this socket to run SO_ORIGINAL_DST on, however there are culprits:

  1. 打开这样的套接字后,内核会更喜欢如果客户端在第一个套接字之后发送其他数据包,而不是侦听器套接字
  2. 这本质上是合理的,因为到您的应用程序有机会调用SO_ORIGINAL_DST时,conntrack条目可能已超时.
  3. 这很慢,而且开销很大

基于TProxy的方法显然更好.

The TProxy based method is clearly better.

这篇关于如何获取重定向的UDP消息的原始目标端口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆