求助一个技术问题,关于网络端口和进程的关联的问题

161 天前
 syam

需求大概是个要对 linux 操作系统所有的进程和绑定的端口进行一个数据的结合,

目的是将来用于限制单个进程绑定的端口,一种防护策略,开发语言是 c++,

我的思路通过/proc/net/tcp 找到所有开启的端口,然后去找进程然后绑定,然后依次 udp 的

但是目前根据网上找到的方案和 chatgpt 给的答案都无法完成绑定的这个步骤,

绕来绕去都是围绕 netstat 和 ss 这几个命令输出信息。

请教一下有什么办法能只用系统编程或者 proc 文件系统把信息绑定起来吗?

1332 次点击
所在节点    C++
16 条回复
lsk569937453
161 天前
syam
161 天前
@lsk569937453 我一开始是按着这个思路走的,我看的是我机器的 ssh 服务,后来发现存在一些 inode 不在 tcp 和 udp 的文件里面,多出来的几个文件有点不敢确定是不是错过的什么东西
mjikop1231
161 天前
`/proc/<pid>/net/tcp`
`/proc/<pid>/net/tcp`
`/proc/<pid>/net/tcp`
mjikop1231
161 天前
#3
敲。。
tcp/tcp6/udp/udp6 里面存 listening 信息
syam
161 天前
@mjikop1231 不行的你这个文件本质还是/proc/net/tcp 的内容 一模一样
mjikop1231
161 天前
关于#2 @syam 你可以先举个例子
syam
161 天前
@mjikop1231 我是拿 ssh 服务的进程看的 会明显多几个,但是实际我的机器没有产生任何的 ssh 连接
barathrum
161 天前
说实话你的 目的 这一块我没理解到位,是为了安全?还是资源限制?理论上来说可以学习 selinux 管理权限,学习 ulimit 管理资源。
syam
161 天前
@barathrum 简单理解就是我要知道每个进程绑定了那些端口 那个端口绑定在那个进程上
kuanat
161 天前
我觉得这个事情的思路有点跑偏了,Linux 内核网络栈的抽象还是比较难的。

首先“端口”是个协议层面的概念,假如 tcp 只有二元组(源 IP ,目标 IP )局限就太大了。

所以内核网络栈不会对“端口”做抽象的,因为没有必要。有必要的是对四元组(源 IP ,源端口,目标 IP ,目标端口)做抽象,这个完整的四元组可以唯一确定一个 tcp 连接。这个抽象在 Linux 里就是 socket 。

因此内核里也就不会有端口号的映射关系,如果你去看 netstat/ss 的代码,我猜测都是曲线救国。

由于网络栈是内核实现,为了方便用户态的程序使用,就通过 socketfs 抽象成一般 fd ,这样应用程序只需要确定 socket fd 就能直接在连接层面上完成网络功能了。

前面铺垫这么多,就是为了引出结论,你这个问题的本质是“如何确定 socket fd 和 pid 的映射关系”。

问题在于 fd 这个东西是可以复制或者转移的,于是最终还要回到 /proc/*/fd/* 去遍历才能确认。


PS

“限制进程可绑定端口”的标准操作是 ACL 机制,selinux 比较方便。自己造这个轮子非常不理智。
gulucn
161 天前
可以考虑 systemtap 的方式去进行监控,chatgpt 关于 systemtap 的例子
# socket_trace.stp

global sockets

probe begin {
print("Tracing sockets...\n")
}

probe syscall.socket {
pid = pid()
sfd = $return
sockets[pid, sfd] = 1
}

probe syscall.close {
pid = pid()
sfd = $fd
if (exists(sockets[pid, sfd])) {
delete sockets[pid, sfd]
printf("Process %d closed socket %d\n", pid, sfd)
}
}

然后再考虑一下怎么把 socket id 跟端口关联就可以了
idontnowhat2say
161 天前
你的需求如果没法直接调用 ss 或 lsof 命令输出处理的话,要不去看看他们代码怎么实现的?另外感觉你开发的这个东西这个很像 HIDS ,可以找找开源的 HIDS 看他们怎么写的
ttvast
161 天前
netstat -anp
syam
160 天前
@kuanat 是的 我看过 lsof 的实现命令了就是遍历出来的,之所以不用 selinux 是因为 我分到的模块只是监控的这一部分 这个是参与的一个社区开源项目
julyclyde
160 天前
首先,你这个需求是错的
这个需求用 selinux 或者 appArmor 就可以实现,没必要你自己在额外实现一遍
先不说你的开发质量怎么样,就单凭,人家是内核,你只是应用层,就差很多了

其次,不知道你说的所谓绑定是什么
是通过端口倒查 pid ?还是网络编程里所谓 bind/listen 那个 bind ?
不要在自己不懂的情况下乱发明新的术语
jones2000
160 天前
用钩子把 bind 函数截获。 其他程序调用 bind 你记录下不就可以了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/996254

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX