Maneira confiável de processar processos filhos usando 'nsenter:'

15

Eu sei que os namespaces do Linux, entre muitas outras coisas, podem ser aproveitados para lidar com a restrição e o aprisionamento de processos filhos com segurança, sem qualquer chance de eles serem zumbidos e descartados em init . Mas estou confuso em detalhes de implementação. Como posso usar as ferramentas fornecidas por util-linux como mount e nsenter para assistir, monitorar e garantir que todos os processos iniciados sejam os descendentes diretos de namespace de outro processo?

    
por mikeserv 10.04.2014 / 22:39

1 resposta

17

Crie um namespace PID

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

sudo unshare -fp some_command

Para executar um shell, apenas omita o comando. Isto irá criar um processo que, juntamente com qualquer um dos seus filhos, terá um PID, como de costume, dentro do espaço de nomes pai (sistema). No entanto, dentro do novo namespace, ele terá um PID de 1 , juntamente com algumas das características especiais do processo init . Talvez a característica mais relevante de uma perspectiva de monitoramento seja que, se algum de seus descendentes ficar órfão, eles serão re-paiseados para este processo, em vez do processo real init .

Simplesmente fazer isso pode ser suficiente para a maioria dos casos de monitoramento. Como mencionado anteriormente, todos os processos dentro do espaço de nomes têm PIDs no espaço de nomes pai, pelo que podem ser utilizados comandos regulares para monitorizar a sua atividade. Também estamos certos de que, se algum processo no espaço de nomes ficar órfão, ele não cairá dos ramos da árvore do processo sob o PID do programa de nível superior, o que significa que ainda pode ser facilmente monitorado.

Combinar com um namespace de montagem

No entanto, o que não podemos fazer é monitorar o processo em relação ao PID que pensa que tem. Para fazer isso, e em particular para poder usar o comando ps no novo namespace, é necessário montar um sistema de arquivos procfs separado para o namespace. Isso, por sua vez, leva a outro problema, pois o único local que ps aceita para procfs é /proc . Uma solução seria criar uma chroot jail e montar o novo procfs lá. Mas essa é uma abordagem complicada, pois, no mínimo, precisaríamos copiar (ou pelo menos vincular) todos os binários que pretendemos usar junto com as bibliotecas das quais eles dependem para a nova raiz.

A solução também é usar um novo espaço de nomes de montagem . Dentro disso, podemos montar o novo procfs de uma maneira que use o diretório true root /proc , possa ser utilizável dentro do namespace do PID e não interfira em mais nada. Para tornar esse processo muito simples, o comando unshare fornece a opção --mount-proc :

sudo unshare -fp --mount-proc some_command

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

Que tal nsenter ?

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

sudo nsenter -t $PID -m -p

Se este namespace estiver configurado como acima, ps agora listará apenas os processos dentro desse namespace.

    
por 11.04.2014 / 02:51