O SELinux
O Security-Enhanced Linux – SELinux – foi desenvolvido pela Agência Nacional de Segurança dos EUA (NSA). Logo no início, seu objetivo principal era tornar-se um sistema operacional capaz de fornecer controles avançados de acesso para os órgãos militares dos Estados Unidos.
Porém, com o passar do tempo, a NSA identificou que seria mais lógico aprimorar um sistema de controle de acesso obrigatório, e adicioná-los a um sistema operacional já existente. A opção pelo GNU/Linux surgiu devida à facilidade e flexibilidade de incorporar tal framework ao Kernel do sistema. Logo depois, sistemas que traziam a plataforma Unix, também usufruíram desta tão poderosa ferramenta. Altamente implementado e refinado em cima da arquitetura MAC (Mandatory Access Control), provendo maior segurança a arquivos, diretórios, processos, sistema de arquivos, entre outros objetos, através de regras providas pelo SELinux. Vale ressaltar, que este nível de segurança vai além da arquitetura DAC (Discretionary Access Control) que está associada à permissão de arquivos e ACLs (Access Control List’s) do GNU/Linux, como exemplo, as permissões MAC podem ser aplicadas até ao usuário root, limitando ações do mesmo. Em um conceito prático, imaginemos que a conta de sistema associada ao serviço HTTP foi comprometida, o SELinux através de regras pré estabelecidas, limita este comprometimento apenas ao serviço HTTP, impossibilitando o comprometimento de outros serviços, ou até mesmo, do próprio sistema operacional. Depois deste breve conceito, vamos à prática. Lembrando que mais informações do SELinux, podem ser obtidas na Wiki do Projeto: Ou, na página oficial da NSA: Modo de operação do SELinux (conceito e prática)Basicamente, o SELinux pode operar em três tipos diferentes, que são:
Obs.: Para nossos testes, estou utilizando o CentOS 6.3. Visualizando o status do SELinux: # sestatus Saída do comando:
Caso se queira visualizar apenas o Current mode do SELinux, utilize o comando: # getenforce Saída do comando:
Perceba que este comando traz apenas o modo de operação do SELinux. Para alterarmos o modo de operação temporário do SELinux (apenas Enforcing e Permissive), utilizaremos o seguinte comando: # setenforce MODO_DE_OPERAÇÂO Ex.: # setenforce permissive Logo, visualize o status do SELinux: # sestatus
Obs.: Para desabilitar, ou alterar, o ‘current mode’ do SELinux por completo, é necessário editar o arquivo de configuração do SELinux (/etc/selinux/config) e alterar a variável: ‘SELINUX=’.
* Apenas como fonte de informação:
|
||||
Contextos de segurança
Em uma explicação básica, um contexto é um valor de dado assumido pelos objetos de uma classe.
Nome, Idade e Peso, são exemplos de contextos do objeto “Pessoa”. Cor, Categoria e Modelo, são possíveis contextos do objeto “Carro”. No caso, os contextos da arquitetura DAC são: Tipo, Dono, Grupo e Outros. Ex.: # ls –ld /etc Saída do comando:
Onde:
No caso da arquitetura MAC, os contextos mudam de características, conforme: Usuário, Papel, Tipo e Nível. Onde:
Na prática, com o mesmo diretório /etc: # ls –Zd Saída do comando:
Onde:
Visualizando contextos MAC nos objetos do sistemaPara visualizar todos os processos que estão rodando no sistema, juntamente com os contextos do SELinux, vamos utilizar o comando abaixo: # ps auxZ Perceba que apenas adicionando a opção “Z” no comando ps, já é suficiente para visualizarmos os contextos de todos os processos do SELinux. Isto vale para outros comandos também, como por exemplo, o comando ls. Vamos visualizar o contexto de um arquivo ou diretório qualquer do sistema: # ls –Z /boot Saída do comando:
Isso vale também para o comando id, que nos traz informações de um determinado usuário: Ex.: # id –Z Saída do comando:
Perceba que neste caso, todo o contexto está definido como: unconfined_* …Isto indica que o SELinux não terá influência alguma no objeto correspondente. |
||||
O comando Semanage
Para um bom entendimento do SELinux, é necessário explorar o mesmo por completo, o comando semanage traz uma série de opções para que isso aconteça.
Primeiro, devemos instalar o conjunto de pacotes, que traz (além de vários outros) o comando Semanage: # yum install policycoreutils-python Com o Semanage instalado em nossa máquina, vamos listar todos os usuários, nível de MLS/MCS e papéis (roles) do SELinux: # semanage user –l Onde: -l = list Saída do comando:
Pergunta: “ual a função de cada usuário? Permissão? Acessos e etc…? Vamos a um overview rápido e objetivo de cada um:
Agora que já sabemos as reais permissões dos usuários do SELiux, vamos listar todos os usuários do sistema que estão atrelados aos usuários e permissões do SELinux: # semanage login –l Saída do comando:
Apenas como fonte de conhecimento, vamos criar um usuário chamado “teste”, e referenciá-lo ao usuário “guest_u” do SELinux: # useradd –c “Usuário Teste” –d /home/teste –m –k /etc/skel –s /bin/bash teste Onde:
Logo, liste os logins novamente: # semanage login –l
Perceba que agora, o usuário “teste”, está atrelado ao usuário do SELinux “guest_u”, obtendo automaticamente as mesmas permissões do mesmo. Tente logar na área gráfica com o usuário “teste”. Depois tente logar com o mesmo usuário, em algum terminal. Perceba que as permissões do usuário “guest_u” do SELinux, não permitem o login na área gráfica, somente no terminal. Agora, experimente atrelar o usuário “teste” ao usuário “xguest_u”. Neste momento, o usuário “teste” tem as devidas permissões para acessar a área gráfica. Para remover o usuário “teste” das diretivas do SELinux, basta executar o comando: # semanage login -d teste Onde: -d = delete Continuando com o comando semanage, vamos listar todos os contextos aplicados no sistema: # semanage fcontext –l Assim, fica muito mais fácil saber se determinado objeto ou serviço, está atrelado às politicas MAC do SELinux. Mais informações sobre o comando semanage: # semanage – -help |
||||
Os comandos Chcon e Restorecon
Diversas vezes, nos deparamos com problemas de permissão de contextos no SELinux, isto acontece frequentemente, ainda mais em serviços que têm uma alta rotatividade de objetos, como File Servers e FTP.
Para resolver este problema, utilizaremos o comando chcon, sua função nada mais é do que alterar contextos em objetos. Para os nossos testes com o chcon, vamos criar um arquivo denominado “teste.txt” dentro do diretório /etc: # touch /etc/teste.txt Verifique os contextos deste arquivo: # ls -Z /etc/teste.txt Saída do comando:
Perceba que o usuário está definido como “unconfined_u”. Imagine agora, que precisamos alterar (por algum motivo qualquer) para o usuário “user_u”. Vamos utilizar o seguinte comando: # chcon -u user_u /etc/teste.txt Onde: -u = user # ls -Z /etc/teste.txt Saída do comando:
Perceba que, agora o arquivo está com o contexto de usuário definido para “user_u”. Caso precisamos (por algum motivo qualquer) alterar o domínio (type) deste objeto, para “tmp_t”: # chcon -t tmp_t /etc/teste.txt Onde: -t = type # ls -Z /etc/teste.txt Saída do comando:
Pronto, o arquivo está com seu domínio alterado, assim, todos os objetos que tem acesso ao domínio “tmp_t”, terão acesso ao arquivo /etc/teste.txt. Em um último teste do comando chcon, imaginamos que você queira clonar o contexto de outro objeto?! O chcon também faz isso: # chcon –reference /var /etc/teste.txt Saída do comando:
Obs.: Caso você queira aplicar contextos recursivamente, basta inserir a opção “-R” no comando chcon. Em muitos casos, queremos deixar o objeto de acordo com as regras do domínio (type) no qual o mesmo está armazenado. Poderíamos utilizar o chcon e copiar todos os contextos, ou utilizar um comando que faz exatamente isso. Este comando é o restorecon, vamos vê-lo em detalhes: # restorecon -F /etc/teste.txt Com este comando, o arquivo “teste.txt” herdará todos os contextos do diretório /etc (local onde o mesmo está armazenado). Útil, não?! =) Os comandos chcon e restorecon, são extremamente úteis e complexos, para um maior detalhamento dos mesmos, leia a Man Page oficial: # man chcon |
||||
Variáveis booleanas
As variáveis booleanas nada mais são, do que ligar(1) ou desligar(0) determinada ação (seja temporário ou não).
Um exemplo seria, imaginamos que determinada aplicação necessita de acesso a gravação no sistema, caso não existisse as variáveis booleanas, teríamos que reescrever o código do SELinux para permitir tal ação! As mesmas são extremamente úteis para qualquer um que queira administrar o SELinux. Para uma prática eficiente com as variáveis booleanas, é só lembrar dos termos 0 e 1, ou para ficar mais fácil: nã0 e s1m. =) Vamos à mais um case! Vamos instalar um serviço de FTP (apenas de exemplo), e gerenciar as variáveis booleanas: # yum install vsftpd E, adicionar aos níveis de execução: # chkconfig –level 2345 vsftpd on Agora, vamos reiniciar o serviço: # service vsftpd restart Agora que já temos o serviço devidamente instalado, vamos gerenciar as variáveis booleanas. Primeiro, vamos listá-las: # getsebool -a Onde: -a = all – Pergunta: Apenas com o nome das variáveis, fica difícil saber para que cada uma serve? # semanage boolean -l Onde: -l = list Perceba que agora, temos os nomes das variáveis, e também uma breve descrição de cada uma delas. Vamos filtrar as variáveis para tudo que atrela-se ao serviço FTP: # semanage boolean -l | grep ftp Saída do comando:
Por padrão, o serviço VSFTPD não permite o total gerenciamento de arquivos para o usuário anonymous, isso devido às restrições do SELinux! Caso você queira dar tal permissão para o usuário anonymous (ou outros usuários), basta setar a variável: allow_ftpd_full_access Com ela é possível dar controle total a qualquer usuário que conecte no FTP (lembrando que esse é apenas mais um teste). – Pergunta: E como fazer isso? # setsebool -P allow_ftpd_full_access 1 Onde:
Pronto! Seu servidor FTP está dando controle total para qualquer usuário. Feliz agora?! Bom, eu não ficaria, pois estamos abrindo um furo na segurança do sistema. Portanto, vamos desativar a variável booleana correspondente: # setsebool -P allow_ftpd_full_access 0 Onde: 0 = Desativar a variável. Lembre-se: As variáveis booleanas são extremamente importantes para a boa administração do SELinux, liste e teste cada uma delas, assim tudo ficara mais fácil. 😉 |
||||
O comando Semodule
Assim, como o próprio sistema GNU/Linux, o SELinux opera em formato modular, ou seja, caso precise adicionar exceções, ou aprimoramento, de regras no SELinux para determinadas aplicações, como por exemplo um MTA, ou um servidor Web, não será necessária a recompilação do próprio sistema SELinux.
E sim, adicionar um código externo (módulo) que indique tal ação. Este módulo pode ser fornecido tanto pela equipe que administra a aplicação, quanto construída pelo próprio administrador do SELinux. Obs.: Não confunda os módulos do SELinux com as variáveis booleanas. Os módulos são funções acrescentadas nas regras de determinada aplicação, já as variáveis booleanas, são permissões referentes à comunicação entre aplicação e objetos do sistema. O comando que gerencia tais módulos no SELinux, é o Semodule, e sua utilização é muito simples. Para listar os módulos do SELinux: # semodule -l Onde: -l = list Saída do comando (resumida):
Caso precisemos desabilitar determinado módulo, como por exemplo, o módulo do Asterisk, utilizaremos a seguinte sintaxe do comando semodule: # semodule -d asterisk Onde: -d = disable Agora, vamos listar os módulos, filtrando apenas o módulo do Asterisk: # semodule -l | grep asterisk Saída do comando:
Perceba que este módulo está presente, porém sem qualquer funcionalidade. Para remover o módulo por completo, utilize o comando: # semodule -r asterisk Onde: -r = remove # semodule -l Listando novamente os módulos, perceba que o mesmo não se encontra mais na listagem. – Pergunta: E se eu precisar do módulo do Asterisk novamente, o que eu faço? Simples, não?! Agora basta achar tal arquivo “.pp” do Asterisk. Por padrão, o diretório /usr/share/selinux/targeted/ contém diversos arquivos de pacotes de políticas (*.pp). Estes arquivos estão inclusos no pacote “selinux-policy”, e são utilizados para construir o arquivo de política. Em diversas distribuições, como o CentOS e Red Hat, tais arquivos podem estar compactados, porém, a descompactação não se faz necessária para instalação. Como estamos trabalhando com módulos defaults, o arquivo “.pp” do Asterisk está armazenado neste diretório, portanto, vamos reativá-lo: # cd /usr/share/selinux/targeted/ # semodule -i asterisk.pp.bz2 Onde: -i = Install # semodule -l | grep asterisk Perceba que não precisamos habilitar o módulo novamente, apenas com a instalação do mesmo, ele já fica em modo enable. Caso o módulo não fique em modo enable, basta executar o comando semodule com a opção “-e”, seguida do nome do módulo, no nosso caso, seria o “asterisk”. Para mais opções do comando semodule, basta executar: # man semodule |
||||
Auditoria e logs
Com relação à auditoria e depuração de Logs, o SELinux lida muito bem com isso, a começar pelo pacote Setroubleshoot, a junção de diversos aplicativos é uma “Mãe” para qualquer administrador SELinux. A ferramenta demonstra os alertas de AVC do SELinux, e ainda diz qual comando pode corrigir o mesmo.
Falando em AVC, sigla para Access Vector Cache (e não para Acidente Vascular Cerebral), que nada mais é do que alertas de acessos bloqueados sejam elas de aplicação ou usuários do sistema. Primeiramente, vamos instalar o pacote “Setroubleshoot”. Obs.: Caso tenha interface gráfica no servidor, o mesmo irá instalar um pequeno utilitário, que alerta toda vez que um AVC acontecer. # yum install setroubleshoot Antes de qualquer coisa, vamos gerar o nosso próprio AVC. – Pergunta: Mas como assim, o nosso próprio AVC? Vamos aos testes: Instale o serviço HTTP no Servidor: # yum install –y httpd Abra o arquivo de configuração: # vim /etc/httpd/conf/httpd.conf Altere a seguinte linha do arquivo: Listen 80 Para: Listen 8888
Logo, reinicie o serviço HTTP: # service httpd restart Pronto, nosso AVC foi gerado com êxito. =) O primeiro comando para verificação de AVC’s, é o ausearch: # ausearch –m avc | grep httpd Onde: -m = message Saída do comando (resumida): type=AVC msg=audit(1344678620.633:26191): avc: denied { name_bind } for pid=9429 comm=”httpd” src=8888 scontext=unconfined_u:system_r:httpd_t:s0 tcontext=system_u:object_r:port_t:s0
tclass=tcp_socket Perceba que a saída do comando demonstra claramente, o motivo dele ter alarmado tal AVC. – Pergunta: (Bruno, beleza!) Eu “já sei” o que aconteceu pela saída do log, mas agora eu quero que a porta 8888 seja padrão do serviço HTTP, irá continuar gerando AVC’s? Existem duas maneiras de se fazer isso, uma é utilizar o comando semanage com a opção “port”, a outra é o que iremos ver abaixo. Primeiro, vamos utilizar o comando selatert para analisar os logs: # sealert –a /var/log/audit/audit.log | grep httpd Onde:
Saída do comando (resumida):
Analisando a saída, perceba que além de detalhar a possível causa do AVC, ele sugere (caso você realmente queira), indicar a alteração de porta padrão do serviço HTTPD para 8888 ao SELinux. Vamos utilizar o comando que ele sugeriu: # grep httpd /var/log/audit/audit.log | audit2allow -M mypol Onde:
Saída do comando:
Perceba que a saída do comando deixa bem claro que, caso você queira tornar tal módulo ativo, é necessário que você o instale via semodule. Porém, caso você liste o diretório corrente, irá perceber que existem 2 arquivos mypol: # ls Saída do comando:
O arquivo “mypol.te” indica um tipo de arquivo de execução (Type Enforcement), ou seja, ele tem toda instrução do que será executado/alterado no sistema através do arquivo “mypol.pp”. Já o arquivo “mypol.pp”, nada mais é o que o pacote de politicas (Package Policy), ou o módulo propriamente dito. Agora que sabemos qual arquivo instalar, vamos utilizar o semodule para isso: # semodule -i mypol.pp Depois de alguns segundos, o arquivo foi instalado com êxito. Será? Liste os módulos, e veja você mesmo: # semodule –l | grep ^m Saída do comando:
Olha só, o nosso modulo “mypol” instalado e habilitado no sistema. Ou seja, funcionou! =D Vale reforçar que, a criação de módulos com o “audit2allow”, só é aconselhada caso você saiba realmente o que esteja fazendo, utilizar o “audit2allow” apenas para resolver os alertas de AVC do SELinux, estará causando um grande furo de segurança ao sistema. Bom galera, é isso. O artigo foi básico, em relação à complexidade do SELinux, porém, espero que tenha sido útil para aqueles que estão começando com esta tão poderosa ferramenta. Meu muito obrigado, e até a próxima! =D |