如何获取重定向UDP报文的原始目的端口?
使用这个东西我可以获得原始目标IP地址socket(PF_INET, SOCK_DGRAM, 0)
套接字。
如何获取原目的港?
Using this thing I can obtain original destination IP address of socket(PF_INET, SOCK_DGRAM, 0)
socket.
How to get original destination port?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
取决于重定向机制。如果您使用 REDIRECT(即底层的 NAT),则需要使用 SO_ORIGINAL_DST 或 libnetfilter_conntrack 在应用 NAT 之前查询连接的原始目标。然而,由于您可以使用同一个侦听器套接字提供多个连接,因此必须对每个数据包进行此查找。
您可以使用 conntrack 命令行工具试验 libnetfilter_conntrack 及其提供的服务。
另一种选择是使用 TPROXY 进行重定向,这本来是在这种情况下使用的。在那里,您可以使用 recvmsg() 使用辅助消息获取数据包的原始目的地。要查找的关键是 IP_RECVORIGDST setsockopt。
有关 TPROXY 的更多信息可以在内核文档目录中名为 tproxy.txt 的文件中找到。它使用起来有点困难,但工作起来更可靠,因为它是由堆栈实现的,而不是包过滤子系统。
编辑:添加如何使用TProxy查询UDP目标地址。
编辑: SO_ORIGINAL_DST 与 udp
SO_ORIGINAL_DST 应该与 udp 套接字一起使用,但是内核不允许您指定连接端点,它将使用您调用 SO_ORIGINAL_DST 的套接字来获取此地址信息。
这意味着只有当 UDP 套接字正确绑定(到重定向到的地址/端口)并连接(到相关客户端)时,它才会起作用。您的侦听器套接字可能绑定到 0.0.0.0,并且不仅为单个客户端提供服务,而且为多个客户端提供服务。
但是,您不需要使用实际的侦听器套接字来查询目标地址。由于 UDP 在建立连接时不会传输数据报,因此您可以创建一个新的 UDP 套接字,将其绑定到重定向地址并将其连接到客户端(您知道该地址,因为它已将第一个数据包发送到您的侦听器)。然后你可以使用这个套接字来运行 SO_ORIGINAL_DST ,但是有罪魁祸首:
基于 TProxy 的方法显然更好。
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.
You can experiment with libnetfilter_conntrack and the services it provides using the conntrack command line tool.
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.
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.
Edited: to add how to query UDP destination addresses with TProxy.
Edited: SO_ORIGINAL_DST vs. udp
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.
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.
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:
The TProxy based method is clearly better.
尝试解析
/proc/net/nf_conntrack
Try parsing
/proc/net/nf_conntrack