Maneira confiável de prender processos filho usando o `nsenter:`

15

Eu sei que os namespaces do Linux, entre muitas outras coisas, podem ser aproveitados para manipular processos filho de restrição e prisão com segurança, sem nenhuma chance de serem zumbidos e descartados init. Mas sou confuso nos detalhes da implementação. Como eu poderia usar as ferramentas fornecidas por util-linuxtais como mounte nsenterpara assistir, monitorar e assegurar que todos os processos lançados são os descendentes de namespace diretas de outro processo?

mikeserv
fonte

Respostas:

19

Crie um espaço para nome PID

O comando correto para usar aqui é unshare. Observe que as opções necessárias para fazer isso estão disponíveis apenas em util-linux 2.23. A idéia é criar um novo espaço para nome do PID para o programa que você está executando, de modo que todos os seus filhos também sejam criados nesse espaço para nome. Você pode executar um comando em um novo espaço de nome do PID simplesmente fazendo:

sudo unshare -fp some_command

Para executar um shell, apenas omita o comando. Isso criará um processo que, juntamente com qualquer um de seus filhos, terá um PID normalmente no espaço de nomes pai (sistema). No entanto, dentro do novo espaço para nome, ele terá um PID 1junto com algumas das características especiais do initprocesso. Talvez a característica mais relevante do ponto de vista do monitoramento seja que, se algum de seus descendentes ficar órfão, eles serão reinseridos nesse processo e não no initprocesso real .

Simplesmente fazer isso pode ser suficiente para a maioria dos casos de monitoramento. Como mencionado anteriormente, todos os processos no namespace possuem PIDs no namespace pai, portanto, comandos regulares podem ser usados ​​para monitorar suas atividades. Também temos certeza de que, se algum processo no espaço para nome ficar órfão, ele não cairá dos galhos da árvore de processos abaixo do PID do programa de nível superior, o que significa que ele ainda pode ser facilmente rastreado.

Combinar com um espaço para nome de montagem

No entanto, o que não podemos fazer é monitorar o processo em relação ao PID que ele pensa que tem. Para fazer isso, e em particular para poder usar o pscomando dentro do novo espaço para nome, você precisa montar um procfssistema de arquivos separado para o espaço para nome. Por sua vez, isso leva a outro problema, já que o único local que psaceita procfsé /proc. Uma solução seria criar uma chrootprisão e montar o novo procfslá. Mas essa é uma abordagem complicada, pois, no mínimo, precisaríamos copiar (ou pelo menos vincular) quaisquer binários que pretendamos usar junto com as bibliotecas das quais dependem para a nova raiz.

A solução é também usar um novo espaço para nome de montagem . Dentro disso, podemos montar o novo procfsde uma maneira que use o /procdiretório raiz verdadeiro , possa ser usado no espaço de nome PID e não interfira em mais nada. Para tornar esse processo muito simples, o unsharecomando oferece a --mount-procopção:

sudo unshare -fp --mount-proc some_command

Agora, a execução psnos namespaces combinados mostrará apenas os processos com o namespace do PID e mostrará o processo de nível superior como tendo um PID de 1.

Que tal nsenter?

Como o nome sugere, nsenterpode ser usado para inserir um espaço para nome que já foi criado unshare. Isso é útil se quisermos obter informações disponíveis apenas dentro do namespace a partir de um script não relacionado. A maneira mais simples é acessar o PID de qualquer programa em execução no espaço para nome. Para ficar claro, esse deve ser o PID do programa de destino no espaço para nome do qual nsenterestá sendo executado (como os espaços para nome podem ser aninhados, é possível que um único processo tenha muitos PIDs). Para executar um shell no espaço de nomes PID / mount de destino, basta:

sudo nsenter -t $PID -m -p

Se esse espaço para nome estiver configurado como acima, psagora listará apenas processos dentro desse espaço para nome.

Graeme
fonte
Obrigado, Graeme. Isso já respondeu à pergunta e muito mais. O que realmente me fez perguntar foi ler as notas da página de manual procfs nos vários arquivos em / proc / pid / ns / *, que diz: "Vincule a montagem deste arquivo (consulte mount (2)) a outro local do sistema de arquivos. ... espaço para nome do processo especificado por pid alive, mesmo que todos os processos atualmente no espaço para nome terminem. " Dificilmente a mesma pergunta, eu sei, mas isso já é tão bom que pensei que, se você considerasse relevante, poderia adicioná-la. Linux.die.net/man/5/proc
mikeserv
Isso é abordado no artigo LWN da última seção (basta procurar a montagem de ligação). Não sei ao certo o que é isso, pois mantém o namespace do PID ativo, mas depois que o initprocesso de estilo de nível superior morre, você não pode mais criar.
Graeme
Sim, também não tenho muita certeza. Mas com esta resposta e manum fim de semana para mim, pretendo me familiarizar um pouco mais com ela. Obrigado novamente. Talvez tenha mais relevância no --user espaço para nome.
mikeserv