Linux内核钩子,知道套接字的目标进程

sho*_*osh 13 sockets linux hook kernel

我正在寻找一个特定的地方来为linux内核添加某种钩子,这将允许我执行以下操作:

  • 检测TCP连接转向环回的情况(127.0.0.1)
  • 检测数据包的源进程是否与目标进程相同
  • 如果是这种情况,请允许连接,拒绝任何其他环回连接(一个进程到另一个进程)

我一直在寻找netfilter挂钩,但它们似乎不适合需要.bpf过滤器只查看数据包本身.

我也在看socket-connect的LSM钩子.我可以通过查看哪个进程具有所请求的端口当前绑定来预测连接将要连接的位置来尝试从套接字连接挂钩实现这一点,这听起来非常h​​ackish.

Ste*_*cht 5

一种简单的方法可能是使用Linux网络命名空间.

Linux网络命名空间

顾名思义,网络命名空间将网络设备,地址,端口,路由,防火墙规则等的使用划分为单独的框,实质上是在单个运行的内核实例中虚拟化网络.网络命名空间在2.6.24中进入内核,...

请参阅https://lwn.net/Articles/580893/

取消共享

unshare()允许进程(或线程)取消当前与其他进程(或线程)共享的部分执行上下文.

http://man7.org/linux/man-pages/man2/unshare.2.html

测试用例

由于程序应该能够与自身通信,我们需要一个通过sockes与自身通信的程序.有一个很酷的SO答案,显示了一个简单的Java程序,它传输文本'Hello World!' 通过套接字自身,请参见/sf/answers/568379591/.

/usr/bin/java SendReceive
Run Code Online (Sandbox Code Playgroud)

按预期工作,输出'Hello World!'

使用-n选项,可以取消共享网络命名空间.

unshare -n -- sh -c '/usr/bin/java SendReceive'
Run Code Online (Sandbox Code Playgroud)

给出一个SocketException:网络无法访问,因为无法访问回送设备.

unshare -n -- sh -c 'ip link set dev lo up; /usr/bin/java SendReceive'
Run Code Online (Sandbox Code Playgroud)

终于转移'Hello World!' 再次通过环回接口.BTW:这是一个私有环回设备.您无法访问标准环回设备上的开放端口.

另请参阅这个很酷的Unix Stackexchange答案:https://unix.stackexchange.com/a/83348 :阻止进程的网络访问?

截图

这里是在Ubuntu 18.10上执行的上述测试用例的屏幕截图:

截图