Montando uma imagem do sistema de arquivos dentro de um namespace não compartilhado

6

Estou usando o unshare para executar coisas como vincular montagens locais a um determinado processo sem exigir acesso root , por exemplo:

unshare -mr bash mount --bind a b

(Sim, isso parece meio idiota; no meu caso de uso real, unshare está executando um script bash que executa a montagem de bind. Eu não fiz isso aqui para que seja um exemplo menor).

No entanto, se eu tentar uma montagem de loop, ela falhará:

ryan@DevPC-LX ~/stuff/util-linux master $ unshare -mr mount -o loop x.img a
mount: no permission to look at /dev/loop<N>

: /

Eu tentei usar mknod para criar um dispositivo de loop falso (requer privilégios não disponíveis para não-raiz), executando manualmente losetup (ainda requer privilégios de root) e um monte de outras coisas que não trabalho.

Claro, eu poderia fazer apenas chown myuser /dev/loop* , mas parece que isso pode se tornar um grande problema de segurança.

Além disso, guestmount é muito lento para meu caso de uso e fuseext2 tem um aviso sobre possível perda de dados no modo de gravação (e também é muito lento).

Existe alguma maneira de fazer ... isso? Em tudo?

    
por kirbyfan64sos 10.05.2017 / 22:29

2 respostas

3

Para executar um compartilhamento não compartilhado, você precisa ter recursos de root para criar um espaço de montagem separado.

Eu tentei isso que parece fazer o que você quer (eu acho):

Ishtar:> mkdir -p /tmp/unshare/home
Ishtar:> cd /tmp/unshare
Ishtar:/tmp/unshare> sudo unshare -m /bin/bash
Ishtar:/tmp/unshare# mount --rbind /home/packages /tmp/unshare/home
Ishtar:/tmp/unshare# tty
/dev/pts/4
Ishtar:/tmp/unshare# # ls home
BUILD@      RPMS@     build/           linux@    sources/           tmp/
BUILDROOT@  SOURCES@  buildroot/       logs/     specs/
OSbuild/    SPECS@    config-scripts/  perlsrc/  srpms/
OTHER/      SRPMS@    debug@           rpms/     sysvinit-288.spec

Portanto, o processo acima tem '/ home / packages mounted @ / tmp / unshare / home.

Em outra tty-window, com qualquer usuário, posso tentar ver: o que está em / tmp / unshare / home:

Ishtar:/> tty
/dev/pts/5
Ishtar:/> ll /tmp/unshare/home
total 0
Ishtar:/> cd tmp/unshare
Ishtar:/tmp/unshare> sudo
Ishtar:/tmp/unshare# ls home
Ishtar:/tmp/unshare# ll home
total 0
# create file in original "bound" dir from 1st usr above:
Ishtar:/tmp/unshare# touch /home/packages/PACKAGES.DIR 
Ishtar:/tmp/unshare# ll home  #home still empty
total 0
Ishtar:/> tty
/dev/pts/5
# now on other user again
Ishtar:/tmp/unshare# tty
/dev/pts/4
Ishtar:/tmp/unshare# ls home
BUILD@        RPMS@     buildroot/       perlsrc/  sysvinit-288.spec
BUILDROOT@    SOURCES@  config-scripts/  rpms/     tmp/
OSbuild/      SPECS@    debug@           sources/
OTHER/        SRPMS@    linux@           specs/
PACKAGES.DIR  build/    logs/            srpms/
#^^^ see PACKAGES.DIR appear (as created in original dir by another
# user

Depois de ter o seu "diretório privado montado para o usuário em" pts / 4 "você pode mude para o UID que você deseja executar no programa:

Ishtar:/tmp/unshare# su astara
Ishtar:/tmp/unshare> whoami
astara
Ishtar:/tmp/unshare> ls home/PACK*
home/PACKAGES.DIR

Observação de montagem ainda está lá para o usuário unpriv'd.

Para salvar, coloquei o 'su para outro usuário' em um arquivo de script seguido por 'desmontar / tmp / unshare / home', (desde quando o seu OTHERUSER sai, vai se tornar root novamente, e desmontar o arquivo no espaço privado,). Então você pode sair.

Isso chega perto do que você quer? - Você tem que usar 'root' para configurar seu filho env, mas, em seguida, execute o filho - e só ele tem acesso a a montagem criada no novo namespace de montagem.

(update) BTW - apenas notei que unshare tem um usuário -map-root que permite especificamente usar root ou caps para opções de configuração no novo namespace. A manpage diz (sobre esse switch):

....This makes it possible to  conveniently
gain  capabilities needed to manage various aspects of the newly
created namespaces (such as configuring interfaces in  the  net-
work  namespace  or mounting filesystems in the mount namespace)
even when run unprivileged.

Isso pode permitir que você gerencie o seu loop sem ser root (ou assim diz o manpage). O provável CAP_SYS_ADMIN é o limite necessário para fazer isso.

    
por 15.05.2017 / 03:54
2

Como você entendeu claramente, a criação de uma montagem de loop consiste em duas etapas:

  1. Configurando o dispositivo de loop
  2. Montando

Of course, I could just do chown myuser /dev/loop*, but that seems like it could become a major security issue.

Acredito que isso permitiria a criação do dispositivo de loop apropriado (dando acesso a /dev/loopcontrol ). Não sei se há também algum tipo de namespace disponível que afeta a exibição de dispositivos de loop. Isso presumivelmente permitiria fazer isso com mais segurança.

A etapa 2 ainda não foi considerada: os namespaces de usuário permitem a criação de novos namespaces de montagem nos quais é possível que os usuários criem novas montagens, mas é bastante limitada - CAP_SYS_ADMIN no namespace inicial ainda é necessário para montar dispositivos de bloco: como user_namespaces(7) diz…

Note however, that mounting block-based filesystems can be done only by a process that holds CAP_SYS_ADMIN in the initial user namespace.

Os dispositivos de loop são dispositivos de bloco apoiados por arquivos, o que ainda é um problema. Isso é lamentável, eu acho que deve haver uma maneira para que isso funcione de forma segura. Mas eu imagino que há muitas complexidades ( particularmente com o setuid ) que são a razão pela qual ainda não foi implementado .

Então, tanto quanto eu entendo, tudo que você pode realmente fazer é contornar o problema. Talvez você possa extrair os arquivos da imagem (se o pior acontecer, ou seja, não houver ferramentas disponíveis para trabalhar com o formato específico diretamente, você poderia montá-lo em uma VM temporária para fazer isso), em seguida, montar o diretório resultante .

    
por 23.05.2017 / 10:49