使用`nsenter'的可靠方法来监禁子进程:


15

我知道Linux命名空间以及许多其他东西都可以用来安全地处理子进程并对其进行约束,而不会被子进程破坏和转储init。但是我对实现细节一无所知。我怎么可能会使用所提供的工具util-linux,如mountnsenter观看,监控,并确保所有的进程都启动另一个进程的直接后裔的命名空间?

Answers:


19

创建一个PID名称空间

此处使用的正确命令是unshare。请注意,只能从中获得执行此操作所需的选项util-linux 2.23。这个想法是为您正在运行的程序创建一个新的PID名称空间,以便在该名称空间中也创建其所有子级。您只需执行以下操作即可在新的PID名称空间中运行命令:

sudo unshare -fp some_command

要运行shell,只需省略该命令。这将创建一个进程,该进程及其任何子进程将在父(系统)名称空间中像往常一样具有PID。但是,在新的名称空间中,它将具有PID 1以及init流程的某些特殊特征。从监视的角度来看,最相关的特性也许是,如果其后代中的任何一个成为孤儿,他们将重新成为该过程的父项,而不是实际的init过程。

对于大多数监视案例而言,简单地执行此操作就足够了。如前所述,名称空间中的进程在父名称空间中都具有PID,因此可以使用常规命令来监视其活动。我们还保证,如果命名空间中的任何进程成为孤立进程,它将不会从顶级程序的PID之下的进程树分支中掉出来,这意味着仍可以轻松地对其进行跟踪。

与安装名称空间结合

但是,我们不能针对它认为具有的PID监视过程。为此,特别是为了能够ps在新名称空间中使用该命令,您需要procfs为该名称空间安装一个单独的文件系统。这又导致了另一个问题,因为ps接受的唯一位置procfs/proc。一种解决方案是创建一个chroot监狱并在其中安装新监狱procfs。但这是一个麻烦的方法,因为至少我们需要将(我们打算使用的)任何二进制文件以及它们依赖的任何库复制(或至少硬链接)到新的根目录。

解决方案是还使用新的安装命名空间。在此方法中,我们可以procfs使用真正的根/proc目录来挂载新文件,可以在PID名称空间中使用它,并且不会干扰其他任何内容。为了使此过程非常简单,该unshare命令提供了以下--mount-proc选项:

sudo unshare -fp --mount-proc some_command

现在,ps在组合的名称空间中运行时,将仅显示具有PID命名空间的进程,并且将显示PID为的顶级进程1

nsenter

顾名思义,nsenter可用于输入已使用创建的名称空间unshare。如果我们想从其他不相关的脚本中仅从名称空间中获取信息,则这很有用。最简单的方法是访问命名空间中运行的任何程序的PID。为了清楚起见,该名称必须nsenter是正在运行的名称空间中目标程序的PID (由于名称空间可以嵌套,因此单个进程可能具有许多PID)。要在目标PID / mount名称空间中运行shell,只需执行以下操作:

sudo nsenter -t $PID -m -p

如果按上述方法设置了该名称空间,ps则现在将仅列出该名称空间中的进程。


谢谢,格雷姆。这已经回答了更多问题。我真正要问的是从procfs手册页上的/ proc / pid / ns / *中的各个文件上读取注释,该注释中说:“将文件挂载(参见mount(2))到文件系统中的其他位置会使... pid所指定的进程的名称空间仍然有效,即使该名称空间中当前所有的进程都终止了。” 我知道几乎不是同一问题,但是这个问题已经很好了,我想如果您觉得它有意义,那么您可能需要添加它。linux.die.net
man/5/

这在上一节LWN文章中进行了介绍(仅搜索绑定安装)。我不确定它的意义,因为它可以使PID名称空间保持活动状态,但是在顶层init样式过程终止后,您将无法再创建它。
Graeme 2014年

是的,我也不太确定其余的内容。但是有了这个答案,man还有我自己的一个周末,我的意思是对它有所了解。再次感谢。也许它在--user 名称空间中具有更大的相关性。
mikeserv 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.