我的问题已经大致讨论here。
tl; dr解决方案是:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
您可以将其修改为仅阻止您正在主动收听的端口 但正如上面提到的问题和here中所提到的,这些并不是优雅的解决方案。
现在,我并不关心事物的优雅 但我确实关心学习。所以我深入挖掘了Linux源代码(目前主要对基于Linux的机器感兴趣)并通过我认为的socket.bind方法进行排序,以便找到与指令有关的任何内容“我们”正在主动监视TCP端口的内核。
我假设套接字库告知内核一些特定端口绑定到应用程序的方式,这样内核就不会自动响应RST
数据包到客户端连接,提示< em>“拒绝连接”。
但是,我在源代码中找不到这样的代码 packet手册页也没有告诉我如何通知内核忽略/接受特定端口上的数据包。
我有一个非常basic socket的设置,可以用混杂的模式(这是它自己的故事)来听。
然而,我的问题是,一旦客户端连接,在任何给定的端口上 - 内核按照预期的方式发送传入的Ethernet+IP+TCP
数据帧 - 但它也会立即发出“反转”的响应源端口和目标端口以及RST
标志集。它应该是哪个,但不是我告诉它的特定端口。问题是,我如何告诉内核我正在监视一个特定的端口?
一个选项是(正如其他一些论坛和其他各种SO线程所讨论的那样) - 在该端口上创建一个虚拟套接字。
s = socket()
s.bind(('', <port>))
然而,这会导致一系列其他问题(其中一个问题就是它会有一个很快就会被填充的缓冲区)最重要的是,仍然没有教会我这些魔法是怎样的发生。如果没有其他方法,上述两种解决方案是最后的解决方案,但我觉得我比以往任何时候都更加紧张,因为找到适当的解决方案来解决这个问题。
解决方案或提示可以在 C以及和/ 或内核模块中,只是为了指示内核所需的信息。我知道这一切都在内核中发生了,在下面的评论和非常欣赏的解决方案之后,我现在知道这个问题没有用户空间功能。我可以/轻松地将它移植到cPython模块,或者使用内核模块/扩展可以轻松地将其转换为Python代码。但我真的不知道内核在设置这些内容方面的功能在哪里,或者它们被称为什么。
我挖得很深,很远,很浅..但似乎没有其他人有必要这样做。主要是因为混杂的套接字用于获取流量并对其进行分析。但是.bind((interface, protocol))
也在那里,它面临同样的问题,一种不进入混杂模式的方式,而只是通过执行.bind((interface, 0x0800))
来接收TCP数据包。
我可能会站在这里,但也许man 7 netdevice
只是给了我一个主意。我正在尝试设置SystemTap以检查调用ioctl()
执行的操作以及socket()
对象如何请求文件描述符。可能是一个关于这一切如何下降的线索。棘手的让SystemTap工作。
任何人都有任何其他线索如何解决这个问题或者之前碰到过这个问题?
聚苯乙烯。对于一个模糊的问题我很抱歉,我不知道这些较低级别的东西的正确术语是什么。因为他们对我来说很新鲜。
编辑:我可能一直在寻找bind()
的错误位置,根据ipv4.af_inet实现它将尝试调用套接字bind()
函数,但如果没有,它将会试着在这里设置很多魔法。 here他们在af_inet
cla and and and and and and and .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..
进一步向下挖洞,selinux/hooks.c也包含一些绑定功能。也许更安全相关,但仍值得我调查。仍然没有接近解决这个谜语的地方。
答案 0 :(得分:1)
这里的问题是你要求一种方法告诉内核有效“为我做这100件事,但留下这个特别的细节。”坦率地说,我认为iptables解决方案是最简单,最干净的。
另一个选择是,不要求内核完成所有其他位,而是自己承担更多工作。具体来说,组成您自己的IP地址,并开始使用它。唯一的缺点是你必须接管内核为你做的另一件重要事情:响应ARP(ARP用于发现拥有给定IP地址的站的MAC [以太网]地址)。简而言之,我建议你:
如果您使用的MAC地址不是分配给该接口的MAC地址,您当然必须进行混杂捕获。这是非常典型的原始数据包套接字。此外,您将为所有流量构建以太网报头,IP报头和TCP报头(以及ARP请求的以太网+ ARP),这样您将学到很多东西。