New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在Windows上使用的可能性 #2

Open
linhua55 opened this Issue Jan 30, 2017 · 8 comments

Comments

Projects
None yet
2 participants
@linhua55

linhua55 commented Jan 30, 2017

@Chion82
关于在windows上运行的可能性, 分享一下最近 看 net-speeder 和 finalSpeed 源码的心得:

net-speeder 使用了 pcap来接收,使用libnet来发送。 net-speeder支持openvz (Cooked packet/mode),因此libnet应该也支持openvz

而finalSpeed 统一使用 pcap来接收和发送,但pcap的发送不支持openvz(Cooked packet/mode)。 因此在openvz上finalSpeed只支持UDP mode,不支持 TCP mode。
https://github.com/the-tcpdump-group/libpcap/blob/f8198434d6d0b1016ee597a7c64723b1b1c48333/pcap-linux.c#L2064
https://wiki.wireshark.org/SLL

而finalSpeed的 TCP mode 的实现, 就是 使用了 绕过内核协议栈 的技术。 在linux机器上使用iptables (drop)来绕过。而在Windows机器上,Windows xp 和 Windows 2003使用 ipseccmd.exe , 而在其他Windows机器上使用 netsh命令。
详细命令可见:
https://github.com/91yun/finalspeed/blob/master/src/net/fs/server/FSServer.java#L171
https://github.com/91yun/finalspeed/blob/master/src/net/fs/server/FSServer.java#L234

@Chion82

This comment has been minimized.

Owner

Chion82 commented Jan 30, 2017

感谢分享。后续可以考虑使用libpcap来实现。目前该项目仍在开发中,尚有些问题待解决,特别是需要接入mux层。目前暂时只支持linux平台,待时机成熟的时候会考虑进行windows兼容。

再次感谢你的分享。

@Chion82

This comment has been minimized.

Owner

Chion82 commented Jan 31, 2017

刚才尝试了一下,如果不绕过内核,内核会发RST包,但是仍然能够使用(程序会对包做协议头验证),不过会大大降低带宽载荷,另外如果广域网中间路由器对RST包做检测,也可能会切断伪TCP连接。

@linhua55

This comment has been minimized.

linhua55 commented Jan 31, 2017

@Chion82
不绕过内核,只在 在客户端获取不到管理员/root权限的 情况下,才有意义,像未root的手机。但raw/packet socket也需要管理员/root权限。 中间路由器主动切断伪TCP连接也是用发送RST包的方式吧,只要中间路由器 不封端口/ip 或者 按协议丢包(此时需要混淆成http/https流量) 就不影响。

@Chion82

This comment has been minimized.

Owner

Chion82 commented Feb 1, 2017

@linhua55 是的,这只是一个尝试,实际使用肯定还是要想办法绕过内核的。需要移植的话还有很多的工作需要做。btw,中间路由器在切断连接的时候除了发RST还会撤销NAT映射关系,在客户端心跳检测逻辑中有自动更换端口的设定,在NAT失效后可以重新选择随机端口尝试建立新的NAT通道。

@linhua55

This comment has been minimized.

linhua55 commented Feb 3, 2017

It needs to bypass the kernel, since normally the TCP stack there will intercept any incoming packets and reset the connection. So we listen on a fake IP address and send gratuitous ARPs to the router. This is why curl.py needs your network interface and a fake IP address.
Sometimes the ARP spoofing or sniffing doesn't quite work. Usually if I run it 5 times it will work.

https://github.com/jvns/teeceepee
http://jvns.ca/blog/2014/08/12/what-happens-if-you-write-a-tcp-stack-in-python/
https://news.ycombinator.com/item?id=8167546

这个是 将计算机和一个假IP绑定,因此需要手动发送 ARP 包到路由器(ARP污染),从而将计算机网卡的MAC地址和这个假IP绑定。以让路由器接收到 发送给假IP的数据包后,转发给 这个计算机网卡。 然后需要用这个假IP来发送数据包 而本计算机中正常的内核TCP协议栈接收到发送给这个假IP的数据包后,不会进行处理(发RST包)。

可能 虚拟机的 桥接网卡 模式,也是这样(ARP投毒)实现的

@Chion82

This comment has been minimized.

Owner

Chion82 commented Feb 4, 2017

这确实是一个不错的方法。在路由器上查询ARP缓存表,虚拟机和实体机的IP对应的是同一个MAC地址,看来桥接网卡确实是通过ARP投毒实现的。

@linhua55

This comment has been minimized.

linhua55 commented Feb 12, 2017

理解错了,虚拟机 桥接网卡 使用的MAC地址是虚拟机自己的MAC地址,不是主机的MAC地址
在路由器中 绑定的 是: MAC地址和 端口(LAN口) (这个不是ARP表) 可能是多个MAC地址对应一个端口(LAN口),相当于 路由器的一个LAN口下面接了一个交换机 , 实际应该是 路由器接收到远端发来的一个包后 先查询NAT表,找到本地目标IP,再根据 本地目标IP查询ARP表,找到本地目标机器MAC地址,再根据 本地目标机器MAC地址 查询 上面这个 表 来决定 应该从哪个端口(LAN口)发出去

@Chion82

This comment has been minimized.

Owner

Chion82 commented Feb 12, 2017

事实上我的路由器(是软路由)只有一个LAN口,下面接的是交换机再接电脑,所以在我的路由器上不存在物理端口和电脑的MAC直接对应的关系表。我是在路由器上使用arp -n命令查询的,发现物理机和虚拟机确实是不同ip对应相同的MAC(都为物理机网卡的MAC),而其他客户端(另外的电脑和手机)都是不同IP对应不同的MAC。当然,虚拟机在dhcp握手阶段提交的是虚拟机的网卡MAC地址(可能是因为dhcp是在udp层提交MAC地址而不是dhcp服务器直接从链路层获取MAC的缘故?只是猜测,我并没有了解过dhcp协议报文),才能避免物理机和虚拟机分配到相同的IP。我认为应该还是发生了arp投毒。至于MAC地址和物理端口的缓存关系表是存在的,这个表应该是在家用路由器(即NAT路由器+交换机)的交换部分逻辑中。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment