Eu queria saber se existe uma maneira de executar um programa C não confiável em uma área restrita no Linux. Algo que impediria o programa de abrir arquivos ou conexões de rede, bifurcação, exec, etc?
Seria um pequeno programa, uma tarefa de casa, que é carregada em um servidor e tem testes de unidade executados nele. Portanto, o programa teria vida curta.
Respostas:
Eu usei o Systrace para colocar programas não confiáveis na sandbox tanto interativamente quanto no modo automático. Ele tem um
ptrace()
backend baseado em que permite seu uso em um sistema Linux sem privilégios especiais, bem como um backend muito mais rápido e poderoso que requer patch do kernel.Também é possível criar uma sandbox em sistemas do tipo Unix usando
chroot(1)
, embora isso não seja tão fácil ou seguro. Os contêineres do Linux e as jaulas do FreeBSD são uma alternativa melhor ao chroot. Outra alternativa no Linux é usar um framework de segurança como SELinux ou AppArmor , que é o que eu proporia para sistemas de produção.Seríamos capazes de ajudá-lo mais se você dissesse exatamente o que é que você deseja fazer.
EDITAR:
Systrace funcionaria para o seu caso, mas acho que algo baseado no modelo de segurança do Linux, como AppArmor ou SELinux, é uma alternativa mais padrão e, portanto, preferencial, dependendo da sua distribuição.
EDIT 2:
Embora
chroot(1)
esteja disponível na maioria (todos?) Dos sistemas do tipo Unix, tem alguns problemas:Ele pode ser quebrado. Se você for realmente compilar ou executar programas C não confiáveis em seu sistema, estará especialmente vulnerável a esse problema. E se seus alunos forem parecidos com os meus, alguém VAI tentar escapar da prisão.
Você deve criar uma hierarquia de sistema de arquivos totalmente independente com tudo o que é necessário para sua tarefa. Você não precisa ter um compilador no chroot, mas tudo o que é necessário para executar os programas compilados deve ser incluído. Embora existam utilitários que ajudam com isso, ainda não é trivial.
Você tem que manter o chroot. Por ser independente, os arquivos chroot não serão atualizados junto com sua distribuição. Você terá que recriar o chroot regularmente ou incluir as ferramentas de atualização necessárias nele, o que essencialmente requer que seja uma distribuição Linux completa. Você também terá que manter os dados do sistema e do usuário (senhas, arquivos de entrada, etc.) sincronizados com o sistema host.
chroot()
protege apenas o sistema de arquivos. Não impede que um programa malicioso abra sockets de rede ou um programa mal escrito de sugar todos os recursos disponíveis.O problema de uso de recursos é comum entre todas as alternativas. As cotas do sistema de arquivos impedirão que os programas ocupem o disco. As configurações adequadas
ulimit
(setrlimit()
em C) podem proteger contra o uso excessivo de memória e quaisquer bombas de fork, bem como acabar com os devoradores de CPU.nice(1)
pode diminuir a prioridade desses programas para que o computador possa ser usado para quaisquer tarefas consideradas mais importantes sem problemas.fonte
Recentemente, escrevi uma visão geral das técnicas de sandboxing no Linux . Acho que sua abordagem mais fácil seria usar contêineres Linux (lxc) se você não se importasse com bifurcação e assim por diante, o que realmente não importa neste ambiente. Você pode dar ao processo um sistema de arquivos raiz somente leitura, uma conexão de rede de loopback isolada e ainda pode eliminá-lo facilmente e definir limites de memória, etc.
Seccomp vai ser um pouco difícil, já que o código nem consegue alocar memória.
Selinux é a outra opção, mas acho que pode dar mais trabalho do que um container.
fonte
Você pode usar o Qemu para testar atribuições rapidamente. O procedimento abaixo leva menos de 5 segundos no meu laptop de 5 anos.
Vamos supor que o aluno tenha que desenvolver um programa que aceite ints sem sinal, cada um em sua própria linha, até que uma linha com "-1" chegue. O programa deve então calcular a média de todos os ints e saída "Média:% f". Veja como você pode testar o programa completamente isolado:
Primeiro, pegue o
root.bin
Jslinux, vamos usar isso como a área de usuário (tem o compilador C tcc):wget https://github.com/levskaya/jslinux-deobfuscated/raw/master/root.bin
Queremos colocar o envio do aluno
root.bin
, então configure o dispositivo de loop:sudo losetup /dev/loop0 root.bin
(você poderia usar fuseext2 para isso também, mas não é muito estável. Se estabilizar, você não precisará do root para nada disso)
Faça um diretório vazio:
mkdir mountpoint
Monte
root.bin
:sudo mount /dev/loop0 mountpoint
Digite o sistema de arquivos montado:
cd mountpoint
.Direitos de correção:
sudo chown -R `whoami` .
mkdir -p etc/init.d
vi etc/init.d
:chmod +x etc/init.d/rcS
Copie o envio para a VM:
cp ~/student_assignment.c root/assignment.c
Saia do FS raiz da VM:
cd ..
sudo umount mountpoint
mkfifo /tmp/guest_output
Abra um terminal separado e comece a ouvir a saída do convidado:
dd if=/tmp/guest_output bs=1
Em outro terminal:
qemu-system-i386 -kernel vmlinuz-3.5.0-27-generic -initrd root.bin -monitor stdio -nographic -serial pipe:/tmp/guestoutput
(Acabei de usar o kernel do Ubuntu aqui, mas muitos kernels funcionarão)Quando a saída do convidado mostra "READY", você pode enviar chaves para a VM a partir do prompt do qemu. Por exemplo, para testar esta tarefa, você poderia fazer
Agora
Average = 12.000000
deve aparecer no tubo de saída do convidado. Se não, o aluno falhou.quit
Um programa que passou no teste está aqui: https://stackoverflow.com/a/14424295/309483 . Basta usar em
tcclib.h
vez destdio.h
.fonte
Experimente o Linux no modo de usuário . Ele tem cerca de 1% de sobrecarga de desempenho para trabalhos com uso intensivo de CPU, mas pode ser 6 vezes mais lento para trabalhos com uso intenso de E / S.
fonte
Firejail é uma das ferramentas mais abrangentes para fazer isso - suporta seccomp, contêineres de sistema de arquivos, recursos e muito mais:
https://firejail.wordpress.com/features-3/
fonte
Executá-lo dentro de uma máquina virtual deve oferecer a você toda a segurança e restrições que você deseja.
O QEMU seria uma boa opção para isso e todo o trabalho (baixar o aplicativo, atualizar a imagem do disco, iniciar o QEMU, executar o aplicativo dentro dele e salvar a saída para recuperação posterior) poderia ser criado para testes automatizados.
fonte
Quando se trata de sanboxing com base no check-out de ptrace (strace):
" sydbox " sandbox e biblioteca de programação " pinktrace " (é C99, mas existem ligações para python e ruby até onde eu sei).
Links coletados relacionados ao tópico:
http://www.diigo.com/user/wierzowiecki/sydbox
(desculpe, não links diretos, mas ainda não há pontos de reputação suficientes)
fonte
seccomp e seccomp-bpf fazem isso com o mínimo esforço: https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt
fonte
Esta biblioteca deve servir bem ao seu objetivo
http://sandbox.sourceforge.net
Boa sorte!
fonte
Isso também parece promissor. Uma caixa de areia do sistema de arquivos para Linux usando interceptações syscall.
https://github.com/adtac/fssb
fonte
ok graças a todas as respostas eles me ajudaram muito. Mas eu não sugeriria nenhum deles como solução para a pessoa que fez a pergunta original. Todas as ferramentas mencionadas exigem muito trabalho com o propósito de testar o código dos alunos como professor, tutor, prof. A melhor forma neste caso seria na minha opinião o virtualbox. Ok, isso emula um sistema x68 completo e não tem nada a ver com o significado de sandboxing dessa forma, mas se eu imaginar meu professor de programação, seria o melhor para ele. Então "apt-get install virtualbox" em sistemas baseados em debian, todos os outros vão para http://virtualbox.org/ , crie uma vm, adicione uma iso, clique em instalar, espere um pouco e tenha sorte. Será muito mais fácil de usar para configurar o modo de usuário-linux ou fazer alguma coisa pesada ...
E se você tem medo de seus alunos hackearem você, eu acho que você tem um problema de autoridade e uma solução para isso seria ameaçá-los de que você os processará até a morte se puder provar apenas uma mordida de maleware no trabalho que eles dão vocês...
Além disso, se houver uma classe e 1% dela for tão boa quanto ele poderia fazer essas coisas, não os entedie com tarefas tão simples e dê a eles algumas grandes onde eles tenham que codificar um pouco mais. A aprendizagem integrativa é melhor para todos, então não confie em velhas estruturas em impasse ...
E, claro, nunca use o mesmo computador para coisas importantes (como redigir atestados e exames), que você está usando para coisas como navegar na web e testar software.
Use um computador off-line para coisas importantes e um computador on-line para todas as outras coisas.
No entanto, para todos os outros que não são professores paranóicos (não quero ofender ninguém, sou apenas a opinião de que você deve aprender o básico sobre segurança e nossa sociedade antes de começar a ser um professor de programadores ...)
... onde eu estava ... para todos os outros:
feliz hackeando !!
fonte