Quero executar um comando no Linux de uma maneira que não possa criar ou abrir nenhum arquivo para gravação. Ele ainda deve ler os arquivos normalmente (portanto, um chroot vazio não é uma opção) e ainda pode gravar em arquivos já abertos (especialmente stdout).
Pontos de bônus se a gravação de arquivos em determinados diretórios (ou seja, o diretório atual) ainda for possível.
Estou procurando uma solução que seja local do processo, ou seja, não envolva a configuração de coisas como AppArmor ou SELinux para todo o sistema, nem privilégios de root. No entanto, pode envolver a instalação de seus módulos do kernel.
Eu estava olhando para os recursos e estes teriam sido agradáveis e fáceis, se houvesse um recurso para criar arquivos. O ulimit é outra abordagem que seria conveniente se abordasse esse caso de uso.
strace
informa quais arquivos o programa está abrindo. Por que você quer fazer isso? É um programa específico ou você deseja que seja testado ou algo mais? Você pode executar o programa como um usuário / grupo que não tem permissão para gravar em quase todos os lugares, exceto no diretório atual? As distribuições modernas do Linux usam a idéia de um grupo para cada usuário, portanto, isso deve ser relativamente fácil de configurar.Respostas:
Que tal criar um chroot vazio e montar o sistema de arquivos principal como somente leitura dentro do chroot?
Provavelmente deve ser algo assim para criar uma montagem de ligação somente leitura:
Você pode montar outros diretórios aos quais deseja que a cadeia também tenha acesso de gravação. Tenha cuidado se você precisar vincular diretórios especiais de montagem (/ dev /, / proc /, / sys /), pois sua montagem como está pode ser insegura.
fonte
/foo/
caminho para o sistema de arquivos principal?Parece que a ferramenta certa para este trabalho é
fseccomp
baseada nosync-ignoring
código f de Bastian Blank, criei um arquivo relativamente pequeno que faz com que todos os seus filhos não consigam abrir um arquivo para escrever:Aqui você pode ver que ainda é possível ler arquivos:
Ele não impede a exclusão de arquivos, a sua movimentação ou outras operações de arquivos além da abertura, mas que podem ser adicionadas.
Uma ferramenta que permite isso sem precisar escrever código C é syscall_limiter .
fonte
Você consideraria escrever um substituto para
open(…)
funcionar e carregá-lo usando LD_PRELOAD?fonte
open
... Bem, eu consideraria usar uma solução existente que use essa abordagem, sim.write(…)
também.A solução mais simples é provavelmente um programa wrapper que cria um novo espaço para nome do sistema de arquivos com os sistemas de arquivos relevantes montados somente leitura e depois executa o programa que você está tentando restringir.
É o que
systemd
faz quando você usaReadOnlyDirectories=
para marcar determinados diretórios como somente leitura para um serviço. Há também umunshare
comandoutil-linux
que pode fazer o trabalho de criar um novo espaço para nome, para que você possa fazer algo como:onde
wrapper
seria necessário apenas remontar os sistemas de arquivos conforme necessário antes de iniciar o programa de destino real.O único problema é que você precisa
root
criar o novo espaço para nome ...fonte
Você poderia executá-lo em um chroot, montando versões especiais
/tmp
e assim por dentro. Talvez o systemd seja útil, e particularmente o systemd-nspawn (1) , que se parece exatamente com o que você deseja.fonte
Uma máquina virtual possibilitaria que o script escrevesse em qualquer lugar sem afetar o sistema host e inspecionasse para onde ele realmente estava tentando gravar, o que parece ser o objetivo.
Por exemplo, você pode iniciar facilmente o Arch Linux com
fonte
Fazer algumas configurações iniciais como root é realmente a maneira mais fácil. Especificamente, um chroot em uma montagem de ligação somente leitura é o caminho de menor resistência.
Você pode usar bindfs em vez de
mount --bind
criar a visualização somente leitura sem precisar ser raiz. No entanto, você precisa fazer algo como root para impedir o acesso a outros arquivos, como o chroot.Outra abordagem é
LD_PRELOAD
uma biblioteca que se conecta à abertura de arquivos e se recusa a permitir a gravação. Isso não requer privilégios especiais. Do ponto de vista da segurança, isso pode ser ignorado, mas não há problema em seu caso de uso em que você só precisa conter um recurso específico e não um código nativo arbitrário. Eu não conheço uma biblioteca existente para isso, no entanto.LD_PRELOAD
também pode ser usado para limitar o programa à exibição somente leitura criada commount --bind
oubindfs
; novamente, não conheço uma biblioteca existente.No Debian e derivados, você pode configurar um ambiente schroot . O Schroot é raiz setuid e precisa ser configurado como raiz, mas pode ser executado por qualquer usuário autorizado.
Um método que não requer nenhuma cooperação da raiz é executar o processo em uma máquina virtual. Você pode configurar o KVM ou o VirtualBox ou o Linux no modo de usuário . É um pouco pesado e significa consumo de memória extra, mas não deve afetar significativamente a velocidade da computação simbólica bruta.
Como "encarcerar" um processo sem ser root? pode fornecer alguma inspiração.
fonte
Uma maneira de pelo menos impedir que o processo grave os arquivos (mas não os crie) é ligar
ulimit -f 0
primeiro. Isso interromperá o processo assim que ele tentar gravar em um arquivo, mas a criação de arquivos vazios ainda é possível.fonte