Uma das características mais importantes, além da administração centralizada, é o isolamento dos processos e objetos em domínio, evitando, por exemplo, que um processo de um determinado domínio possa ter acesso a arquivos de outro domínio, a menos que essa ação seja devidamente autorizada. Isso impede que um atacante, que comprometeu um servidor HTTP, possa, a partir daí, ter acesso a arquivos de um servidor Samba, por exemplo.
Para proteger os processo ou serviços do S.O., o SELinux isola os mesmos em domínios diferentes, ou seja, os processos são confinados, para que em caso de algum incidente, isso não comprometa o sistema como um todo.
Por padrão, quase todos os serviços de rede, no CentOS 7, estão confinados em seus próprios domínios. Por exemplo, o processo de um servidor web httpd, executa no domínio httpd_t.
A seguir, será realizado um teste, para verificarmos como o SELinux bloqueia o acesso indevido.
O primeiro passo é verificarmos se o SELinux está sendo executado e se o mesmo está no modo Enforcing. Aqui foi usado o comando
sestatus:
# sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28
O próximo passo é a criação de um arquivo, para que possamos testar o acesso usando domínios diferentes. Note que aqui foi utilizado, para a criação do arquivo, o usuário root, para que possamos demonstrar que mesmo o superusuário não tem permissões suficientes para sobrepor as dos rótulos do contexto de segurança.
Por padrão, o usuário root roda como unconfined, sendo assim, os arquivos criados pelo mesmo seguem o mesmo padrão. O modelo de controle de acesso RBAC tem seu foco nos processos, mas pode-se observar um papel genérico no arquivo, o object_r, usado em sistema de arquivos de rede.
A observação mais importante aqui, está no campo tipo do contexto de segurança, que neste caso é o httpd_sys_context, este tipo permite que o processo httpd possa acessar o arquivo, que foi criado no diretório
/var/www/http/.
Veja:
# ls -Z VOL.txt
-rw-r--r--. root root unconfined_u:object_r:httpd_sys_content_t:s0 VOL.txt
Agora vamos verificar, com o uso do utilitário
wget, se é possível copiar o arquivo que foi criado anteriormente, para um diretório onde o usuário tem permissão de escrita, neste caso, é para o meu diretório
home. Se tudo ocorreu bem, deve ser apresentada a seguinte mensagem:
# wget http://localhost/VOL.txt
--2014-11-27 11:17:34-- http://localhost/VOL.txt
Resolvendo localhost (localhost)... ::1, 127.0.0.1
Conectando-se a localhost (localhost)|::1|:80... conectado.
A requisição HTTP foi enviada, aguardando resposta... 200 OK
Tamanho: 0 [text/plain]
Salvando em: "VOL.txt"
[ <=> ] 0 --.-K/s em 0s
2014-11-27 11:17:34 (0,00 B/s) - "VOL.txt" salvo [0/0]
Agora, vamos modificar o atributo do campo tipo do arquivo,
VOL.txt, utilizando o comando
chcon. As mudanças de rótulo com esse utilitário não são permanentes, mas serviram para este teste.
# chcon -t samba_share_t VOL.txt
Utilizando o comando
ls -Z /var/www/http/VOL.txt, é possível visualizarmos a mudança do contexto de segurança, no campo tipo do arquivo. Outra observação importante para o teste, é que a mudança não alterou nada no modelo de controle DAC, e que as permissões para o usuário utilizado, usuário root, permanecem as mesmas.
# ls -Z /var/www/html/VOL.txt
-rw-r--r--. root root unconfined_u:object_r:samba_share_t:s0
/var/www/html/VOL.txt
Utilizando novamente o utilitário
wget, nota-se que não é mais possível realizar a cópia do arquivo, mesmo para isso, usando o usuário root, administrador do sistema.
Sendo assim, comprova-se que mesmo um servidor que tenha seu serviço web comprometido com algum tipo de falha, usuários maliciosos não poderão utilizar-se desta falha, para ter acesso a arquivos que estão configurados com o SELinux.
# wget http://localhost/VOL.txt
--2014-11-27 11:35:05-- http://localhost/VOL.txt
Resolvendo localhost (localhost)... ::1, 127.0.0.1
Conectando-se a localhost (localhost)|::1|:80... conectado.
A requisição HTTP foi enviada, aguardando resposta... 403 Forbidden
2014-11-27 11:35:05 ERRO 403: Forbidden.
Com os registros de log também pode-se observar, quando a tentativa de acesso ao arquivo é negada. Para isso, acesse o arquivo
/var/log/audit/audit.log:
type=AVC msg=audit(1417098905.465:71): avc: denied { getattr } for pid=1928 comm="httpd" path="/var/www/html/VOL.txt" dev="dm-1" ino=50699744
scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:samba_share_t:s0 tclass=file
type=SYSCALL msg=audit(1417098905.465:71): arch=c000003e syscall=6 success=no exit=-13 a0=7fc158dbfb00 a1=7fff3779a350 a2=7fff3779a350 a3=0 items=0 ppid=1922 pid=1928 auid=4294967295 uid=48 gid=48 euid=48 suid=48
fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null)
Este artigo tem como objetivo a demonstração básica do conceito do SELinux e um exemplo simples de sua utilização.