使用python原始套接字的TCP握手

使用python原始套接字的TCP握手,python,linux,tcp,network-programming,raw-sockets,Python,Linux,Tcp,Network Programming,Raw Sockets,我正在使用python原始套接字实现TCP握手。然而,Linux内核非常烦人,因为它试图处理该协议的某些方面 例如,当我发送SYN数据包时,服务器用SYN,ACK数据包进行响应;内核通过重置连接的RST数据包自动响应。我克服了这一问题,使用以下iptable规则丢弃了所有此类重置数据包: -A OUTPUT -p tcp -m tcp --sport 999 --tcp-flags RST RST -j DROP 现在我想接收服务器发送的SYN,ACK数据包并打印出来。但当我做以下事情时,我什

我正在使用python原始套接字实现TCP握手。然而,Linux内核非常烦人,因为它试图处理该协议的某些方面

例如,当我发送SYN数据包时,服务器用SYN,ACK数据包进行响应;内核通过重置连接的RST数据包自动响应。我克服了这一问题,使用以下iptable规则丢弃了所有此类重置数据包:

-A OUTPUT -p tcp -m tcp --sport 999 --tcp-flags RST RST -j DROP
现在我想接收服务器发送的SYN,ACK数据包并打印出来。但当我做以下事情时,我什么也得不到:

a = self.s.recvfrom(4096)

我怀疑内核在我使用套接字接收SYN,ACK之前丢弃了它。有人知道合理的解决方法吗

虽然我希望有人能想出一个更方便的解决方案,但其中一种方法是使用iptables将传入的TCP-Syn数据包传递给服务器。Nfqueue有现有的python,所以使用它应该不是问题

其思想是在到达内核的TCP实现之前捕获所有传入的TCP SYN。然后将这些数据包传递到您的userland应用程序可以监视的nfqueue。对于您的应用程序将从nfqueue获得的每个数据包,它必须决定()是处理数据包本身(即,就操作系统而言,丢弃数据包)还是将其传递给常规TCP实现


我知道这个方法是有效的,但它很麻烦

您可以使用libpcap,在Python中,它似乎是这个模块:或者这个模块:

使用pcap,您可以注册以接收来自内核的消息。通过从应用程序提供正确的过滤器,您可以从内核接收TCP段。我已经在C中使用了libpcap,我想您可以用同样的方式使用指定的模块。对我来说,这是最好的解决方案,因为您可以从应用程序以相当标准的方式处理它


为了避免内核使用RST进行响应,您的iptables解决方案看起来是最适合我的解决方案。

既然您是用原始数据包自己完成这项工作的,为什么不创建自己的MAC地址和IP地址呢?您需要将适配器置于混杂模式以接收数据包,但如果您这样做,内核不应该向传入的数据包发送任何响应,因为这些数据包似乎是发往“其他系统”的。这使得从别人那里过滤你关心的数据包变得很简单


您还需要适当地响应ARP,以便其他系统找到您的MAC地址。如果你需要DHCP来获取IP地址,你也需要处理这些交互。scapy是否能够恢复并解析SYN,ACK?我相信这个数据包是由KernelI丢弃的,我不知道,我建议它作为一个可能的更高级别的库,你可以使用(或至少可以从中学习),而不是试图从头开始做它。@JohnZwinck我验证了scapy在做什么。它似乎实现了一种数据包捕获方法,类似于下面rodolk所建议的。这听起来是对我来说最合理的解决方案。