如何在Linux中被动监测是否有新的TCP连接建立?

3
最简单的方法可能是编写一个循环来监视/proc/net/tcp或/proc/net/tcp6。但由于我需要几乎立即得到通知,这样做效率太低。我找到的最接近的东西是inotify,它可以在任何文件上提供IO事件的回调。问题是procfs不是常规文件系统,而且inotify似乎不支持它(至少不支持/proc/net/tcp和/proc/net/tcp6)。
此外,我不想让程序拥有root权限来实现这个功能。
编辑:我去掉了用户空间连接的要求。另外,我希望有一种内置的内核支持,例如inotify,可以实现这一点。在我的情况下,甚至操作iptables可能会过于侵入式。
有人有什么想法吗?谢谢!!

你能举个例子说明在什么情况下 Linux 内核会发起 TCP 会话(而非用户空间)吗? - Mike Pennington
抱歉,我发现用户空间连接并不重要。我已经在问题中将其删除了。 - zack
3个回答

2
您可以在本地的iptables配置中添加一个日志规则,每当建立新连接时记录一条消息,然后使日志文件可被非root用户读取。这样可以实现(a)立即通知事件(您可以使用inotify检测文件写入)和(b)检测过程本身不需要root权限。

一个 iptables 解决方案单独如何处理在用户空间启动的 TCP 会话(与由内核启动的会话不同)? - Mike Pennington
我猜它并没有特别的影响,因为内核发起的TCP连接数量相对较少,而且端口相对静态,所以理论上很容易过滤掉。实际上,当我考虑这个问题时,我无法想出一个内核发起TCP连接的例子。我认为即使像NFS-over-TCP这样的东西也是在用户空间中启动的。你能给我举个例子吗? - larsks
1
我想我的观点是,在没有相反的例子的情况下,所有TCP连接都在典型系统中由用户空间发起。 - larsks
更改iptables可能仍然过于侵入性。例如,如果我想在未root的Android手机上开发应用程序,我无法更改iptables怎么办?我不太熟悉ptrace。非特权应用程序是否可以使用ptrace来监视其他应用程序的系统调用? - zack
1
不,你基本上只能检测到其他应用程序在/proc中可读且非空的内容,以及实际文件上的inotify。 - Chris Stratton
你可以使用ptrace来检测像connect(2)这样的调用并与之交互。但是,你一次只能附加到一个进程,如果你附加到所有进程,性能将非常糟糕。另一种解决方案是LD_PRELOAD某些东西,它会查看connect()。顺便说一下,你可以使用ptrace在每个二进制文件加载时进行monkey patch(这需要了解PLT和一些汇编语言)...换句话说,这很混乱。 - Mark Nunberg

1

我能想到的最好的方法是尝试运行一个内置代理,并说服其他应用程序通过它连接。有些人尝试通过更改APN设置来实现这一点。

但这很丑陋,可能无法在所有版本上工作,并且可能会被规避。

不幸的是,Android并没有设计成允许终端用户安装可选的系统行为改进,除非破解整个系统(即rooting)。


1

使用原始套接字监视出站流量是完全可能的。请参阅数据包(7)的手册以了解如何执行此操作。但是,这可能不是您想要的。

如果启用了连接跟踪,则可以使用netlink从内核获取有关新连接的通知。执行这些操作的API非常糟糕,因此请考虑查看已经执行此操作的程序的源代码。我认为“conntrack”二进制文件可能会随某些发行版一起提供(我不确定它属于哪个部分)。


你能在没有特殊权限的情况下完成这个任务吗?似乎需要一个适用于安全的消费级Android设备的解决方案。也就是说,需要一个类似Linux的系统,但是没有传统系统中设备所有者可以执行/允许的管理员任务的方式。 - Chris Stratton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接