Uma das técnicas utilizadas em segurança de servidores é a criação de um sistema isolado que dificultam o ataque de usuário que possuem acesso a determinado recurso mas que não devem ter acesso a outros.
Estou trabalhando em um projeto que já queria ter desenvolvido a algum tempo. Neste semestre tive uma disciplina onde o trabalho final era de tema livre, a única restrição era a linguagem em que o sistema deveria ser implementado, no meu caso, Erlang. Já faz algum tempo que estou estudando linguagens funcionais e achei esta uma bela oportunidade.
O sistema desenvolvido consiste em uma aplicação web onde os usuários submetem códigos, a aplicação compila-os e retorna a saída. Funciona como ideone.com. Meus objetivos com ele são:
Aprender novas técnologias e resolver novos problemas;
Me divertir. Objetivo de quase todos os projetos que desenvolvo sozinho;
Utiliza-lo em minicurso que eventualmente eu apresento por ai.
Bom, meu objetivo 1 foi logo alcançado. Encontrei um problema que ainda não tinha resolvido em algum outro projeto que desenvolvi. Eu estaria dando acesso a um profissional qualificado(ou não) ao meu servidor para ele poder criar uma aplicação. Esse é um tremendo problema de segurança.
No primeiro momento pensei em virtualização, porém meus recursos financeiros não permitem-me chegar muito longe nesta solução. Realizei algumas pesquisas e resolvi adotar o modo que descreverei neste artigo. Talvez haja um jeito bem melhor, porém acredito que o jeito implementado seja válido.
Em segurança da informação, o termo Sandbox é utilizado para referenciar um ambiente controlado onde são executados procedimentos que podem danificar um sistema.
Bom, realmente não sou especialista nesta área. Por isso adicionei mais alguns artigos sobre o assunto abaixo do post.
Minha experiencia com esse aplicativo dava-se apenas a alteração da senha de root de sistemas instalados em laboratórios onde tive aula. Sempre gostei de ser root, poder instalar minhas aplicações favoritas e não ter que depender do técnico para executar um simples fsck.
O comando Chroot altera o diretório raiz do processo corrente e dos processos filhos do processo corrente para o diretório passado como argumento. Assim, todos os comandos executados e todas as suas implicações serão relativas ao novo sistema de arquivos.
Por exemplo, ao executarmos o comando # chroot /jails/root
o diretório
passado como argumento torna-se o “/”, sendo assim, no processo filho, quando eu executo
um ls
na raiz, na verdade eu estarei executando /jails/root/bin/ls /jails/root
. E isto
ajuda-me a resolver o problema descrito na Introdução.
Como todo sistema e aplicação, existem falhas nesta técnica, existe como um usuário preso na jail sair(também adicionei um artigo falando sobre isso no final do post), mas no caso em que estarei executando o processo dentro do jail, até o usuário rodar a aplicação que quebre, provavelmente o sistema já terá encerrado sua execução.
Neste ponto começarei a ser um pouco especifico. Neste exemplo irei mostrar um jeito fácil de criar a estrutura de diretórios tendo como base os sistemas operacionais Fedora ou CentOS(provavelmente não diferenciar muito em um Red Hat, mas como eu não cheguei a testar eu não vou afirmar nada).
Podemos criar os todos os diretórios base manualmente e copiar os aplicativos e libs para eles ou podemos pegar um pronto. Neste artigo, como escrevi anteriormente, irei mostrar como fazer isso de forma simples com o auxilio do yum.
Vamos criar o diretório destino:
# mkdir -p /jails/root/var/lib/rpm
Agora vamos iniciar a base de dados do yum:
# rpm --root /jails/root --initdb
O próximo passo é obter o pacote rpm base do sistema. Se você tiver instalado o programa yumdownloader você pode utilizá-lo para obter este pacote:
yumdownloader --destdir=/tmp fedora-release
: No Fedora
yumdownloader --destdir=/tmp centos-release
: No CentOS
Ou pode obte-lo fazendo download:
wget http://archive.fedoraproject.org/pub/fedora/linux/releases/17/Fedora/x86_64/os/Packages/f/fedora-release-17-1.noarch.rpm
: No caso do Fedora 17
wget http://mirror.centos.org/centos/6.2/os/x86_64/Packages/centos-release-6-2.el6.centos.7.x86_64.rpm
: No caso do CentOs 6.2
Eu adicionei os links para o pacote mais recente de cada distribuição, se você precisar de outra versão, a organização dos diretórios é bem intuitiva e podem ser obtidos seguindo o mesmo caminho.
rpm -i --root=/jails/root --nodeps os-release.rpm
Para instalar novos pacotes através do yum podemos utilizar o comando passando o parametro installroot, como o exemplo:
yum --installroot=/jails/root install bash
Para executarmos o jail basta executarmos o comando.
# chroot /jails/root
Para alterar o diretório raiz utilizando o comando chroot você precisa estar logado como root, porém podemos acessá-lo como um usuário normal através do comando fakechroot. O comando fakechroot torna possibilita um usuário criar sua própria sandbox.
Para executarmos o bash, ou outro comando qualquer, dentro de uma jail utilizando o fakechroot podemos utilizar o seguinte comando.
fakechroot /path/to/command/chroot /path/to/directory/jail /bin/bash
Fazia muito tempo que eu não gastava tanto tempo para resolver um problema de infra. Gosto muito de estudar essa área, porém não estou com muito tempo para o mesmo.
Se alguém tiver alguma dúvida peço que utilize o sistema de comentários do site. Mesmo que eu não saiba responder de imediato, irei procurar a resposta pois tenho muito interesse nestes tipos de problemas e colocarei a resposta aqui.