为了理解TCP的工作原理,我尝试伪造自己的TCP SYN / SYN-ACK / ACK(基于教程:http://www.thice.nl/creating-ack-get-packets-with-scapy/)。
问题在于,只要我的计算机从服务器接收到SYN-ACK,它就会生成一个RST数据包来停止连接过程。
我尝试使用OS X Lion和Ubuntu 10.10 Maverick Meerkat,都重置了连接。我发现了这个:http://lkml.indiana.edu/hypermail/linux/net/0404.2/0021.html,我不知道是不是这个原因。
有谁能告诉我可能是什么原因?以及如何避免这个问题?
谢谢。
答案 0 :(得分:25)
你引用的文章非常清楚......
由于您没有完成完整的TCP握手,您的操作系统可能会尝试控制并可以开始发送RST(重置)数据包,为避免这种情况,我们可以使用iptables:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.20 -j DROP
基本上,问题是scapy
在用户空间中运行,而linux内核将首先接收SYN-ACK。内核将发送一个RST,因为在你有机会对scapy
做任何事情之前,它不会在有问题的端口号上打开套接字。
解决方案(正如博客所提到的)是防火墙内核发送RST数据包。
答案 1 :(得分:4)
我没有非iptables的答案,但可以解决重置问题。而不是尝试过滤过滤表中的传出重置,而是过滤掉原始表中目标的所有传入数据包。这可以防止来自目标的返回数据包甚至被内核处理,尽管scapy仍然可以看到它们。我使用了以下语法:
iptables -t raw -A PREROUTING -p tcp --dport <source port I use for scapy traffic> -j DROP
这个解决方案确实迫使我为我的流量使用相同的源端口;随意使用自己的iptables-fu来识别目标的返回数据包。
答案 2 :(得分:4)
其他答案中引用的博客文章并不完全正确。这不仅是因为你没有完成三次握手,而且内核的IP堆栈也不知道发生了连接。收到SYN-ACK
后,它会发送RST-ACK
,因为它是意料之外的。接收第一个或最后一个确实没有进入它。堆栈接收 SYN-ACK
是问题所在。
使用IPTables删除出站RST
数据包是一种常见且有效的方法,但有时您需要从Scapy发送RST
。一个更复杂但非常可行的方法是降低,使用与主机不同的MAC生成和响应ARP。这使您能够在不受主机干扰的情况下发送和接收任何内容。
RST
时,我只采用这种方法(而不是RST
丢弃方法)。