Fundo
Para uma exportação/compartilhamento NFSv4, a opção root_squash habilitada por padrão forçará o NFS a alterar a raiz do cliente para um ID anônimo. Na verdade, isso aumentará a segurança, evitando que a propriedade da conta root em um sistema migre para outro sistema.
Overlayfs permite que um sistema de arquivos local e transparente seja montado sobre outro sistema de arquivos. Infelizmente, parece que ele acessa o sistema de arquivos subjacente usando o usuário root, e não o usuário real. Pelo menos essa é a conclusão que tiro do seguinte experimento.
Por que montar um Overlayfs em um compartilhamento NFS? Para permitir que uma máquina menos confiável possa fingir que pode gravar no sistema de arquivos compartilhado.
Configuração de teste
Primeiro instale o servidor kernel NFS conforme apropriado para sua distribuição. Em seguida, certifique-se de exportar apenas o NFSv4. (Embora provavelmente não seja importante para este problema, é uma boa precaução de segurança.)
$ sudo cat /proc/fs/nfsd/versions
-2 -3 +4 +4.1 +4.2
Se não, dê uma olhada /etc/nfs.conf
e defina vers3=n
.
Em seguida, crie um sistema de arquivos Ext4 em um arquivo esparso e monte-o no sistema de arquivos local. Este será o sistema de arquivos que sustentará nosso compartilhamento NFS.
$ truncate -s 512M 512BM-ext4.img
$ mkfs.ext4 512BM-ext4.img
$ sudo mkdir /mnt/ext4-file
$ sudo mount -o loop,noacl 512BM-ext4.img /mnt/ext4-file
Em seguida, compartilhe/exporte esse sistema de arquivos pela rede com NFSv4 para uma máquina apropriada. Neste exemplo usarei localhost, mas pode ser qualquer máquina da rede local. Faça isso editando /etc/exports
para obter uma linha como a seguinte.
/mnt/ext4-file/ localhost(ro,fsid=123123)
Em seguida, reinicie o servidor NFS em sua máquina; os arquivos de serviço podem ser diferentes em seu sistema operacional.
$ sudo systemctl restart nfs-server.service nfs-mountd.service
$ sudo exportfs -v
/mnt/ext4-file localhost(sync,wdelay,hide,no_subtree_check,fsid=123123,sec=sys,ro,secure,root_squash,no_all_squash)
Certifique-se de que root_squash
e ro
esteja ativado.
Agora deve ser possível montar o compartilhamento NFSv4 no cliente pretendido.
$ sudo mount -t nfs -o ro localhost:/mnt/ext4-file /mnt/nfs-share/
$ findmnt /mnt/nfs-share
TARGET SOURCE FSTYPE OPTIONS
/mnt/nfs-share localhost:/mnt/ext4-file nfs4 rw,relatime,vers=4.2,rsize=1048576,wsize=1048576,namlen=255
E então montamos overlayfs2 em cima deste compartilhamento.
$ mkdir -p /tmp/overlay/{work,upper}
$ sudo mkdir /mnt/overlay
$ sudo mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
Para nosso experimento, criaremos uma pasta no sistema de arquivos que só pode ser lida e gravada por um usuário e lida por um grupo. Eu escolhi o grupo pertencente ao meu usuário.
$ sudo mkdir /mnt/ext4-file/rovanion
$ sudo chown rovanion:rovanion /mnt/ext4-file/rovanion
$ sudo chmod 2750 /mnt/ext4-file/rovanion
$ touch /mnt/ext4-file/rovanion/hi-from-ext4
$ ls -la /mnt/nfs-share/rovanion/
totalt 8,0K
drwxr-s--- 2 rovanion rovanion 4,0K sep 6 14:14 .
drwxr-xr-x 4 root root 4,0K sep 6 14:12 ..
-rw-rw-r-- 1 rovanion rovanion 0 sep 6 14:14 hi-from-ext4
$ touch /mnt/nfs-share/rovanion/hi-from-nfs
touch: cannot touch '/mnt/nfs-share/rovanion/hi-from-nfs': Read-only file system
Podemos listar o conteúdo de /mnt/nfs-share/rovanion
, mas não podemos tocar no sistema de arquivos mesmo que tenhamos permissão para isso, porque o compartilhamento NFS é montado como somente leitura. Tudo está como esperado.
Falha
Mas aí vem o problema.
$ ls -la /mnt/overlay/rovanion/
ls: cannot open directory '/mnt/overlay/rovanion/': Permission denied
$ ls -l /mnt/overlay/
total 28K
drwx------ 2 root root 16K Sep 6 13:04 lost+found
drwxr-s--- 2 rovanion rovanion 4.0K Sep 6 14:14 rovanion
$ whoami
rovanion
$ groups
rovanion sudo
Foi-nos negado o acesso à lista, /mnt/overlay/rovanion
embora o sistema de permissões nos permita fazê-lo.
Meu melhor palpite sobre o que está acontecendo é que o Overlayfs faz todo o acesso ao sistema de arquivos subjacente, pois root
o root squash do NFS é mapeado para nobody
quem não tem permissão para acessar a pasta, já que nobody
não pertence ao grupo rovanion
e outros não têm permissão para liste a pasta.
Pergunta
Minha pergunta então é: é possível contornar esse problema? Para permitir que um usuário acesse uma pasta através do Overlayfs à qual apenas um grupo selecionado tem acesso, sem desabilitar root_squash na exportação/compartilhamento NFS ou adicionar o+rx
à pasta.
Responder1
A seguinte seção doDocumentação do kernel Linux em Overlayfsdescreve o modelo de permissão.
A verificação de permissão no sistema de arquivos de sobreposição segue estes princípios:
1) permission check SHOULD return the same result before and after copy up 2) task creating the overlay mount MUST NOT gain additional privileges 3) non-mounting task MAY gain additional privileges through the overlay, compared to direct access on underlying lower or upper filesystems
Isso é conseguido realizando duas verificações de permissão em cada acesso
a) check if current task is allowed access based on local DAC (owner, group, mode and posix acl), as well as MAC checks b) check if mounting task would be allowed real operation on lower or upper layer based on underlying filesystem permissions, again including MAC checks
A verificação (a) garante a consistência (1), uma vez que as ACLs de proprietário, grupo, modo e posix são copiadas. Por outro lado, pode fazer com que as permissões impostas pelo servidor (usadas pelo NFS, por exemplo) sejam ignoradas (3).
A verificação (b) garante que nenhuma tarefa obtenha permissões para camadas subjacentes que a tarefa de montagem não possui (2).Isto também significa que é possível criar configurações onde a regra de consistência (1) não é válida; normalmente, entretanto, a tarefa de montagem terá privilégios suficientes para executar todas as operações.
Ênfase minha. Minha leitura é que consegui criar tal situação. Aquele em que a tarefa de montagem, executada como root, não tem o privilégio de listar a pasta e, portanto, Overlayfs não permite o acesso do usuário à pasta.
Se montarmos o Overlayfs como um usuário com permissão para acessar os arquivos, que não seja root para que o UID não seja comprimido, talvez possamos listar o diretório e criar um arquivo nele?
$ unshare --mount --map-root-user
# mount -t overlay overlay -o lowerdir=/mnt/nfs-share/,upperdir=/tmp/overlay/upper/,workdir=/tmp/overlay/work/ /mnt/overlay/
# ls -la /mnt/overlay/
totalt 28K
drwxrwxr-x 1 root root 4,0K sep 6 14:08 .
drwxr-xr-x 7 nobody nogroup 4,0K sep 6 14:09 ..
drwx------ 2 nobody nogroup 16K sep 6 13:04 lost+found
drwxr-s--- 2 root root 4,0K sep 6 14:14 rovanion
# touch /mnt/overlay/rovanion/hi-from-overlay
E isso nós podemos! E o arquivo existe apenas na sobreposição.
$ ls /mnt/ext4-file/rovanion/
hi-from-ext4
$ ls /tmp/overlay/upper/rovanion/
hi-from-overlay
Embora esta solução tenha suas próprias implicações interessantes. Agora devemos ter namespaces de usuário habilitados em nossas máquinas não 100% confiáveis e de repente existimos em um espaço onde nosso UID parece ser 0, mas está mapeado para nosso ID de usuário normal para o mundo exterior. Infelizmente unshare --mount
sem --map-root-user
não parece possível.