gpt4 book ai didi

python - 使用套接字AF_PACKET/SOCK_RAW,但告诉内核不要发送RST

转载 作者:太空狗 更新时间:2023-10-29 12:23:46 35 4
gpt4 key购买 nike

我的问题已被here粗略地讨论过。

而tl; dr解决方案是:

iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP

您可以修改此设置,以仅阻止您正在积极监听的端口。
但是,正如上面的问题和 here所提到的,这些并不是优雅的解决方案。

现在,我不太在乎事物的优雅。
但是我确实很在乎学习。因此,我深入研究了Linux源代码(目前主要对基于Linux的机器感兴趣),并按照我认为的 socket.bind方法进行了排序,以便找到与指示内核“我们”正在积极监视TCP的内容有关的任何内容。港口。

我假设套接字库告知内核有关如何将特定端口绑定(bind)到应用程序的信息,这样内核就不会自动以 RST数据包响应客户端连接,并提示“连接被拒绝”。

但是,我在源代码中找不到这样的代码。
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进行敲击,并造成了很多表垃圾。.我仍然没有找到解决方案,但可能还在前进……或者更糟的是,又一次追捕鹅。

在兔子洞的更深处, selinux/hooks.c也包含一些绑定(bind)功能。也许与安全性有关,但仍然值得我调查。仍然没有办法解决这个令人毛骨悚然的难题。

最佳答案

这里的问题是,您正在寻求一种方法来告诉内核实际上是“为我做这100件事,但是省去了一个特定的细节”。坦白地说,我认为iptables解决方案是最简单,最干净的。

但是,另一种选择是不要求内核执行所有其他操作,而是自己承担更多工作。具体来说,请建立您自己的IP地址,然后开始使用它。唯一的缺点是您必须接管内核为您所做的另一项重要工作:响应ARP(ARP用于发现拥有给定IP地址的站点的MAC [Ethernet]地址)。简而言之,我建议您:

  • 在您的本地子网中选择一个未使用的IP地址。
  • 组成一个MAC地址供您使用。 (并非绝对必要,但可以更轻松地区分“您的”流量。)
  • 打开一个原始数据包套接字,而不是原始IP套接字(https://linux.die.net/man/7/packet)。
  • 撰写并发送ARP请求以发现您要发送到的站点的MAC地址(如果在本地LAN上,则为下一跳[路由器] IP地址的MAC)。
  • 接收ARP答复并记录另一个站点的MAC。
  • 构造SYN数据包并将其从您自己的MAC地址发送到目标站的MAC。 (使用您选择的源和目标IP,端口等)
  • 监听IP的返回ARP并根据需要进行回复。
  • 接收SYN + ACK响应。由于内核不知道目标IP地址(由您组成的目标IP地址)属于您的系统,因此内核将不会使用RST(或其他任何内容)来响应SYN + ACK。
  • 下一步要做任何你想做的事...

  • 如果您使用的MAC地址不是分配给接口(interface)的MAC地址,那么您当然必须混杂捕获。对于原始数据包套接字,这是非常典型的。另外,您将为所有流量构造以太网头,IP头和TCP头(以及,ARP请求的以太网+ ARP),因此您将学到很多东西。

    关于python - 使用套接字AF_PACKET/SOCK_RAW,但告诉内核不要发送RST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48891727/

    35 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com