SELinux: Segurança no Linux que você não pode ignorar

Muitos tutoriais começam com uma instrução assustadora:

\> "DESATIVE O SELinux..."

No começo, só para seguir o tutorial, eu sempre desativava. Mas depois, pesquisando mais, percebi o quão essencial essa camada de segurança é!

🔒 O que é o SELinux?

O Security-Enhanced Linux (SELinux) é uma camada extra de segurança que controla o que pode ou não ser acessado no sistema. Mesmo que as permissões tradicionais (como chmod e chown) estejam liberadas, o SELinux impede acessos não autorizados com base em políticas rígidas.

Pense nele como um "porteiro" extra que só permite ações explicitamente autorizadas.

🎭 DAC vs MAC: Os dois modelos de controle de acesso

DAC (Discretionary Access Control)

O DAC, ou Controle de Acesso Discricionário, é o modelo tradicional de permissões no Linux. Nele, o dono do arquivo ou diretório decide quem pode acessá-lo, usando as permissões de leitura, escrita e execução para:

  • Usuário (dono)

  • Grupo

  • Outros

Por exemplo, um arquivo com permissão -rw-r--r-- significa que:

  • O dono pode ler e escrever.

  • O grupo pode ler.

  • Outros podem ler.

Mas o dono do arquivo tem o poder de mudar essas permissões a qualquer momento, daí o termo "discricionário" — o controle é "à vontade" do dono.

touch segredo.txt  
chmod 600 segredo.txt  
chown usuario1:usuario1 segredo.txt

Agora apenas usuario1 pode ler e escrever o arquivo, e outros usuários não têm acesso.

🚫 MAC (Mandatory Access Control)

O MAC, ou Controle de Acesso Obrigatório, é uma camada extra e mais rígida. Aqui, o sistema define regras que não podem ser mudadas pelos usuários comuns, nem pelo dono do arquivo. Essas regras obrigam os processos e usuários a respeitarem políticas de segurança pré-definidas.

Se o SELinux estiver ativo e houver uma política de bloqueio, mesmo que o usuário rode:

chmod 777 segredo.txt

O acesso ainda será negado!

É aí que o SELinux brilha, garantindo que ninguém mude permissões de forma indiscriminada.

Por que o SELinux é importante?

  • Camada extra de proteção: Mesmo que alguém mal-intencionado ou um programa com falha consiga acesso, o SELinux pode impedir ações não autorizadas.

  • Controle detalhado: Você pode configurar políticas específicas para limitar o comportamento dos programas, tornando o sistema mais seguro e estável.

  • Prevenção de exploração: Reduz a chance de vulnerabilidades se transformarem em ataques reais.

Como trabalhar com o SELinux?

O SELinux possui três modos principais de operação:

  • Enforcing: O SELinux está ativo e aplicando as regras.

  • Permissive: O SELinux não bloqueia, mas registra o que seria bloqueado (ótimo para testar as regras sem causar problemas).

  • Disabled: O SELinux está desligado.

🔎 Verificando o status do SELinux

Para saber se o SELinux está ativo, execute:

sestatus

Se mostrar SELinux status: disabled, ele está desativado. Caso contrário, ele pode estar em modo enforcing ou permissive.

🔄 Como ativar o SELinux

1️⃣ Editar o arquivo de configuração:

sudo vim /etc/selinux/config

Altere SELINUX=disabled para:

SELINUX=enforcing

⚠️ Quer testar sem bloquear nada? Use SELINUX=permissive.

2️⃣ Reiniciar o sistema:

sudo reboot

3️⃣ Confirmar se está ativo:

Deve mostrar algo como:

[root@sudoersblog ~]# 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
Memory protection checking:     actual (secure)
Max kernel policy version:      33

🛠 Mudando o modo do SELinux sem reiniciar

sudo setenforce 1  # Modo enforcing (ativo)  
sudo setenforce 0  # Modo permissive (somente registra)  
getenforce  # Exibe o modo atual

🚀 Testando restrições do SELinux com Apache

Para demonstrar como as permissões do SELinux funcionam na prática, instalei rapidamente um servidor Apache em minha máquina de teste. Com isso, podemos simular o Apache rodando com as permissões corretas e, também, verificar como o SELinux pode bloquear o acesso.

Configurando e testando o Apache

Após configurar o meu index.html, executei o comando abaixo:

curl http://localhost

Saída esperada:

[root@sudoersblog sudoersblog]# curl http://localhost  
Bem-vindo ao Sudoers Blog !

Agora, consultando as permissões do arquivo, verificamos que ele está dentro do contexto httpd:

[root@sudoersblog html]# ls -Z  
unconfined_u:object_r:httpd_sys_content_t:s0 index.html

📌 Mas o que significa essa saída?

Vamos explicar cada parte:

  • unconfined_u → Usuário SELinux (sem restrições específicas).

  • object_r → Tipo de objeto (arquivo normal).

  • httpd_sys_content_t → Tipo que indica conteúdo web para o Apache (o "pulo do gato").

  • s0 → Nível de sensibilidade padrão.

O que faz o ls -Z?

O comando ls todo mundo conhece: ele lista arquivos e diretórios. Mas o -Z exibe o contexto de segurança do SELinux nos arquivos listados.

Alterando o arquivo para um diretório fora do contexto do Apache

Criei um novo arquivo index.html fora do contexto do Apache:

cd /home/sudoersblog  

echo "Bem-vindo ao Sudoers Blog!" > index.html

Saída do comando:

[root@sudoersblog sudoersblog]# curl http://localhost  
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">  
<html><head>  
<title>403 Forbidden</title>  
</head><body>  
<h1>Forbidden</h1>  
<p>You don't have permission to access this resource.</p>  
</body></html>  
[root@sudoersblog sudoersblog]#

⚠️ A casa caiu! Sem acesso!

Isso acontece porque, além da camada DAC, agora entra também o MAC, verificando se o arquivo está dentro do contexto esperado. Consultando novamente as permissões do arquivo:

[root@sudoersblog sudoersblog]# ls -Z  
unconfined_u:object_r:user_home_t:s0 index.html

Cadê o contexto do httpd? Simplesmente não existe aqui!

🔁 Corrigindo as permissões do SELinux para o Apache

O Apache não tem permissão para ler arquivos com o contexto user_home_t. Mesmo que as permissões tradicionais (chmod) estejam liberadas, o SELinux bloqueia o acesso.

Para resolver isso, precisamos adicionar o arquivo ao contexto correto do SELinux:

semanage fcontext -a -t httpd_sys_content_t "/home/sudoersblog(/.*)?"  
restorecon -Rv /home/sudoersblog

📌 O que esses comandos fazem?

  • semanage fcontext -a -t httpd_sys_content_t "/home/sudoersblog(/.*)?"

    • Diz ao SELinux: "Ei, todos os arquivos e pastas dentro de /home/sudoersblog devem ser tratados como conteúdo web do Apache."
  • restorecon -Rv /home/sudoersblog

    • Restaura os contextos de segurança do SELinux para todos os arquivos e pastas dentro de /home/sudoersblog.

Agora, ao executar ls -Z novamente:

[root@sudoersblog sudoersblog]# ls -Z  
unconfined_u:object_r:httpd_sys_content_t:s0 index.html

Tudo certo! Agora, bora testar!

🚀 Testando novamente o acesso ao Apache

[root@sudoersblog sudoersblog]# curl http://localhost  
Bem-vindo ao Sudoers Blog !

Agora a página carrega corretamente!

UFA! Esse tema me empolgou demais! Mexer com Linux sempre me fascina, mas cuidado ao testar essas configurações em ambientes de produção uma configuração mal feita pode gerar grandes problemas.

💡 Antes de aplicar qualquer ajuste, valide tudo corretamente!

Aliás, enquanto montava este artigo, acabei perdendo uma VM com Ubuntu. Foi aí que descobri que distros baseadas em Debian não possuem suporte nativo ao SELinux! (Funciona, mais da um trabalho legal.)

Sendo assim, tive que refazer a máquina para poder demonstrar (um pouco) como tudo funciona.

🚀 Valeu, pessoal! Semana que vem tem mais!

2
Subscribe to my newsletter

Read articles from Hudson Alves Amaral directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Hudson Alves Amaral
Hudson Alves Amaral