LXC: Qualquer diferença de segurança entre os recipientes não privilegiados raiz e os pertencentes ao usuário final?

5

Eu pretendo usar contêineres LXC para isolar a maioria dos serviços voltados para a rede.

Segundo meu entendimento, tenho basicamente duas maneiras de fazer isso:

  1. Crie contêineres sem privilégios pertencentes à raiz . Nesse caso, o root terá um único conjunto grande de sub-UIDs e sub-GIDs e subconjuntos diferentes desse intervalo serão afetados em cada contêiner (nenhum contêiner compartilhará qualquer sub-UID ou sub-GID um com o outro),

  2. Crie contêineres sem privilégios pertencentes a contas do sistema sem privilégios . Nesse caso, cada conta terá um único contêiner e os UIDs e GIDs subordinados necessários para esse único contêiner.

De um ponto de vista de usabilidade, o primeiro é muito melhor: mais fácil de configurar e manter.

No entanto, de uma perspectiva de segurança, existe alguma diferença entre os dois?

Por exemplo:

  • Existe algum link ou relação horizontal de algum tipo entre os IDs pertencentes ao mesmo pool (mesma linha) definidos em /etc/subuid e /etc/subgid , comparados aos IDs pertencentes a diferentes usuários e, portanto, pertencentes a diferentes piscinas (linhas diferentes)?

  • Existe algum link ou relação vertical de algum tipo entre um ID subordinado e sua conta de proprietário? Um ID subordinado de propriedade do root pode obter privilégios maiores que um ID subordinado de um usuário não privilegiado? Um ID subordinado pode escalar para seu ID de proprietário de uma maneira mais fácil do que escalar para qualquer outro ID arbitrário?

  • Propriedade root significa que todos os comandos para administrar o contêiner serão iniciados com o privilégio de raiz do host. Isso constitui uma fraqueza ou, por exemplo, todos os privilégios são abandonados precocemente?

  • Etc.

Em outras palavras: os contêineres não privilegiados de raiz podem ser "menos sem privilégios" do que os pertencentes a contas padrão?

    
por WhiteWinterWolf 20.03.2016 / 15:18

1 resposta

0

In other words: may root owned unprivileged containers be "less unprivileged" than ones owned by standard accounts?

Eu não penso assim. O que importa é o que está em /proc/$PID/uid_map de processos no namespace de usuário do contêiner, não o que está em /etc/subuid . Suponha que você execute o seguinte do namespace de usuário inicial (ou seja, não do contêiner) para $PID de um processo em execução no contêiner:

$ cat /proc/$PID/uid_map
0 200000 1000

Isso significa que o intervalo de UID [0-1000) do processo $ PID será mapeado para o intervalo de UID [200000-201000) fora de seu espaço de nome de usuário (do contêiner). Os UIDs fora do intervalo [200000-201000) serão mapeados para 65534 ( $(cat /proc/sys/kernel/overflowuid) ) no contêiner. Isso pode acontecer, por exemplo, se você não criar um novo namespace PID. Nesse caso, o processo no contêiner veria processos externos, mas seu UID seria 65534.

Portanto, com o mapeamento de UID adequado, mesmo que o contêiner seja iniciado pelo root, seus processos terão UIDs sem privilégios fora dele.

UIDs subordinados em /etc/subuid não estão de forma alguma vinculados a um único UID externo. O objetivo desse arquivo é permitir que usuários sem privilégios iniciem contêineres que usam mais de um UID (que é o caso da maioria dos sistemas operacionais Linux). Por padrão, você só pode mapear seu UID se você for um usuário sem privilégios. Ou seja, se o seu UID for 1000 e $PID fizer referência a um processo no contêiner, você só poderá fazer

echo "$N 1000 1" >/proc/$PID/uid_map

para qualquer $N como usuário sem privilégios. Tudo o mais não é permitido. Se você pudesse mapear um intervalo maior, por exemplo

echo "$N 1000 50" >/proc/$PID/uid_map

você ganharia acesso aos UIDs [1000-1050) fora do contêiner por meio do contêiner. E, claro, se você pudesse alterar o início do intervalo de UID externo, você teria uma maneira fácil de obter raiz. Portanto, /etc/subuid define intervalos externos que você pode usar. Este arquivo é usado por newuidmap , que é root setuid.

$ cat /etc/subuid
woky:200000:50
$ echo '0 200000 50' >/proc/$PID/uid_map
-bash: echo: write error: Operation not permitted
$ newuidmap $PID 0 200000 50
$ # success

Os detalhes são muito mais complicados e eu provavelmente não sou a pessoa certa para explicar isso, mas eu acho que é melhor não ter resposta. :-) Você pode querer verificar as páginas man user_namespaces(7) e newuidmap(1) , e minha própria pesquisa O primeiro processo em um novo namespace de usuário Linux precisa chamar setuid ()? . Infelizmente, não tenho certeza de como o LXC usa esse arquivo.

    
por 18.06.2018 / 10:44