Depois de ler sobre os namespaces do Linux, fiquei com a impressão de que eles são, entre muitos outros recursos, uma alternativa ao chroot. Por exemplo, neste artigo :
Outros usos [de namespaces] incluem [...] o isolamento no estilo chroot() de um processo para uma parte da hierarquia de diretório único.
No entanto, quando clono o namespace mount, por exemplo, com o comando a seguir, ainda vejo toda a árvore raiz original.
unshare --mount -- /bin/bash
Entendo que agora posso executar montagens adicionais no novo namespace que não são compartilhados com o namespace original e, portanto, isso fornece isolamento, mas ainda é a mesma raiz, por exemplo, /etc
ainda é o mesmo para ambos os namespaces. Ainda preciso chroot
alterar a raiz ou existe uma alternativa?
Eu esperava que essa pergunta fornecesse uma resposta, mas a resposta usa apenas chroot
, novamente.
EDIÇÃO #1
Havia um comentário agora excluído que mencionava pivot_root
. Como isso é realmente parte de linux/fs/namespace.c
, na verdade é parte da implementação de namespaces. Isso sugere que alterar o diretório raiz apenas com unshare
e mount
não é possível, mas os namespaces fornecem uma versão própria - mais inteligente - do chroot
. Ainda não entendi a ideia principal dessa abordagem que a torna fundamentalmente diferente de chroot
, mesmo depois de ler o código-fonte (no sentido de, por exemplo, segurança ou melhor isolamento).
EDIÇÃO #2
Esta não é uma duplicata desta pergunta . Depois de executar todos os comandos da resposta, tenho separado /tmp/tmp.vyM9IwnKuY (ou similar), mas o diretório raiz ainda é o mesmo!
A inserção de um namespace de montagem antes de configurar um
chroot
, permite evitar sobrecarregar o namespace do host com montagens adicionais, por exemplo, para/proc
. Você pode usarchroot
dentro de um namespace de montagem como um hack agradável e simples.Eu acho que há vantagens em entender
pivot_root
, mas tem um pouco de curva de aprendizado. A documentação não explica tudo... embora haja um exemplo de uso emman 8 pivot_root
(para o comando shell).man 2 pivot_root
(para a chamada do sistema) poderia ser mais claro se fizesse o mesmo e incluísse um exemplo de programa C.Como usar pivot_root
Imediatamente após inserir o namespace mount, você também precisa
mount --make-rslave /
ou equivalente. Caso contrário, todas as alterações de montagem serão propagadas para as montagens no namespace original, incluindo o arquivopivot_root
. Você não quer isso :).Se você usou o
unshare --mount
comando, observe que ele está documentado para ser aplicadomount --make-rprivate
por padrão. AFAICS este é um padrão ruim e você não quer isso no código de produção. Por exemplo, neste ponto, ele parariaeject
de funcionar em um DVD ou USB montado no namespace do host. O DVD ou USB permaneceria montado dentro da árvore de montagem privada e o kernel não permitiria que você ejetasse o DVD.Depois de fazer isso, você pode montar, por exemplo, o
/proc
diretório que você usará. Da mesma forma que você faria parachroot
.Ao contrário de quando você usa
chroot
,pivot_root
requer que seu novo sistema de arquivos raiz seja um ponto de montagem. Se ainda não for um, você pode satisfazer isso simplesmente aplicando uma montagem de ligação:mount --rbind new_root new_root
.Use
pivot_root
- e depoisumount
o antigo sistema de arquivos raiz, com a opção-l
/MNT_DETACH
. ( Você não precisaumount -R
, o que pode levar mais tempo. ).Tecnicamente, o uso
pivot_root
geralmente precisa envolverchroot
o uso também; não é "ou-ou".De acordo
man 2 pivot_root
com , é definido apenas como trocar a raiz do namespace de montagem. Não está definido para alterar para qual diretório físico a raiz do processo está apontando. Ou o diretório de trabalho atual (/proc/self/cwd
). Acontece que ele faz isso, mas este é um hack para lidar com threads do kernel. A página de manual diz que isso pode mudar no futuro.Normalmente você quer esta sequência:
A posição do
chroot
nesta sequência é mais um detalhe sutil . Embora o objetivopivot_root
seja reorganizar o namespace de montagem, o código do kernel parece encontrar o sistema de arquivos raiz a ser movido observando a raiz por processo, que é o quechroot
define.Por que usar pivot_root
Em princípio, faz sentido usar
pivot_root
para segurança e isolamento. Gosto de pensar na teoria da segurança baseada em capacidade . Você passa uma lista dos recursos específicos necessários e o processo não pode acessar outros recursos. Neste caso, estamos falando sobre os sistemas de arquivos passados para um namespace de montagem. Essa ideia se aplica geralmente ao recurso "namespaces" do Linux, embora eu provavelmente não esteja expressando isso muito bem.chroot
apenas define a raiz do processo, mas o processo ainda se refere ao namespace de montagem completa. Se um processo retiver o privilégio de executarchroot
, ele poderá percorrer de volta o namespace do sistema de arquivos. Conforme detalhado emman 2 chroot
, "o superusuário pode escapar de uma 'jaula chroot' por...".Outra maneira instigante de desfazer
chroot
énsenter --mount=/proc/self/ns/mnt
. Este é talvez um argumento mais forte para o princípio.nsenter
/setns()
necessariamente recarrega a raiz do processo, a partir da raiz do namespace mount ... embora o fato de que isso funcione quando os dois se referem a diretórios físicos diferentes, possa ser considerado um bug do kernel. (Nota técnica: pode haver vários sistemas de arquivos montados um em cima do outro na raiz;setns()
usa o topo, o mais recentemente montado).Isso ilustra uma vantagem de combinar um namespace de montagem com um "namespace PID". Estar dentro de um namespace PID impediria você de inserir o namespace de montagem de um processo não confinado. Também evita que você entre na raiz de um processo não confinado (
/proc/$PID/root
). E, claro, um namespace PID também impede que você mate qualquer processo que esteja fora dele :-).