Garanta a segurança de programas com um sandbox SELinux Sandbox segura joseasreyes, 123RF CAPA É difícil manter seu navegador livre de scripts e aplicativos suspeitos. Um sandbox com SELinux mantém todas as ameaças em um ambiente seguro. por Thorsten Scherf Normalmente, o Firefox é tido como muito seguro, mas a popularidade não é proteção contra falhas de software. Em julho de 2009, a Fundação Mozilla revelou vários bugs no Firefox 3.5, incluindo um erro no compilador JavaScript Just-in-Time (JIT). Se o usuário, com uma versão vulnerável do navegador, entrasse em um site que possui algum código feito para explorar essa falha, um ataque poderia executar códigos arbitrários no cliente, o que representa um grande risco aos usuários que armazenam números de cartões de crédito ou qualquer outra informação importante no navegador. O sistema de controle obrigatório de acesso SELinux [1] foi desenvolvido para evitar que um intruso que tenha encontrado uma brecha no sistema consiga privilégios. A intenção original do SELinux era proteger serviços do sistema, porém, há algum tempo, a equipe de desenvolvedores resolveu proteger os navegadores e outros aplicativos de desktop. O objetivo é fornecer uma sandbox isolada que permita ao navegador executar códigos pouco confiáveis de modo mais seguro. Mas o conjunto de regras do SELinux para navegadores não é tão simples quanto parece. Por exemplo, muitos aplicativos em um desktop Gnome desejam ter controle completo do diretório home do usuário. Além do mais, o aplicativo precisa se comunicar com o sistema de mensagens do computador (D-Bus), e o servidor X sob o Firefox precisa de acesso 34 http://www.linuxmagazine.com.br
SELinux CAPA ao diretório /tmp. Uma das bases do SELinux, o princípio do menor privilégio, é de difícil implementação devido aos relacionamentos complexos de componentes independentes. A equipe de desenvolvedores do SELinux, na Red Hat, resolveu criar um tipo de jaula virtual onde seria possível manter aplicativos gráficos como o Firefox. A solução resultante foi ao mesmo tempo inteligente e elegante. Em vez de dar ao aplicativo acesso direto aos diretórios /tmp e /home, o utilitário sandbox oferece ao aplicativo diferentes diretórios mapeados para os alvos necessários. Para enjaular um aplicativo, basta digitar a seguinte linha: Figura 1 A política da sandbox permite acesso aos arquivos do tipo sandbox_x_file_t, mas não aos do tipo tmp_t. sandbox -X evince Como funciona A ferramenta sandbox cria uma jaula virtual formada por dois novos diretórios: um deles localizado no diretório home do usuário, e o outro no diretório /tmp/. Cada um dos diretórios recebe seu próprio contexto SELinux. Diferentes aplicativos são colocados em diferentes jaulas, tornando impossível que, digamos, um leitor de PDFs sendo executado em uma sandbox acesse o arquivo de senhas do navegador, que está sendo executado em outra sandbox. Depois, o módulo seunshare monta os novos diretórios. Cada vez que o aplicativo é iniciado, encontra diretórios /tmp/ e home novos e, portanto, vazios. O seunshare inicia o shell do usuário, mais uma vez usando o contexto SE- Linux da sandbox, sandbox_ x_t:mcs, e um rótulo MCS (Multi-Category Security) aleatório. Aplicativos clientes dentro de uma prisão recebem o rótulo sandbox_x_ client_t. Existe uma política detalhada para que esse domínio especifique qual acesso é permitido o módulo de política da sandbox (por exemplo, o leitor de PDF precisará de Figura 2 A sandbox permite acesso apenas a recursos específicos. Figura 3 Iniciar um aplicativo com o rótulo sandbox_net_t permite total acesso à rede. um servidor X e de um gerenciador de janela). O servidor X não consegue acessar o sistema anfitrião. O aplicativo é executado em tela cheia no gerenciador de janelas dedicado da sandbox, e isso evita o acesso a outras funções do gerenciador de janelas. Inicialmente, o acesso à Listagem 1: Trecho do arquivo sandbox.if 01 type $1_t, sandbox_x_domain; 02 domain_type($1_t) 04 type $1_file_t, sandbox_file_type; 05 files_type($1_file_t) 06 07 type $1_client_t, sandbox_x_domain; 08 domain_type($1_client_t) 09 10 can_exec($1_client_t, $1_file_t) 11... rede também é impossível a partir da sandbox. Os arquivos precisam do rótulo sandbox_x_file_t; caso contrário, a política evitará o acesso a eles (figuras 1 e 2). Para permitir que um aplicativo acesse a rede a partir de sua sandbox, é possível iniciá-lo com um Linux Magazine #64 Março de 2010 35
CAPA SELinux Listagem 2: Abertura proibida # sesearch --allow -s sandbox_t -t etc_t -c file Found 2 semantic av rules: allow sandbox_domain etc_t : file { read write getattr lock append } ; allow sandbox_domain file_type : file entrypoint ; Listagem 3: sesearch mostra a política 01 $ sesearch --allow -s sandbox_t -c file -p open -d 02 Found 1 semantic av rules: allow sandbox_t sandbox_file_t : file { ioctl read write create getattr setattr lock append 04 unlink link rename execute execute_no_trans open } ; rótulo diferente, no lugar do padrão sandbox_x_client_t. Por exemplo, para permitir que o Firefox tenha acesso externo, inicie-o com o rótulo sandbox_web_t: sandbox -X \ -t sandbox_web_t firefox O rótulo sandbox_net_t permite acesso irrestrito à rede (figura 3), mas é aconselhável certo cuidado. A ideia da sandbox é permitir acesso específico e, caso um aplicativo executado com o rótulo sandbox_net_t possua falhas, ele pode transportar dados importantes do sistema ou do usuário para fora da sandbox, apesar de todas as precauções. Por esse motivo, cada aplicativo deve ter Listagem 4: Ping proibido acesso apenas ao protocolo de rede necessário para seu funcionamento. Os desenvolvedores do SELinux fizeram várias macros bem úteis para desenvolver políticas customizadas. Para criar regras para aplicativos arbitrários, pode-se usar sandbox_x_domain_template. Por exemplo, se for necessário que um aplicativo acesse o smtp a partir da sandbox, basta acessar a macro de sua própria política deste modo: sandbox_x_domain_template(sandbox _mail) Uma olhada no código de definição da macro (listagem 1) rapidamente revela o que acontece quando ela é chamada. Ao acessar a macro, 01 type=avc msg=audit(1256541838.863:183): avc: denied { create } for pid=5474 02 comm= ping scontext=unconfined_u:unconfined_r:sandbox_t:s0:c313,c341 tcontext=unconfined_u:unconfined_r:sandbox_t:s0:c313,c341 tclass=rawip_socket Listagem 5: Trecho do arquivo audit.log 01 type=avc msg=audit(1256575191.000:861): avc: denied { name_ connect } 02 for pid=15663 comm= telnet dest=25 scontext=xguest_u:xguest_ r:xguest_t:s0 tcontext=system_u:object_r:smtp_port_t:s0 tclass=tcp_socket ela apresenta um framework básico para um novo domínio SELinux no qual o aplicativo será executado. Se suas regras forem adicionadas depois, é possível chamar o semodule para adicionar ao sistema o módulo de política recém-compilado. Scripts Além disso, a sandbox é útil para executar com segurança scripts novos ou desconhecidos e aplicativos não gráficos [2]. Essa técnica é particularmente útil no caso do download de um script cuja fonte não seja muito confiável. Executar o aplicativo desconhecido em uma sandbox utiliza os códigos pré-definidos, que especificam os tipos de acesso permitidos ao script. A sintaxe é semelhante a dos aplicativos gráficos, mas é possível deixar de fora a opção -X: # ls -lz /etc/passwd -rw-r--r--. root root system_u:object_r:etc_t:s0 /etc/passwd # sandbox cat /etc/passwd cut -d: -f1 /bin/cat: /etc/passwd: Permission denied Normalmente, a listagem 2 devolveria uma lista das contas de usuários existentes, mas a política não dá permissão para abrir arquivos do tipo etc_t, o que efetivamente evita que aplicativos executados em uma sandbox os acessem (listagem 2). Essa regra pode parecer confusa a princípio, pois não especifica as permissões de leitura e escrita. Logicamente, é necessário passar os descritores de arquivos para a sandbox nesse tipo de acesso. Se o script for modificado como mostra o código a seguir, você terá as restrições de acesso necessárias: cat /etc/passwd sandbox cut \ -d: -f1 36 http://www.linuxmagazine.com.br
SELinux CAPA Mais uma vez, é recomendável verificar a política para conferir os detalhes de permissões de acesso (listagem 3). Se for necessário que um aplicativo tenha autonomia para abrir um arquivo a partir da sandbox, esse arquivo deve ser do tipo sandbox_file_t; caso contrário, o acesso não é permitido. Geralmente, o acesso à rede é proibido aos scripts no domínio sandbox_t (listagem 4); para alterar isso, é preciso um grupo de regras para o domínio sandbox_t. O desenvolvimento das funções da sandbox está apenas no começo e, por isso, elas estão disponíveis apenas no Fedora 12, por enquanto. Algumas funções, tais como copiar e colar entre a sandbox e o sistema anfitrião, ou a capacidade de armazenar arquivos em uma sandbox, ainda não foram implementadas. Provavelmente, estarão disponíveis em um futuro próximo. Listagem 6: Política do xguest para SMTP 01 # mkdir ~/policy 02 # cat > xguest_smtp.te <<eof 04 policy_module(xguest_smtp,1.0.0) 05 06 require { 07 type xguest_t; 08 } 09 10 #============= xguest_t ============== 11 corenet_tcp_connect_smtp_port(xguest_t) 12 13 # make -f /usr/share/selinux/devel/makefile 14 Compiling targeted xguest_smtp module 15 /usr/bin/checkmodule: loading policy configuration from tmp /xguest_smtp.tmp 16 /usr/bin/checkmodule: policy configuration loaded 17 /usr/bin/checkmodule: writing binary representation (version 10) to 18 tmp/xguest_smtp.mod 19 Creating targeted xguest_smtp.pp policy package 20 rm tmp/xguest_smtp.mod.fc tmp/xguest_smtp.mod 21 22 # semodule -i xguest_smtp.pp 23 # semodule -l grep xguest_smtp 24 xguest_smtpt 1.0.0 Complete a sua coleção O objetivo da coleção é trazer conhecimento confiável e de alto nível sempre com enfoque prático e voltado para a utilização do sistema Linux e de outras tecnologias livres. Mais informações Site: www.linuxmagazine.com.br Linux Magazine #64 Março de 2010 Tel: 11 4082-1300 37
CAPA SELinux Listagem 7: Novas contas para xguest 01 # usermod -Z xguest_u foobar 02 # semanage login -l 04 Login Name SELinux User MLS/MCS Range 05 06 _default unconfined_u s0-s0:c0.c1023 07 foobar xguest_u s0 08 root unconfined_u s0-s0:c0.c1023 09 system_u system_u s0-s0:c0.c1023 10 xguest xguest_u s0 Quiosque Caso você tenha gostado do que viu até agora e queira restringir o acesso de aplicativos no seu servidor, seria interessante conferir a conta guest/ xguest em um sistema SELinux. Essa conta permite confinar um usuário dentro de um terminal (guest) ou de uma sessão de desktop (xguest) e permite apenas o acesso definido por regras (módulo de política guest/xguest). Enquando o sandbox usa principalmente a implementação de Type Enforcement (TE) do SELinux para restringir o acesso a recursos, uma conta guest/xguest depende também do Role Based Access Control (RBAC Controle de Acesso Baseado em Função). Após a união das políticas estritas e de alvo, apenas um conjunto de regras fica disponível. Se um sistema for acessado por uma conta xguest, o shell do usuário é inicializado no domínio SELinux xguest protegido. O usuário recebe do SELinux o papel de xguest, que permite acesso apenas a domínios específicos. HTTP. A política também impede a execução de arquivos nos diretórios /tmp/ e home do usuário. Caso o usuário queira baixar um programa malicioso usando o Firefox, a política xguest irá interromper o programa, evitando, assim, maiores problemas. Porém, se for realmente necessário conceder uma permissão a um u- suário xguest para executar arquivos arbitrários, pode-se usar: setsebool -P \ allow_xguest_exec_content=1 Para permitir acesso a outros serviços de rede a partir do domínio xguest, é necessário um módulo de política separado. Se for preciso dar permissão para um usuário xguest mandar emails, o domínio precisará acessar a porta SMTP. Sem uma regra que permita esse acesso, ele seria proibido, como é possível ver no trecho do arquivo audit.log na Mais informações [1] SELinux: http://selinux.sourceforge.net/ listagem 5. Um módulo separado irá garantir a acesso SMTP (listagem 6). Após adicionar ao sistema o novo módulo de política, o acesso baseado em SMTP deverá funcionar. Se for preciso estender a política, verifique outras mensagens de negação no arquivo audit.log e depois inclua instruções no módulo de política para alterar os tipos de acesso. A última questão é como adicionar uma conta de usuário ao domínio xguest. O mais fácil seria usar a ferramenta usermod para contas já existentes ou useradd para novas contas (listagem 7). Quando um usuário se conectar a um desktop, toda a sua sessão será executada no domínio xguest protegido pelo SELinux: $ id -Z xguest_u:xguest_r:xguest_t:s0 Conclusões A nova tecnologia de sandbox do SELinux facilita a colocação de aplicativos nas mãos protetoras do SELinux. As regras do SELinux foram desenvolvidas para proteger serviços individuais do sistema, e a proteção pelo controle obrigatório de acesso agora foi estendida aos usuários comuns. Graças ao xguest, novos tipos de aplicativos estão no radar do SELinux. n # id -Z xguest_u:xguest_r:xguest_t:s0 O módulo de política xguest controla o acesso a recursos individuais. Todos os aplicativos do usuário serão executados no domínio xguest. Os aplicativos não têm permissão irrestrita de acesso à rede, com exceção do navegador Firefox, que tem permissão irrestrita de acesso [2] Apresentação da sandbox SELinux: http://danwalsh.livejournal.com/28545.html [3] SELinux no Fedora: http://fedoraproject.org/wiki/selinux Gostou do artigo? Queremos ouvir sua opinião. Fale conosco em cartas@linuxmagazine.com.br Este artigo no nosso site: http://lnm.com.br/article/3336 38 http://www.linuxmagazine.com.br