- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试从已通过 iptables TPROXY 规则重定向的 UDP 数据包中获取原始目的地。然而,有几种方法都失败了,使用原始套接字从 IP header 中获取数据包似乎是乱码。
混淆实际上是双重的。后一个小数据包是通过 SOCK_DGRAM 获得的 UDP 有效载荷,但是将其更改为 SOCK_RAW 会返回此乱码,其中不包含有效载荷的痕迹,也不包含 IP header 。
错误的东西:
Port: 0 -- 45 00 00 48 1c ac 00 00 6e 11 7b f6 1b 46 8b 53 8b 63 82 06 69 7d 69 b4 00 34 29 5f 00 ba 03 00 47 20 01 00 30 2b ca 00 01 7d 8d 58 e8 89 88 0e 60 7f ee 00 c0 0b e3 01 00 00 00 00 00 00 00 06 0d e3 01 80 83 06 85 80 received 74 bytes
正确的负载:端口:0 -- ff ff ff ff 55 4b a1 d5 77 收到 9 个字节
未受 TPROXY 影响的正确原始数据包如下所示:
45-00-00-65-17-4B-40-00-3A-11-46-F8-2D-23-01-BA-4E-9F-64-C9-69-CD-26-8F-00-51-C2-C9-FF-FF-FF-FF-52-4C-20-30-36-2F.....
FF-FF-FF-FF-5x
是所需负载的开始,端口位于 69CD。
由于 C# 似乎没有显然需要 TPROXY 工作所需的 IP_TRANSPARENT 标志,我已经转移到 C/C++ 套接字代码,我尝试为 IP_TRANSPARENT、IP_RECVORIGSTDADDR、IP_HDRINCL 设置套接字选项。
我从 recvfrom 更改为 recvmsg 和 msghdrs,以便尝试循环遍历辅助数据以从 sockaddr_in 结果中获取 sin_port。我从不同的 SO 问题中拼凑了很多尝试,诚然,我真的不知道在这个级别的套接字代码中发生了什么,像 cmsghdr、cmsg、msghdr、iovecs 等对我来说都是新的。这里似乎没有任何作用,无论 TPROXY 对这些数据包做了什么,它们无论如何都无法使用。
下面是获取数据包、打印十六进制并尝试获取端口的内容(无论如何结果都是 0)
recvlen = recvmsg(fd, &message, 0);
printf("received %d bytes\n", recvlen);
for (cmsghdr *cmsg = CMSG_FIRSTHDR(&message); cmsg != NULL; cmsg = CMSG_NXTHDR(&message, cmsg))
{
if (cmsg->cmsg_level != SOL_IP || cmsg->cmsg_type != IP_ORIGDSTADDR) continue;
printf("copying port\n");
std::memcpy(&dstIpAddr, CMSG_DATA(cmsg), sizeof(sockaddr_in));
dstPort = ntohs(dstIpAddr.sin_port);
}
printf("Port: %i -- ", dstPort);
//std::cout << "Destination port: " << dstPort << std::endl;
for (int i = 0; i < recvlen; i++)
{
printf("%02x ", buf[i]);
}
iptables 规则将匹配十六进制字符串的数据包重定向到此套接字绑定(bind)到的端口:
TPROXY udp -- anywhere anywhere udp dpts:27000:28000 STRING match "|ffffffff54|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1
TPROXY udp -- anywhere anywhere udp dpts:27000:28000 STRING match "|ffffffff55|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1
TPROXY udp -- anywhere anywhere udp dpts:27000:28000 STRING match "|ffffffff56|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1
TPROXY udp -- anywhere anywhere udp dpts:27000:28000 STRING match "|ffffffff57|" ALGO name bm TO 65535 TPROXY redirect 0.0.0.0:29000 mark 0x1/0x1
我只需要获取目标地址:端口,以便转发流量以有条件地将其转发到它应该去的地方,并将结果发回。如果我可以使用 UDP 套接字执行此操作并以某种方式获取有效负载,然后从某些函数获取端口,fab。如果我必须获取原始数据包然后从 IP header 中获取它,那也没关系,除非我不能,因为 TPROXY 似乎在混淆这些数据包。
最佳答案
我相信我通过 sizeof(buffer)
将 iov_len 设置为 const char*
的大小,因此基本上没有可写空间。在摆弄声明并以此结束后,我使用 cmsg 循环正确获得了 IP 和端口。我仍然不知道为什么 TPROXY 在通过原始套接字查看数据包时会扭曲数据包,这很有趣。
iov.iov_base = cPacket;
iov.iov_len = BUFSIZE;
mHeader.msg_name = &sSourceAddr; //sockaddr_storage
mHeader.msg_namelen = sizeof(struct sockaddr_in);
mHeader.msg_iov = &iov;
mHeader.msg_iovlen = 1;
mHeader.msg_control = cControl;
mHeader.msg_controllen = BUFSIZE;
for (cmsghdr *cmsg = CMSG_FIRSTHDR(&mHeader); cmsg != NULL; cmsg = CMSG_NXTHDR(&mHeader, cmsg))
{
if (cmsg->cmsg_level != SOL_IP || cmsg->cmsg_type != IP_ORIGDSTADDR) continue;
std::memcpy(&sDestIP, CMSG_DATA(cmsg), sizeof(sockaddr_in));
iPort = ntohs(sDestIP.sin_port);
sAddress = sDestIP.sin_addr;
}
关于c - 获取 UDP 目标地址 :Port from TPROXY'd Traffic,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56727876/
我开始怀疑 iptables 是否无法做到这一点,但我想透明地将 https 重定向到 redsocks(代理)服务器。 设置是这样的。我在 boot2docker 中,想要使用需要身份验证的上游代理
我正在为特定应用程序使用用户空间 tcp/ip 堆栈。 我在 Linux 内核空间堆栈中看到 Tproxy 支持作为内核模块。 但我需要在用户空间堆栈中进行类似的实现。 这样我就可以了解tproxy当
我正在尝试了解 TPROXY 的工作原理,以便为 Docker 容器构建透明代理。 经过大量研究,我设法创建了一个网络命名空间,向其中注入(inject)了一个 veth 接口(interface)并
我正在路由器上开发一种“监控流量”类型的应用程序,其中我使用 TPROXY 功能来拦截 DNS 数据包并将其发送到监听端口的应用程序服务器。处理后,我修改 TTL 后将数据包转发到实际目的地(即 dn
我打算使用 iptables 的 TPROXY 目标将一些 UDP 数据包重定向到原始套接字,但套接字不会收到任何数据包。它与 UDP 一起工作 socket 。我是不是遗漏了什么或者原始套接字无法接
使用最新的 TPROXY 和 Linux 内核,我如何获取远程/目标计算机的 IP 地址?我假设本地/源端点是从 accept() 返回的。 最佳答案 原始(重新路由之前)远程目标将位于 getsoc
我正在 Linux 上开发某种透明代理的概念验证。 透明代理拦截 TCP 流量并将其转发到后端。我用 https://www.kernel.org/doc/Documentation/networki
我是一名优秀的程序员,十分优秀!