Red Hat Training

A Red Hat training course is available for RHEL 8

Usando SELinux

Red Hat Enterprise Linux 8

Configuração básica e avançada do Linux Avançado em Segurança (SELinux)

Resumo

Este título auxilia usuários e administradores no aprendizado dos princípios básicos e princípios sobre os quais a SELinux funciona e descreve tarefas práticas para a criação e configuração de vários serviços.

Tornando o código aberto mais inclusivo

A Red Hat tem o compromisso de substituir a linguagem problemática em nosso código, documentação e propriedades da web. Estamos começando com estes quatro termos: master, slave, blacklist e whitelist. Por causa da enormidade deste esforço, estas mudanças serão implementadas gradualmente ao longo de vários lançamentos futuros. Para mais detalhes, veja a mensagem de nosso CTO Chris Wright.

Fornecendo feedback sobre a documentação da Red Hat

Agradecemos sua contribuição em nossa documentação. Por favor, diga-nos como podemos melhorá-la. Para fazer isso:

  • Para comentários simples sobre passagens específicas:

    1. Certifique-se de que você está visualizando a documentação no formato Multi-page HTML. Além disso, certifique-se de ver o botão Feedback no canto superior direito do documento.
    2. Use o cursor do mouse para destacar a parte do texto que você deseja comentar.
    3. Clique no pop-up Add Feedback que aparece abaixo do texto destacado.
    4. Siga as instruções apresentadas.
  • Para enviar comentários mais complexos, crie um bilhete Bugzilla:

    1. Ir para o site da Bugzilla.
    2. Como Componente, use Documentation.
    3. Preencha o campo Description com sua sugestão de melhoria. Inclua um link para a(s) parte(s) relevante(s) da documentação.
    4. Clique em Submit Bug.

Capítulo 1. Começando com a SELinux

1.1. Introdução à SELinux

O Security Enhanced Linux (SELinux) oferece uma camada adicional de segurança do sistema. O SELinux responde fundamentalmente à pergunta: May <subject> do <action> to <object>?, por exemplo May a web server access files in users' home directories?

A política de acesso padrão baseada no usuário, grupo e outras permissões, conhecida como Controle de Acesso Discricionário (DAC), não permite que os administradores de sistema criem políticas de segurança abrangentes e de granulação fina, tais como restringir aplicações específicas a apenas visualizar arquivos de log, enquanto permite que outras aplicações anexem novos dados aos arquivos de log.

A SELinux implementa o Controle de Acesso Obrigatório (MAC). Cada recurso de processo e sistema tem uma etiqueta de segurança especial chamada SELinux context. Um contexto SELinux, às vezes referido como SELinux label, é um identificador que abstrai os detalhes em nível de sistema e se concentra nas propriedades de segurança da entidade. Isto não apenas fornece uma maneira consistente de referenciar objetos na política SELinux, mas também elimina qualquer ambiguidade que possa ser encontrada em outros métodos de identificação. Por exemplo, um arquivo pode ter vários nomes de caminho válidos em um sistema que faz uso de suportes de encadernação.

A política SELinux utiliza estes contextos em uma série de regras que definem como os processos podem interagir uns com os outros e os vários recursos do sistema. Por padrão, a política não permite qualquer interação, a menos que uma regra conceda acesso explícito.

Nota

Lembre-se de que as regras da política SELinux são verificadas após as regras do DAC. As regras de política SELinux não são usadas se as regras do DAC negarem o acesso primeiro, o que significa que nenhuma negação do SELinux é registrada se as regras tradicionais do DAC impedirem o acesso.

Os contextos SELinux têm vários campos: usuário, função, tipo e nível de segurança. A informação do tipo SELinux é talvez a mais importante quando se trata da política SELinux, como a regra política mais comum que define as interações permitidas entre processos e recursos do sistema utiliza tipos SELinux e não o contexto SELinux completo. Os tipos de SELinux terminam com _t. Por exemplo, o nome do tipo para o servidor web é httpd_t. O contexto do tipo para arquivos e diretórios normalmente encontrados em /var/www/html/ é httpd_sys_content_t. O tipo de contexto para arquivos e diretórios normalmente encontrado em /tmp e /var/tmp/ é tmp_t. O contexto do tipo para as portas do servidor web é http_port_t.

Há uma regra de política que permite ao Apache (o processo do servidor web funcionando como httpd_t) acessar arquivos e diretórios com um contexto normalmente encontrado em /var/www/html/ e outros diretórios de servidores web (httpd_sys_content_t). Não há uma regra de permissão na política para arquivos normalmente encontrados em /tmp e /var/tmp/, portanto, o acesso não é permitido. Com o SELinux, mesmo que o Apache esteja comprometido, e um script malicioso ganhe acesso, ele ainda não é capaz de acessar o diretório /tmp.

Figura 1.1. Um exemplo de como a SELinux pode ajudar a administrar o Apache e a MariaDB de forma segura.

SELinux_Apache_MariaDB_example

Como o esquema anterior mostra, o SELinux permite que o processo Apache em execução como httpd_t acesse o diretório /var/www/html/ e nega o mesmo processo para acessar o diretório /data/mysql/ porque não há regra de permissão para os contextos do tipo httpd_t e mysqld_db_t. Por outro lado, o processo MariaDB rodando como mysqld_t pode acessar o diretório /data/mysql/ e o SELinux também nega corretamente o processo com o tipo mysqld_t para acessar o diretório /var/www/html/ rotulado como httpd_sys_content_t.

Recursos adicionais

Para mais informações, consulte a seguinte documentação:

  • A página de homem selinux(8) e as páginas de homem listadas pelo comando apropos selinux.
  • Páginas de homem listadas pelo comando man -k _selinux quando o pacote selinux-policy-doc é instalado.
  • O Livro Colorido SELinux ajuda você a entender melhor os conceitos básicos da SELinux.
  • SELinux Wiki FAQ

1.2. Vantagens de executar o SELinux

A SELinux oferece os seguintes benefícios:

  • Todos os processos e arquivos são etiquetados. As regras da política SELinux definem como os processos interagem com os arquivos, assim como como os processos interagem uns com os outros. O acesso só é permitido se existir uma regra de política SELinux que o permita especificamente.
  • Controle de acesso com granulação fina. Indo além das tradicionais permissões UNIX que são controladas a critério do usuário e baseadas em IDs de usuário e grupo Linux, as decisões de acesso ao SELinux são baseadas em todas as informações disponíveis, tais como um usuário SELinux, função, tipo e, opcionalmente, um nível de segurança.
  • A política da SELinux é definida administrativamente e aplicada em todo o sistema.
  • Melhoria na mitigação de ataques de escalada de privilégios. Os processos correm em domínios e, portanto, são separados uns dos outros. As regras da política SELinux definem como os processos acessam os arquivos e outros processos. Se um processo for comprometido, o atacante só tem acesso às funções normais desse processo, e aos arquivos aos quais o processo foi configurado para ter acesso. Por exemplo, se o Servidor HTTP Apache for comprometido, um atacante não pode utilizar esse processo para ler arquivos nos diretórios domésticos do usuário, a menos que uma regra de política específica do SELinux tenha sido adicionada ou configurada para permitir tal acesso.
  • A SELinux pode ser usada para reforçar a confidencialidade e integridade dos dados, bem como para proteger processos contra entradas não confiáveis.

No entanto, a SELinux não é:

  • software antivírus,
  • substituição de senhas, firewalls e outros sistemas de segurança,
  • solução de segurança "tudo em um".

A SELinux é projetada para melhorar as soluções de segurança existentes, não para substituí-las. Mesmo ao executar o SELinux, é importante continuar seguindo boas práticas de segurança, tais como manter o software atualizado, utilizando senhas difíceis de adivinhar e firewalls.

1.3. Exemplos de SELinux

Os exemplos a seguir demonstram como a SELinux aumenta a segurança:

  • A ação padrão é negar. Se uma regra da política SELinux não existir para permitir o acesso, como para um processo de abertura de um arquivo, o acesso é negado.
  • A SELinux pode confinar os usuários do Linux. Há uma série de usuários de SELinux confinados na política SELinux. Os usuários Linux podem ser mapeados para usuários confinados do SELinux para aproveitar as regras e mecanismos de segurança aplicados a eles. Por exemplo, mapear um usuário Linux para o usuário do SELinux user_u, resulta em um usuário Linux que não é capaz de executar, a menos que configurado de outra forma, aplicações de identificação de usuário (setuid), tais como sudo e su, bem como impedi-lo de executar arquivos e aplicações potencialmente maliciosos em seu diretório pessoal.
  • Aumento do processo e separação de dados. O conceito do SELinux domains permite definir quais processos podem acessar certos arquivos e diretórios. Por exemplo, ao executar o SELinux, a menos que configurado de outra forma, um atacante não pode comprometer um servidor Samba, e então utilizar esse servidor Samba como um vetor de ataque para ler e escrever em arquivos utilizados por outros processos, tais como bancos de dados MariaDB.
  • O SELinux ajuda a mitigar os danos causados por erros de configuração. Os servidores DNS (Domain Name System) freqüentemente replicam informações entre si no que é conhecido como transferência de zona. Os atacantes podem usar transferências de zona para atualizar os servidores DNS com informações falsas. Ao rodar o Berkeley Internet Name Domain (BIND) como um servidor DNS no Red Hat Enterprise Linux, mesmo que um administrador se esqueça de limitar quais servidores podem realizar uma transferência de zona, a política default do SELinux evita arquivos de zona [1] de ser atualizado usando transferências de zona, pelo próprio daemon BIND named, e por outros processos.


[1] Arquivos de texto que incluem informações, como o nome do host para mapeamento de endereços IP, que são usados por servidores DNS.

1.4. Arquitetura e embalagens SELinux

SELinux é um Módulo de Segurança Linux (LSM) que está embutido no kernel do Linux. O subsistema SELinux no kernel é conduzido por uma política de segurança que é controlada pelo administrador e carregada na inicialização. Todas as operações de acesso ao sistema relevantes para a segurança, em nível de kernel, são interceptadas pelo SELinux e examinadas no contexto da política de segurança carregada. Se a política carregada permitir a operação, ela continua. Caso contrário, a operação é bloqueada e o processo recebe um erro.

As decisões da SELinux, tais como permitir ou não o acesso, são armazenadas em cache. Este cache é conhecido como Access Vector Cache (AVC). Ao utilizar estas decisões em cache, as regras da política SELinux precisam ser menos verificadas, o que aumenta o desempenho. Lembre-se que as regras da política SELinux não têm efeito se as regras do DAC negarem o acesso primeiro. As mensagens brutas de auditoria são registradas no /var/log/audit/audit.log e começam com a seqüência type=AVC.

No Red Hat Enterprise Linux 8, os serviços do sistema são controlados pelo daemon systemd; systemd inicia e pára todos os serviços, e os usuários e processos comunicam-se com systemd usando o utilitário systemctl. O daemon systemd pode consultar a política SELinux e verificar a etiqueta do processo de chamada e a etiqueta do arquivo da unidade que o chamador tenta gerenciar, e então perguntar ao SELinux se o acesso é permitido ou não ao chamador. Esta abordagem fortalece o controle de acesso às capacidades críticas do sistema, que incluem iniciar e parar os serviços do sistema.

O daemon systemd também trabalha como um Gerente de Acesso SELinux. Ele recupera o rótulo do processo em execução systemctl ou o processo que enviou uma mensagem D-Bus para systemd. O daemon então procura a etiqueta do arquivo da unidade que o processo quis configurar. Finalmente, systemd pode recuperar informações do kernel se a política do SELinux permitir o acesso específico entre a etiqueta do processo e a etiqueta do arquivo de unidade. Isto significa que uma aplicação comprometida que precisa interagir com systemd para um serviço específico pode agora ser confinada pelo SELinux. Os redatores de políticas também podem utilizar estes controles de granulação fina para confinar os administradores.

Importante

Para evitar etiquetagem incorreta da SELinux e problemas subseqüentes, certifique-se de iniciar os serviços utilizando um comando systemctl start.

O Red Hat Enterprise Linux 8 fornece os seguintes pacotes para trabalhar com o SELinux:

  • políticas: selinux-policy-targeted, selinux-policy-mls
  • ferramentas: policycoreutils, policycoreutils-gui, libselinux-utils, policycoreutils-python-utils, setools-console, checkpolicy

1.5. SELinux estados e modos

A SELinux pode funcionar em um dos três modos: coercitivo, permissivo, ou desativado.

  • O modo de aplicação é o modo de operação padrão e recomendado; no modo de aplicação o SELinux opera normalmente, aplicando a política de segurança carregada em todo o sistema.
  • No modo permissivo, o sistema age como se o SELinux estivesse aplicando a política de segurança carregada, inclusive etiquetando objetos e emitindo entradas de negação de acesso nos logs, mas na verdade não nega nenhuma operação. Embora não seja recomendado para sistemas de produção, o modo permissivo pode ser útil para o desenvolvimento e depuração da política SELinux.
  • O modo desabilitado é fortemente desencorajado; não apenas o sistema evita a aplicação da política SELinux, mas também evita a etiquetagem de qualquer objeto persistente, como arquivos, dificultando a habilitação da SELinux no futuro.

Use o utilitário setenforce para mudar entre o modo coercitivo e permissivo. As mudanças feitas com setenforce não persistem através de reinicializações. Para mudar para o modo de imposição, digite o comando setenforce 1 como usuário root do Linux. Para mudar para o modo permissivo, digite o comando setenforce 0. Use o utilitário getenforce para visualizar o modo SELinux atual:

# getenforce
Enforcing
# setenforce 0
# getenforce
Permissive
# setenforce 1
# getenforce
Enforcing

No Red Hat Enterprise Linux, você pode definir domínios individuais para o modo permissivo enquanto o sistema roda em modo de execução. Por exemplo, para tornar o domínio httpd_t permissivo:

# semanage permissive -a httpd_t

Note que os domínios permissivos são uma ferramenta poderosa que pode comprometer a segurança de seu sistema. A Red Hat recomenda usar os domínios permissivos com cautela, por exemplo, na depuração de um cenário específico.

Capítulo 2. Mudança de estados e modos SELinux

Quando ativada, a SELinux pode funcionar em uma de duas modalidades: coercitiva ou permissiva. As seções seguintes mostram como mudar permanentemente para estes modos.

2.1. Mudanças permanentes nos estados e modos SELinux

Como discutido nos estados e modos SELinux, a SELinux pode ser ativada ou desativada. Quando ativada, a SELinux tem dois modos: coercitivo e permissivo.

Use os comandos getenforce ou sestatus para verificar em que modo o SELinux está funcionando. O comando getenforce retorna Enforcing, Permissive, ou Disabled.

O comando sestatus retorna o status SELinux e a política SELinux sendo utilizada:

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:      31
Nota

Quando os sistemas executam o SELinux em modo permissivo, os usuários e processos podem rotular incorretamente vários objetos do sistema de arquivos. Os objetos do sistema de arquivo criados enquanto o SELinux é desativado não são etiquetados de forma alguma. Este comportamento causa problemas quando se muda para o modo de execução porque o SELinux depende de etiquetas corretas dos objetos do sistema de arquivos.

Para evitar que arquivos com e sem rótulos incorretos causem problemas, os sistemas de arquivos são automaticamente reetiquetados ao mudar do estado desabilitado para o modo permissivo ou de imposição. No modo permissivo, use o comando fixfiles -F onboot como raiz para criar o arquivo /.autorelabel contendo a opção -F para garantir que os arquivos sejam reetiquetados na próxima reinicialização.

2.2. Mudando para o modo permissivo

Use o seguinte procedimento para mudar permanentemente o modo SELinux para permissivo. Quando o SELinux está em modo permissivo, a política SELinux não é aplicada. O sistema permanece operacional e o SELinux não nega nenhuma operação, mas apenas registra mensagens AVC, que podem então ser utilizadas para solução de problemas, depuração e melhorias na política SELinux. Neste caso, cada AVC é registrado apenas uma vez.

Pré-requisitos

  • Os pacotes selinux-policy-targeted, libselinux-utils, e policycoreutils estão instalados em seu sistema.
  • Os parâmetros do kernel selinux=0 ou enforcing=0 não são utilizados.

Procedimento

  1. Abra o arquivo /etc/selinux/config em um editor de texto de sua escolha, por exemplo:

    # vi /etc/selinux/config
  2. Configure a opção SELINUX=permissive:

    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #       enforcing - SELinux security policy is enforced.
    #       permissive - SELinux prints warnings instead of enforcing.
    #       disabled - No SELinux policy is loaded.
    SELINUX=permissive
    # SELINUXTYPE= can take one of these two values:
    #       targeted - Targeted processes are protected,
    #       mls - Multi Level Security protection.
    SELINUXTYPE=targeted
  3. Reinicie o sistema:

    # reboot

Etapas de verificação

  1. Após o reinício do sistema, confirme que o comando getenforce retorna Permissive:

    $ getenforce
    Permissive

2.3. Mudando para o modo de aplicação

Use o seguinte procedimento para mudar o SELinux para o modo de aplicação. Quando o SELinux está funcionando em modo de aplicação, ele aplica a política SELinux e nega o acesso com base nas regras da política SELinux. No RHEL, o modo de aplicação é ativado por padrão quando o sistema foi inicialmente instalado com o SELinux.

Pré-requisitos

  • Os pacotes selinux-policy-targeted, libselinux-utils, e policycoreutils estão instalados em seu sistema.
  • Os parâmetros do kernel selinux=0 ou enforcing=0 não são utilizados.

Procedimento

  1. Abra o arquivo /etc/selinux/config em um editor de texto de sua escolha, por exemplo:

    # vi /etc/selinux/config
  2. Configure a opção SELINUX=enforcing:

    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #       enforcing - SELinux security policy is enforced.
    #       permissive - SELinux prints warnings instead of enforcing.
    #       disabled - No SELinux policy is loaded.
    SELINUX=enforcing
    # SELINUXTYPE= can take one of these two values:
    #       targeted - Targeted processes are protected,
    #       mls - Multi Level Security protection.
    SELINUXTYPE=targeted
  3. Salve a mudança, e reinicie o sistema:

    # reboot

    Na próxima inicialização, o SELinux reetiqueta todos os arquivos e diretórios dentro do sistema e adiciona o contexto SELinux para arquivos e diretórios que foram criados quando o SELinux foi desativado.

Etapas de verificação

  1. Após o reinício do sistema, confirme que o comando getenforce retorna Enforcing:

    $ getenforce
    Enforcing
Nota

Depois de mudar para o modo de aplicação, a SELinux pode negar algumas ações por causa de regras incorretas ou ausentes da política da SELinux. Para ver quais ações o SELinux nega, digite o seguinte comando como raiz:

# ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts today

Alternativamente, com o pacote setroubleshoot-server instalado, entre:

# grep "SELinux is preventing" /var/log/messages

Se o SELinux estiver ativo e o daemon de Auditoria (auditd) não estiver rodando em seu sistema, então procure por certas mensagens SELinux na saída do comando dmesg:

# dmesg | grep -i -e type=1300 -e type=1400

Consulte Solução de problemas relacionados à SELinux para obter mais informações.

2.4. Habilitando a SELinux em sistemas que anteriormente a tinham desabilitado

Quando você habilita o SELinux em sistemas que anteriormente o tinham desabilitado, para evitar problemas, tais como sistemas incapazes de inicializar ou de processar falhas, siga este procedimento:

Procedimento

  1. Habilitar o SELinux em modo permissivo. Para mais informações, consulte Mudando para o modo permissivo.
  2. Reinicie seu sistema:

    # reboot
  3. Para mais informações, consulte Identificando as recusas da SELinux.
  4. Se não houver negações, mude para o modo de aplicação. Para mais informações, consulte Mudando os modos SELinux no momento da inicialização.

Etapas de verificação

  1. Após o reinício do sistema, confirme que o comando getenforce retorna Enforcing:

    $ getenforce
    Enforcing

Recursos adicionais

  • Para executar aplicações personalizadas com SELinux em modo de aplicação, escolha um dos seguintes cenários:

    • Execute sua aplicação no domínio unconfined_service_t.
    • Escreva uma nova política para sua aplicação. Veja o artigo Writing Custom SELinux Policy Knowledgebase para mais informações.
  • As mudanças temporárias nos modos são cobertas nos estados e modos SELinux.

2.5. Desabilitando a SELinux

Utilize o seguinte procedimento para desativar permanentemente a SELinux.

Importante

Quando a SELinux é desativada, a política SELinux não é carregada; ela não é aplicada e as mensagens AVC não são registradas. Portanto, todos os benefícios de executar o SELinux são perdidos.

A Red Hat recomenda fortemente o uso do modo permissivo em vez de desativar permanentemente o SELinux. Veja Mudando para o modo per missivo para mais informações sobre o modo permissivo.

Atenção

A desativação do SELinux usando a opção SELINUX=disabled no /etc/selinux/config resulta em um processo no qual o kernel inicia com o SELinux ativado e muda para o modo desativado mais tarde no processo de inicialização. Como podem ocorrer vazamentos de memória e condições de corrida causando pânico no kernel, prefira desativar o SELinux adicionando o parâmetro selinux=0 à linha de comando do kernel, conforme descrito em Mudando os modos SELinux no momento do boot, se seu cenário realmente exigir a desativação completa do SELinux.

Procedimento

  1. Abra o arquivo /etc/selinux/config em um editor de texto de sua escolha, por exemplo:

    # vi /etc/selinux/config
  2. Configure a opção SELINUX=disabled:

    # This file controls the state of SELinux on the system.
    # SELINUX= can take one of these three values:
    #       enforcing - SELinux security policy is enforced.
    #       permissive - SELinux prints warnings instead of enforcing.
    #       disabled - No SELinux policy is loaded.
    SELINUX=disabled
    # SELINUXTYPE= can take one of these two values:
    #       targeted - Targeted processes are protected,
    #       mls - Multi Level Security protection.
    SELINUXTYPE=targeted
  3. Salve a mudança, e reinicie seu sistema:

    # reboot

Etapas de verificação

  1. Após reiniciar, confirme que o comando getenforce retorna Disabled:

    $ getenforce
    Disabled

2.6. Mudança dos modos SELinux no momento da inicialização

Na inicialização, você pode definir vários parâmetros do kernel para mudar a maneira como o SELinux funciona:

aplicação=0

A definição deste parâmetro faz com que o sistema comece em modo permissivo, o que é útil na resolução de problemas. O uso do modo permissivo pode ser a única opção para detectar um problema se seu sistema de arquivos estiver muito corrompido. Além disso, no modo permissivo, o sistema continua a criar as etiquetas corretamente. As mensagens AVC que são criadas neste modo podem ser diferentes do que no modo de execução.

No modo permissivo, apenas a primeira negação de uma série das mesmas negações é relatada. No entanto, no modo permissivo, você pode obter uma negação relacionada à leitura de um diretório, e um aplicativo pára. No modo permissivo, você recebe a mesma mensagem AVC, mas o aplicativo continua lendo arquivos no diretório e você recebe um AVC para cada negação, além disso.

selinux=0

Este parâmetro faz com que o kernel não carregue nenhuma parte da infra-estrutura SELinux. Os scripts de inicialização notam que o sistema foi iniciado com o parâmetro selinux=0 e tocam no arquivo /.autorelabel. Isto faz com que o sistema volte a rotular automaticamente na próxima inicialização com o SELinux ativado.

Importante

A Red Hat não recomenda o uso do parâmetro selinux=0. Para depurar seu sistema, prefira usar o modo permissivo.

auto-rótulo=1

Este parâmetro força o sistema a re-etiquetagem de forma semelhante aos comandos a seguir:

# touch /.autorelabel
# reboot

Se um sistema de arquivo contém uma grande quantidade de objetos mal etiquetados, inicie o sistema em modo permissivo para que o processo de auto-etiquetagem seja bem sucedido.

Recursos adicionais

  • Para parâmetros adicionais de inicialização relacionados ao SELinux, tais como checkreqprot, veja o /usr/share/doc/kernel-doc-<KERNEL_VER>/Documentation/admin-guide/kernel-parameters.txt arquivo instalado com o pacote kernel-doc. Substitua a string <KERNEL_VER> pelo número da versão do kernel instalado, por exemplo:

    # yum install kernel-doc
    $ less /usr/share/doc/kernel-doc-4.18.0/Documentation/admin-guide/kernel-parameters.txt

Capítulo 3. Gerenciando usuários confinados e não confinados

As seções seguintes explicam o mapeamento de usuários Linux para usuários SELinux, descrevem os domínios básicos de usuários confinados e demonstram o mapeamento de um novo usuário para um usuário SELinux.

3.1. Usuários confinados e não confinados

Cada usuário Linux é mapeado para um usuário SELinux utilizando a política SELinux. Isto permite aos usuários do Linux herdar as restrições dos usuários do SELinux.

Para ver o mapeamento do usuário SELinux em seu sistema, use o comando semanage login -l como raiz:

semanage login -l
Login Name           SELinux User         MLS/MCS Range        Service

__default__          unconfined_u         s0-s0:c0.c1023       *
root                 unconfined_u         s0-s0:c0.c1023       *

No Red Hat Enterprise Linux, os usuários do Linux são mapeados para o SELinux default login por padrão, que é mapeado para o usuário do SELinux unconfined_u. A linha a seguir define o mapeamento padrão:

__default__          unconfined_u         s0-s0:c0.c1023       *

Os usuários de Linux confinados e não confinados estão sujeitos a verificações de memória executáveis e graváveis, e também são restringidos pelo MCS ou MLS.

Para listar os usuários SELinux disponíveis, digite o seguinte comando:

$ seinfo -u
Users: 8
   guest_u
   root
   staff_u
   sysadm_u
   system_u
   unconfined_u
   user_u
   xguest_u

Note que o comando seinfo é fornecido pelo pacote setools-console, que não é instalado por padrão.

Se um usuário Linux não definido executa uma aplicação que a política SELinux define como aquela que pode fazer a transição do domínio unconfined_t para seu próprio domínio confinado, o usuário Linux não definido ainda está sujeito às restrições desse domínio confinado. O benefício de segurança disto é que, mesmo que um usuário Linux esteja executando um domínio não-confinado, a aplicação permanece confinada. Portanto, a exploração de uma falha na aplicação pode ser limitada pela política.

Da mesma forma, podemos aplicar estas verificações a usuários confinados. Cada usuário confinado é restringido por um domínio de usuário confinado. A política SELinux também pode definir uma transição de um domínio de usuário confinado para seu próprio domínio alvo confinado. Nesse caso, os usuários confinados estão sujeitos às restrições desse domínio de destino confinado. O ponto principal é que privilégios especiais são associados aos usuários confinados de acordo com seu papel.

3.2. Capacidades do usuário SELinux

A tabela a seguir fornece exemplos de domínios básicos confinados para usuários Linux no Red Hat Enterprise Linux:

Tabela 3.1. Capacidades do usuário SELinux

UsuárioPapelDomínioSistema Janela Xsu ou sudoExecutar no diretório home e /tmp (padrão)Trabalho em rede

sysadm_u

sysadm_r

sysadm_t

sim

su e sudo

sim

sim

staff_u

staff_r

pessoal_t

sim

somente sudo

sim

sim

user_u

user_r

user_t

sim

não

sim

sim

guest_u

guest_r

guest_t

não

não

sim

não

xguest_u

xguest_r

xguest_t

sim

não

sim

Somente Firefox

  • Os usuários do Linux nos domínios user_t, guest_t, e xguest_t só podem executar aplicações set user ID (setuid) se a política SELinux o permitir (por exemplo, passwd). Estes usuários não podem executar as aplicações setuid su e sudo, e, portanto, não podem usar estas aplicações para se tornarem root.
  • Os usuários do Linux nos domínios sysadm_t, staff_t, user_t, e xguest_t podem fazer login usando o Sistema X Window e um terminal.
  • Por padrão, os usuários do Linux nos domínios staff_t, user_t, guest_t, e xguest_t podem executar aplicações em seus diretórios domésticos e /tmp.

    Para impedi-los de executar aplicações, que herdam as permissões dos usuários, em diretórios aos quais eles têm acesso por escrito, configure o guest_exec_content e xguest_exec_content booleans para off. Isto ajuda a evitar que aplicações defeituosas ou maliciosas modifiquem os arquivos dos usuários.

  • Os únicos usuários de acesso à rede Linux no domínio xguest_t têm o Firefox conectando-se a páginas web.
  • O usuário sysadm_u não pode fazer o login diretamente usando SSH. Para ativar os logins do SSH para sysadm_u, defina o booleano ssh_sysadm_login para on:

    # setsebool -P ssh_sysadm_login on

Note que system_u é uma identidade especial de usuário para processos e objetos do sistema. Ela nunca deve ser associada a um usuário Linux. Além disso, unconfined_u e root são usuários não-confinados. Por estas razões, eles não estão incluídos na tabela anterior de capacidades de usuário do SELinux.

Além dos já mencionados usuários do SELinux, existem papéis especiais, que podem ser mapeados para aqueles usuários usando o comando semanage user. Estas funções determinam o que o SELinux permite que o usuário faça:

  • webadm_r só pode administrar os tipos SELinux relacionados ao Servidor HTTP Apache.
  • dbadm_r só pode administrar os tipos SELinux relacionados ao banco de dados MariaDB e ao sistema de gerenciamento de banco de dados PostgreSQL.
  • logadm_r só pode administrar os tipos de SELinux relacionados com os processos syslog e auditlog.
  • secadm_r só pode administrar a SELinux.
  • auditadm_r só pode administrar processos relacionados com o subsistema de Auditoria.

Para listar todas as funções disponíveis, digite o comando seinfo -r:

seinfo -r
Roles: 14
   auditadm_r
   dbadm_r
   guest_r
   logadm_r
   nx_server_r
   object_r
   secadm_r
   staff_r
   sysadm_r
   system_r
   unconfined_r
   user_r
   webadm_r
   xguest_r

Note que o comando seinfo é fornecido pelo pacote setools-console, que não é instalado por padrão.

Recursos adicionais

  • Para mais informações, consulte as páginas de manual seinfo(1), semanage-login(8) e xguest_selinux(8).

3.3. Adicionando um novo usuário mapeado automaticamente ao usuário SELinux não-confinado_u

O procedimento a seguir demonstra como adicionar um novo usuário Linux ao sistema. O usuário é automaticamente mapeado para o usuário do SELinux unconfined_u.

Pré-requisitos

  • O usuário root está rodando sem definição, como faz por default no Red Hat Enterprise Linux.

Procedimento

  1. Digite o seguinte comando para criar um novo usuário Linux chamado example.user:

    # useradd example.user
  2. Para atribuir uma senha para o usuário do Linux example.user:

    passwd example.user
    Changing password for user example.user.
    New password:
    Retype new password:
    passwd: all authentication tokens updated successfully.
  3. Saia de sua sessão atual.
  4. Faça o login como usuário do Linux example.user. Quando você faz o login, o módulo pam_selinux PAM mapeia automaticamente o usuário Linux para um usuário SELinux (neste caso, unconfined_u), e configura o contexto SELinux resultante. O shell do usuário Linux é então lançado com este contexto.

Etapas de verificação

  1. Quando conectado como usuário do example.user, verifique o contexto de um usuário Linux:

    $ id -Z
    unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Recursos adicionais

  • Para mais informações, consulte a página de manual pam_selinux(8).

3.4. Adicionando um novo usuário como um usuário definido pelo SELinux

Use os seguintes passos para adicionar um novo usuário definido pelo SELinux ao sistema. Este procedimento de exemplo mapeia o usuário para o SELinux staff_u direito com o comando para criar a conta de usuário.

Pré-requisitos

  • O usuário root está rodando sem definição, como faz por default no Red Hat Enterprise Linux.

Procedimento

  1. Digite o seguinte comando para criar um novo usuário Linux chamado example.user e mapeá-lo para o usuário do SELinux staff_u:

    # useradd -Z staff_u example.user
  2. Para atribuir uma senha para o usuário do Linux example.user:

    passwd example.user
    Changing password for user example.user.
    New password:
    Retype new password:
    passwd: all authentication tokens updated successfully.
  3. Saia de sua sessão atual.
  4. Faça o login como usuário do Linux example.user. O shell do usuário lança com o contexto staff_u.

Etapas de verificação

  1. Quando conectado como usuário do example.user, verifique o contexto de um usuário Linux:

    $ id -Z
    uid=1000(example.user) gid=1000(example.user) groups=1000(example.user) context=staff_u:staff_r:staff_t:s0-s0:c0.c1023

Recursos adicionais

  • Para mais informações, consulte a página de manual pam_selinux(8).

3.5. Configurando o sistema para confinar os usuários do SELinux

Por default, todos os usuários Linux no Red Hat Enterprise Linux, incluindo usuários com privilégios administrativos, são mapeados para o usuário SELinux não-confinado unconfined_u. Você pode melhorar a segurança do sistema designando usuários para usuários confinados ao SELinux. Isto é útil para estar em conformidade com o Guia de Implementação Técnica de Segurança V-71971. Para mais informações sobre usuários confinados e não-confinados, consulte Gerenciando usuários confinados e não-confinados.

3.5.1. Confinamento de usuários regulares

Você pode confinar todos os usuários regulares em seu sistema, mapeando-os para o usuário do user_u SELinux.

Procedimento

  1. Exibir a lista de registros de login da SELinux. A lista exibe os mapeamentos dos usuários Linux para os usuários do SELinux:

    # semanage login -l
    
    Login Name    SELinux User  MLS/MCS Range   Service
    
    __default__   unconfined_u  s0-s0:c0.c1023       *
    root          unconfined_u  s0-s0:c0.c1023       *
  2. Mapear o usuário __default__, que representa todos os usuários sem um mapeamento explícito, para o usuário do user_u SELinux:

    # semanage login -m -s user_u -r s0 __default__

Etapas de verificação

  1. Verifique se o usuário __default__ está mapeado para o usuário do user_u SELinux:

    # semanage login -l
    
    Login Name    SELinux User   MLS/MCS Range    Service
    
    __default__   user_u         s0               *
    root          unconfined_u   s0-s0:c0.c1023   *
  2. Verificar se os processos de um novo usuário são executados no contexto do user_u:user_r:user_t:s0 SELinux.

    1. Criar um novo usuário:

      # adduser example.user
    2. Definir uma senha para example.user:

      # passwd example.user
    3. Sair como root e entrar como o novo usuário.
    4. Mostrar o contexto de segurança para a identificação do usuário:

      [example.user@localhost ~]$ id -Z
      user_u:user_r:user_t:s0
    5. Mostrar o contexto de segurança dos processos atuais do usuário:

      [example.user@localhost ~]$ ps axZ
      LABEL                           PID TTY      STAT   TIME COMMAND
      -                                 1 ?        Ss     0:05 /usr/lib/systemd/systemd --switched-root --system --deserialize 18
      -                              3729 ?        S      0:00 (sd-pam)
      user_u:user_r:user_t:s0        3907 ?        Ss     0:00 /usr/lib/systemd/systemd --user
      -                              3911 ?        S      0:00 (sd-pam)
      user_u:user_r:user_t:s0        3918 ?        S      0:00 sshd: example.user@pts/0
      user_u:user_r:user_t:s0        3922 pts/0    Ss     0:00 -bash
      user_u:user_r:user_dbusd_t:s0  3969 ?        Ssl    0:00 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
      user_u:user_r:user_t:s0        3971 pts/0    R+     0:00 ps axZ

3.5.2. Confinamento de usuários administradores

Você pode usar um dos dois métodos a seguir para confinar os usuários administradores.

3.5.2.1. Confinando um administrador através do mapeamento ao sysadm_u

Você pode confinar um usuário com privilégios administrativos mapeando o usuário diretamente para o usuário do sysadm_u SELinux. Quando o usuário faz o login, a sessão é executada no contexto sysadm_u:sysadm_r:sysadm_t SELinux.

Pré-requisitos

  • O usuário do site root funciona de forma não confinada. Este é o default do Red Hat Enterprise Linux.

Procedimento

  1. Opcional: Para permitir aos usuários do sysadm_u conectarem-se ao sistema usando SSH:

    # setsebool -P ssh_sysadm_login on
  2. Criar um novo usuário, adicionar o usuário ao grupo de usuários wheel e mapear o usuário para o usuário sysadm_u SELinux:

    # adduser -G wheel -Z sysadm_u example.user
  3. Opcional: Mapear um usuário existente para o usuário sysadm_u SELinux e adicionar o usuário ao grupo de usuários wheel:

    # usermod -G wheel -Z sysadm_u example.user

Etapas de verificação

  1. Verifique se example.user é mapeado para o usuário do sysadm_u SELinux:

    # semanage login -l | grep example.user
    example.user     sysadm_u    s0-s0:c0.c1023   *
  2. Entrar como example.userpor exemplo, usando SSH, e mostrar o contexto de segurança do usuário:

    [example.user@localhost ~]$ id -Z
    sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
  3. Mude para o usuário do site root:

    $ sudo -i
    [sudo] password for example.user:
  4. Verificar que o contexto de segurança permaneça inalterado:

    # id -Z
    sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
  5. Tente uma tarefa administrativa, por exemplo, reiniciar o serviço sshd:

    # systemctl restart sshd

    Se não houver saída, o comando terminou com sucesso.

    Se o comando não terminar com sucesso, ele imprime a seguinte mensagem:

    Failed to restart sshd.service: Access denied
    See system logs and 'systemctl status sshd.service' for details.

3.5.2.2. Confinar um administrador usando sudo e a função sysadm_r

Você pode mapear um usuário específico com privilégios administrativos para o usuário do staff_u SELinux, e configurar sudo para que o usuário possa ganhar o papel de administrador do sysadm_r SELinux. Esta função permite que o usuário execute tarefas administrativas sem que o SELinux negue. Quando o usuário faz login, a sessão é executada no contexto staff_u:staff_r:staff_t SELinux, mas quando o usuário entra em um comando utilizando sudo, a sessão muda para o contexto staff_u:sysadm_r:sysadm_t.

Pré-requisitos

  • O usuário do site root funciona de forma não confinada. Este é o default do Red Hat Enterprise Linux.

Procedimento

  1. Criar um novo usuário, adicionar o usuário ao grupo de usuários wheel e mapear o usuário para o usuário staff_u SELinux:

    # adduser -G wheel -Z staff_u example.user
  2. Opcional: Mapear um usuário existente para o usuário staff_u SELinux e adicionar o usuário ao grupo de usuários wheel:

    # usermod -G wheel -Z staff_u example.user
  3. Para permitir que example.user ganhe o papel de administrador do SELinux, crie um novo arquivo no diretório /etc/sudoers.d/, por exemplo:

    # visudo -f /etc/sudoers.d/example.user
  4. Adicione a seguinte linha ao novo arquivo:

    example.user ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r ALL

Etapas de verificação

  1. Verifique se example.user é mapeado para o usuário do staff_u SELinux:

    # semanage login -l | grep example.user
    example.user     staff_u    s0-s0:c0.c1023   *
  2. Faça o login como example.user, por exemplo, usando SSH, e mude para o usuário root:

    [example.user@localhost ~]$ sudo -i
    [sudo] password for example.user:
  3. Mostrar o contexto de segurança root:

    # id -Z
    staff_u:sysadm_r:sysadm_t:s0-s0:c0.c1023
  4. Tente uma tarefa administrativa, por exemplo, reiniciar o serviço sshd:

    # systemctl restart sshd

    Se não houver saída, o comando terminou com sucesso.

    Se o comando não terminar com sucesso, ele imprime a seguinte mensagem:

    Failed to restart sshd.service: Access denied
    See system logs and 'systemctl status sshd.service' for details.

3.5.3. Recursos adicionais

3.6. Recursos adicionais

  • Para mais informações, consulte a página de manual unconfined_selinux(8).

Capítulo 4. Configuração do SELinux para aplicações e serviços com configurações não padronizadas

Quando a SELinux está em modo de aplicação, a política padrão é a política direcionada. As seções seguintes fornecem informações sobre como configurar e configurar a política SELinux para vários serviços depois de alterar os padrões de configuração, tais como portas, localização de bancos de dados ou permissões de sistema de arquivos para processos.

Nos procedimentos seguintes, você aprende a mudar os tipos de SELinux para portas não padrão, a identificar e corrigir etiquetas incorretas para mudanças de diretórios padrão, e a ajustar a política usando booleans SELinux.

4.1. Personalizando a política SELinux para o servidor HTTP Apache em uma configuração não-padrão

Você pode configurar o servidor HTTP Apache para ouvir em uma porta diferente e fornecer conteúdo em um diretório não padrão. Para evitar negações conseqüentes do SELinux, siga os passos deste procedimento para ajustar a política SELinux de seu sistema.

Pré-requisitos

  • O pacote httpd está instalado e o servidor HTTP Apache está configurado para ouvir na porta TCP 3131 e para usar o diretório /var/test_www/ ao invés do diretório /var/www/ padrão.
  • Os pacotes policycoreutils-python-utils e setroubleshoot-server estão instalados em seu sistema.

Procedimento

  1. Inicie o serviço httpd e verifique o status:

    # systemctl start httpd
    # systemctl status httpd
    ...
    httpd[14523]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:3131
    ...
    systemd[1]: Failed to start The Apache HTTP Server.
    ...
  2. A política da SELinux assume que httpd funciona na porta 80:

    # semanage port -l | grep http
    http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
    http_cache_port_t              udp      3130
    http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
    pegasus_http_port_t            tcp      5988
    pegasus_https_port_t           tcp      5989
  3. Mude o tipo SELinux da porta 3131 para corresponder à porta 80:

    # semanage port -a -t http_port_t -p tcp 3131
  4. Comece httpd novamente:

    # systemctl start httpd
  5. No entanto, o conteúdo permanece inacessível:

    # wget localhost:3131/index.html
    ...
    HTTP request sent, awaiting response... 403 Forbidden
    ...

    Encontre o motivo com a ferramenta sealert:

    # sealert -l "*"
    ...
    SELinux is preventing httpd from getattr access on the file /var/test_www/html/index.html.
    ...
  6. Compare os tipos de SELinux para o padrão e o novo caminho usando a ferramenta matchpathcon:

    # matchpathcon /var/www/html /var/test_www/html
    /var/www/html       system_u:object_r:httpd_sys_content_t:s0
    /var/test_www/html  system_u:object_r:var_t:s0
  7. Mude o tipo SELinux do novo diretório de conteúdo /var/test_www/html/ para o tipo do diretório padrão /var/www/html:

    # semanage fcontext -a -e /var/www /var/test_www
  8. Reenquadre o diretório /var recursivamente:

    # restorecon -Rv /var/
    ...
    Relabeled /var/test_www/html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0
    Relabeled /var/test_www/html/index.html from unconfined_u:object_r:var_t:s0 to unconfined_u:object_r:httpd_sys_content_t:s0

Etapas de verificação

  1. Verifique se o serviço httpd está funcionando:

    # systemctl status httpd
    ...
    Active: active (running)
    ...
    systemd[1]: Started The Apache HTTP Server.
    httpd[14888]: Server configured, listening on: port 3131
    ...
  2. Verificar se o conteúdo fornecido pelo servidor HTTP Apache está acessível:

    # wget localhost:3131/index.html
    ...
    HTTP request sent, awaiting response... 200 OK
    Length: 0 [text/html]
    Saving to: ‘index.html’
    ...

Recursos adicionais

  • As páginas de manual semanage(8), matchpathcon(8), e sealert(8).

4.2. Ajustando a política de compartilhamento de volumes NFS e CIFS usando booleans SELinux

Você pode mudar partes da política SELinux em tempo de execução utilizando booleans, mesmo sem qualquer conhecimento da política da SELinux. Isto permite mudanças, tais como permitir o acesso de serviços a volumes NFS, sem recarregar ou recompilar a política SELinux. O procedimento seguinte demonstra a listagem de booleans SELinux e sua configuração para alcançar as mudanças necessárias na política.

As montagens NFS no lado do cliente são etiquetadas com um contexto padrão definido por uma política para volumes NFS. Na RHEL, este contexto padrão usa o tipo nfs_t. Além disso, as montagens de Samba no lado do cliente são etiquetadas com um contexto padrão definido pela política. Este contexto padrão usa o tipo cifs_t. Você pode habilitar ou desabilitar booleans para controlar quais serviços estão autorizados a acessar os tipos nfs_t e cifs_t.

Para permitir que o serviço servidor HTTP Apache (httpd) acesse e compartilhe volumes NFS e CIFS, execute os seguintes passos:

Pré-requisitos

  • Opcionalmente, instale o pacote selinux-policy-devel para obter descrições mais claras e detalhadas das booleanas SELinux na saída do comando semanage boolean -l.

Procedimento

  1. Identificar as booleanas SELinux relevantes para NFS, CIFS, e Apache:

    # semanage boolean -l | grep 'nfs\|cifs' | grep httpd
    httpd_use_cifs                 (off  ,  off)  Allow httpd to access cifs file systems
    httpd_use_nfs                  (off  ,  off)  Allow httpd to access nfs file systems
  2. Liste o estado atual das booleanas:

    $ getsebool -a | grep 'nfs\|cifs' | grep httpd
    httpd_use_cifs --> off
    httpd_use_nfs --> off
  3. Habilitar as booleanas identificadas:

    # setsebool httpd_use_nfs on
    # setsebool httpd_use_cifs on
    Nota

    Use setsebool com a opção -P para fazer com que as mudanças sejam persistentes em todas as reinicializações. Um comando setsebool -P requer uma reconstrução de toda a política, e pode levar algum tempo, dependendo de sua configuração.

Etapas de verificação

  1. Verifique se as booleans estão em on:

    $ getsebool -a | grep 'nfs\|cifs' | grep httpd
    httpd_use_cifs --> on
    httpd_use_nfs --> on

Recursos adicionais

  • As páginas semanage-boolean(8), sepolicy-booleans(8), getsebool(8), setsebool(8), booleans(5), e booleans(8) man pages.

4.3. Recursos adicionais

Capítulo 6. Usando a Segurança Multinível (MLS)

A política de Segurança Multinível (MLS) usa levels de liberação como originalmente projetado pela comunidade de defesa dos EUA. A MLS atende a um conjunto muito restrito de requisitos de segurança baseados na forma como as informações são gerenciadas em ambientes rigidamente controlados, tais como os militares.

O MLS é difícil de trabalhar e não mapeia bem os cenários gerais de caso.

6.1. Segurança multinível (MLS)

A tecnologia de segurança multinível (MLS) classifica os dados usando os níveis de segurança da informação:

  • [mais alto] Ultra secreto
  • [alto] Segredo
  • [baixo] Confidencial
  • [mais baixo] Não classificado

As regras que se aplicam ao fluxo de dados operam de níveis mais baixos para níveis mais altos, e nunca o contrário.

A MLS chama processos como subjects, e arquivos, dispositivos e outros componentes passivos do sistema como objects. Tanto os sujeitos quanto os objetos são rotulados com um nível de segurança, o que implica na liberação de um sujeito ou na classificação de um objeto.

A SELinux utiliza o modelo Bell-La Padula Model (BLP). Este modelo especifica como a informação pode fluir dentro do sistema com base em etiquetas fixadas a cada assunto e objeto. No BLP, os processos podem ler o mesmo nível de segurança ou níveis de segurança mais baixos, mas só podem escrever para o mesmo nível de segurança ou para um nível de segurança mais alto.

O sistema sempre combina as regras de acesso MLS com permissões de acesso convencionais (permissões de arquivo). Por exemplo, se um usuário com um nível de segurança de "Secret" usa o Controle de Acesso Discricionário (DAC) para bloquear o acesso a um arquivo por outros usuários, isto também bloqueia o acesso por usuários com um nível de segurança de "Top Secret". Uma autorização de segurança maior não permite automaticamente a navegação arbitrária em um sistema de arquivos.

Os usuários com autorizações de nível superior não adquirem automaticamente direitos administrativos em sistemas multiníveis. Embora eles possam ter acesso a todas as informações no computador, isto é diferente de ter direitos administrativos.

6.2. Mudando a política SELinux para MLS

Use os seguintes passos para mudar a política SELinux de segurança direcionada para segurança multinível (MLS).

Importante

A Red Hat não recomenda o uso da política MLS em um sistema que esteja rodando o Sistema X Window. Além disso, quando você reetique o sistema de arquivos com rótulos MLS, o sistema pode impedir o acesso de domínios confinados, o que impede seu sistema de iniciar corretamente. Portanto, certifique-se de mudar o SELinux para o modo permissivo antes de re-etiquetar os arquivos. Na maioria dos sistemas, você vê muitas negações de SELinux após mudar para MLS, e muitas delas não são triviais de serem corrigidas.

Procedimento

  1. Instale o pacote selinux-policy-mls:

    # yum install selinux-policy-mls
  2. Abra o arquivo /etc/selinux/config em um editor de texto de sua escolha, por exemplo:

    # vi /etc/selinux/config
  3. Mudar o modo SELinux de aplicação para permissivo e mudar da política de destino para MLS:

    SELINUX=permissive
    SELINUXTYPE=mls

    Salve as mudanças, e deixe o editor.

  4. Antes de ativar a política MLS, você deve reetique cada arquivo no sistema de arquivos com uma etiqueta MLS:

    # fixfiles -F onboot
    System will relabel on next boot
  5. Reinicie o sistema:

    # reboot
  6. Verifique se a SELinux negou:

    # ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent -i

    Como o comando anterior não cobre todos os cenários, veja Solução de problemas relacionados ao SELinux para orientação na identificação, análise e correção de recusas do SELinux.

  7. Depois de garantir que não haja problemas relacionados ao SELinux em seu sistema, mude o SELinux de volta para o modo de aplicação, alterando a opção correspondente em /etc/selinux/config:

    SELINUX=forçando
  8. Reinicie o sistema:

    # reboot
Importante

Se seu sistema não iniciar ou você não for capaz de fazer login depois de mudar para o MLS, adicione o parâmetro enforcing=0 à sua linha de comando do kernel. Veja Mudando os modos SELinux no momento da inicialização para mais informações.

Observe também que no MLS, os logins SSH como o usuário root mapeado para o papel de sysadm_r SELinux diferem do log in como root em staff_r. Antes de iniciar seu sistema no MLS pela primeira vez, considere permitir logins SSH como sysadm_r, configurando o booleano ssh_sysadm_login SELinux para 1. Para habilitar ssh_sysadm_login mais tarde, já no MLS, você deve entrar como root em staff_r, mudar para root em sysadm_r usando o comando newrole -r sysadm_r, e então definir o booleano para 1.

Etapas de verificação

  1. Verificar se a SELinux funciona em modo de aplicação:

    # getenforce
    Enforcing
  2. Verifique se o status da SELinux retorna o valor mls:

    # sestatus | grep mls
    Loaded policy name:             mls

Recursos adicionais

  • As páginas de manual fixfiles(8), setsebool(8), e ssh_selinux(8).

Capítulo 7. Escrevendo uma política SELinux personalizada

Esta seção lhe orienta sobre como escrever e utilizar uma política personalizada que lhe permite executar suas aplicações confinadas pela SELinux.

7.2. Criação e aplicação de uma política SELinux para uma aplicação personalizada

Este procedimento de exemplo fornece passos para confinar um simples daemon pela SELinux. Substitua o daemon por seu aplicativo personalizado e modifique a regra de exemplo de acordo com as exigências daquele aplicativo e sua política de segurança.

Pré-requisitos

  • O pacote policycoreutils-devel e suas dependências estão instalados em seu sistema.

Procedimento

  1. Para este procedimento de exemplo, prepare um daemon simples que abra o arquivo /var/log/messages para escrita:

    1. Crie um novo arquivo e abra-o em um editor de texto de sua escolha:

      $ vi mydaemon.c
    2. Insira o seguinte código:

      #include <unistd.h>
      #include <stdio.h>
      
      FILE *f;
      
      int main(void)
      {
      while(1) {
      f = fopen("/var/log/messages","w");
              sleep(5);
              fclose(f);
          }
      }
    3. Compilar o arquivo:

      $ gcc -o mydaemon mydaemon.c
    4. Crie um arquivo de unidade systemd para seu daemon:

      $ vi mydaemon.service
      [Unit]
      Description=Simple testing daemon
      
      [Service]
      Type=simple
      ExecStart=/usr/local/bin/mydaemon
      
      [Install]
      WantedBy=multi-user.target
    5. Instale e inicie o daemon:

      # cp mydaemon /usr/local/bin/
      # cp mydaemon.service /usr/lib/systemd/system
      # systemctl start mydaemon
      # systemctl status mydaemon
      ● mydaemon.service - Simple testing daemon
         Loaded: loaded (/usr/lib/systemd/system/mydaemon.service; disabled; vendor preset: disabled)
         Active: active (running) since Sat 2020-05-23 16:56:01 CEST; 19s ago
       Main PID: 4117 (mydaemon)
          Tasks: 1
         Memory: 148.0K
         CGroup: /system.slice/mydaemon.service
                 └─4117 /usr/local/bin/mydaemon
      
      May 23 16:56:01 localhost.localdomain systemd[1]: Started Simple testing daemon.
    6. Verifique se o novo daemon não está confinado pela SELinux:

      $ ps -efZ | grep mydaemon
      system_u:system_r:unconfined_service_t:s0 root 4117    1  0 16:56 ?        00:00:00 /usr/local/bin/mydaemon
  2. Gerar uma política personalizada para o daemon:

    $ sepolicy generate --init /usr/local/bin/mydaemon
    Created the following files:
    /home/example.user/mysepol/mydaemon.te # Type Enforcement file
    /home/example.user/mysepol/mydaemon.if # Interface file
    /home/example.user/mysepol/mydaemon.fc # File Contexts file
    /home/example.user/mysepol/mydaemon_selinux.spec # Spec file
    /home/example.user/mysepol/mydaemon.sh # Setup Script
  3. Reconstruir a política do sistema com o novo módulo de política usando o script de configuração criado pelo comando anterior:

    # ./mydaemon.sh
    Building and Loading Policy
    + make -f /usr/share/selinux/devel/Makefile mydaemon.pp
    Compiling targeted mydaemon module
    Creating targeted mydaemon.pp policy package
    rm tmp/mydaemon.mod.fc tmp/mydaemon.mod
    + /usr/sbin/semodule -i mydaemon.pp
    ...

    Observe que o script de configuração reescreve a parte correspondente do sistema de arquivos usando o comando restorecon:

    restorecon -v /usr/local/bin/mydaemon /usr/lib/systemd/systemd
  4. Reinicie o daemon, e verifique se ele agora funciona confinado pela SELinux:

    # systemctl restart mydaemon
    $ ps -efZ | grep mydaemon
    system_u:system_r:mydaemon_t:s0 root        8150       1  0 17:18 ?        00:00:00 /usr/local/bin/mydaemon
  5. Como o daemon agora está confinado pela SELinux, a SELinux também o impede de acessar /var/log/messages. Exibir a mensagem de negação correspondente:

    # ausearch -m AVC -ts recent
    ...
    type=AVC msg=audit(1590247112.719:5935): avc:  denied  { open } for  pid=8150 comm="mydaemon" path="/var/log/messages" dev="dm-0" ino=2430831 scontext=system_u:system_r:mydaemon_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1
    ...
  6. Você pode obter informações adicionais também usando a ferramenta sealert:

    $ sealert
    SELinux is preventing mydaemon from open access on the file /var/log/messages.
    
     Plugin catchall (100. confidence) suggests *
    
    If you believe that mydaemon should be allowed open access on the messages file by default.
    Then you should report this as a bug.
    You can generate a local policy module to allow this access.
    Do
    allow this access for now by executing:
    # ausearch -c 'mydaemon' --raw | audit2allow -M my-mydaemon
    # semodule -X 300 -i my-mydaemon.pp
    
    Additional Information:
    Source Context                system_u:system_r:mydaemon_t:s0
    Target Context                unconfined_u:object_r:var_log_t:s0
    Target Objects                /var/log/messages [ file ]
    Source                        mydaemon
    
    ...
  7. Use a ferramenta audit2allow para sugerir mudanças:

    $ ausearch -m AVC -ts recent | audit2allow -R
    
    require {
    	type mydaemon_t;
    }
    
    #============= mydaemon_t ==============
    logging_write_generic_logs(mydaemon_t)
  8. Como as regras sugeridas por audit2allow podem ser incorretas para certos casos, use apenas uma parte de sua produção para encontrar a interface política correspondente:

    $ grep -r "logging_write_generic_logs" /usr/share/selinux/devel/include/ | grep .if
    /usr/share/selinux/devel/include/system/logging.if:interface(logging_write_generic_logs',
  9. Verifique a definição da interface:

    $ cat /usr/share/selinux/devel/include/system/logging.if
    ...
    interface(logging_write_generic_logs',
            gen_require(`
                    type var_log_t;
            ')
    
            files_search_var($1)
            allow $1 var_log_t:dir list_dir_perms;
            write_files_pattern($1, var_log_t, var_log_t)
    ')
    ...
  10. Neste caso, você pode usar a interface sugerida. Adicione a regra correspondente ao seu tipo de arquivo de aplicação da lei:

    $ echo "logging_write_generic_logs(mydaemon_t)" >> mydaemon.te

    Alternativamente, você pode adicionar esta regra em vez de usar a interface:

    $ echo "allow mydaemon_t var_log_t:file { open write getattr };" >> mydaemon.te
  11. Reinstalar a política:

    # ./mydaemon.sh
    Building and Loading Policy
    + make -f /usr/share/selinux/devel/Makefile mydaemon.pp
    Compiling targeted mydaemon module
    Creating targeted mydaemon.pp policy package
    rm tmp/mydaemon.mod.fc tmp/mydaemon.mod
    + /usr/sbin/semodule -i mydaemon.pp
    ...

Etapas de verificação

  1. Verifique se sua aplicação funciona confinada pela SELinux, por exemplo:

    $ ps -efZ | grep mydaemon
    system_u:system_r:mydaemon_t:s0 root        8150       1  0 17:18 ?        00:00:00 /usr/local/bin/mydaemon
  2. Verifique se sua aplicação personalizada não causa nenhuma negação da SELinux:

    # ausearch -m AVC -ts recent
    <no matches>

Recursos adicionais

  • Para mais informações, consulte as páginas de manual sepolgen(8), ausearch(8), audit2allow(1), audit2why(1), sealert(8), e restorecon(8).

7.3. Recursos adicionais

Capítulo 8. Criação de políticas SELinux para contêineres

A RHEL 8 fornece uma ferramenta para gerar políticas SELinux para recipientes utilizando o pacote udica. Com udica, você pode criar uma política de segurança sob medida para melhor controle de como um contêiner acessa os recursos do sistema host, tais como armazenamento, dispositivos e rede. Isto permite que você endureça suas implementações de contêineres contra violações de segurança e também simplifica a obtenção e manutenção da conformidade regulamentar.

8.1. Introdução ao gerador de políticas da udica SELinux

Para simplificar a criação de novas políticas SELinux para recipientes personalizados, a RHEL 8 fornece o utilitário udica. Você pode usar esta ferramenta para criar uma política baseada em uma inspeção do arquivo JavaScript Object Notation (JSON) do contêiner, que contém capacidades Linux, pontos de montagem e definições de portas. Consequentemente, a ferramenta combina regras geradas usando os resultados da inspeção com regras herdadas de um bloco específico de Linguagem Intermediária Comum (CIL) SELinux.

O processo de geração da política SELinux para um contêiner utilizando udica tem três partes principais:

  1. Analisando o arquivo de especificação do recipiente no formato JSON
  2. Encontrar regras de permissão adequadas com base nos resultados da primeira parte
  3. Gerando a política final da SELinux

Durante a fase de análise, udica procura por capacidades Linux, portas de rede e pontos de montagem.

Com base nos resultados, udica detecta quais capacidades Linux são requeridas pelo contêiner e cria uma regra SELinux que permite todas essas capacidades. Se o contêiner se liga a uma porta específica, udica utiliza bibliotecas de espaço de usuário SELinux para obter a etiqueta SELinux correta de uma porta que é utilizada pelo contêiner inspecionado.

Posteriormente, udica detecta quais diretórios são montados no espaço de nome do sistema de arquivos do contêiner a partir do host.

O recurso de herança em bloco da CIL permite que udica crie modelos da SELinux allow rules com foco em uma ação específica, por exemplo:

  • allow accessing home directories
  • allow accessing log files
  • allow accessing communication with Xserver.

Estes modelos são chamados de blocos e a política final da SELinux é criada através da fusão dos blocos.

Recursos adicionais

8.2. Criação e utilização de uma política SELinux para um contêiner personalizado

Para gerar uma política de segurança SELinux para um contêiner personalizado, siga as etapas deste procedimento.

Pré-requisitos

  • A ferramenta podman para o gerenciamento de containers está instalada. Caso não esteja, use o comando yum install podman.
  • Um recipiente Linux personalizado - ubi8 neste exemplo.

Procedimento

  1. Instale o pacote udica:

    # yum install -y udica

    Alternativamente, instale o módulo container-tools, que fornece um conjunto de pacotes de software de contêineres, incluindo udica:

    # yum module install -y container-tools
  2. Inicie o recipiente ubi8 que monta o diretório /home com permissões de leitura e o diretório /var/spool com permissões de leitura e escrita. O contêiner expõe o porto 21.

    # podman run --env container=podman -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash

    Note que agora o contêiner funciona com o tipo container_t SELinux. Este tipo é um domínio genérico para todos os contêineres da política SELinux e pode ser muito rígido ou muito frouxo para seu cenário.

  3. Digite o comando podman ps para obter a identificação do recipiente:

    # podman ps
    CONTAINER ID   IMAGE                                   COMMAND   CREATED          STATUS              PORTS   NAMES
    37a3635afb8f   registry.access.redhat.com/ubi8:latest  bash      15 minutes ago   Up 15 minutes ago           heuristic_lewin
  4. Criar um arquivo JSON de contêineres e usar udica para criar um módulo de política com base nas informações do arquivo JSON:

    # podman inspect 37a3635afb8f > container.json
    # udica -j container.json my_container
    Policy my_container with container id 37a3635afb8f created!
    [...]

    Alternativamente:

    # podman inspect 37a3635afb8f | udica my_container
    Policy my_container with container id 37a3635afb8f created!
    
    Please load these modules using:
    # semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}
    
    Restart the container with: "--security-opt label=type:my_container.process" parameter
  5. Como sugerido pela saída de udica no passo anterior, carregue o módulo de política:

    # semodule -i my_container.cil /usr/share/udica/templates/{base_container.cil,net_container.cil,home_container.cil}
  6. Pare o recipiente e inicie-o novamente com a opção --security-opt label=type:my_container.process:

    # podman stop 37a3635afb8f
    # podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash

Etapas de verificação

  1. Verifique se o contêiner funciona com o tipo my_container.process:

    # ps -efZ | grep my_container.process
    unconfined_u:system_r:container_runtime_t:s0-s0:c0.c1023 root 2275 434  1 13:49 pts/1 00:00:00 podman run --security-opt label=type:my_container.process -v /home:/home:ro -v /var/spool:/var/spool:rw -p 21:21 -it ubi8 bash
    system_u:system_r:my_container.process:s0:c270,c963 root 2317 2305  0 13:49 pts/0 00:00:00 bash
  2. Verifique se a SELinux agora permite o acesso aos pontos de montagem /home e /var/spool:

    [root@37a3635afb8f /]# cd /home
    [root@37a3635afb8f home]# ls
    username
    [root@37a3635afb8f ~]# cd /var/spool/
    [root@37a3635afb8f spool]# touch test
    [root@37a3635afb8f spool]#
  3. Verifique se a SELinux permite a ligação somente à porta 21:

    [root@37a3635afb8f /]# yum install nmap-ncat
    [root@37a3635afb8f /]# nc -lvp 21
    Ncat: Version 7.60 ( https://nmap.org/ncat )
    Ncat: Generating a temporary 1024-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.
    Ncat: SHA-1 fingerprint: 6EEC 102E 6666 5F96 CC4F E5FA A1BE 4A5E 6C76 B6DC
    Ncat: Listening on :::21
    Ncat: Listening on 0.0.0.0:21
    
    [root@37a3635afb8f /]# nc -lvp 80
    Ncat: Version 7.60 ( https://nmap.org/ncat )
    Ncat: Generating a temporary 1024-bit RSA key. Use --ssl-key and --ssl-cert to use a permanent one.
    Ncat: SHA-1 fingerprint: 6EEC 102E 6666 5F96 CC4F E5FA A1BE 4A5E 6C76 B6DC
    Ncat: bind to :::80: Permission denied. QUITTING.

Recursos adicionais

  • Para mais informações, consulte as páginas de manual udica(8) e podman(1).
  • Para orientação sobre como começar com recipientes no RHEL e como trabalhar com imagens de recipientes, consulte o documento Building, running, and managing containers.

8.3. Recursos adicionais

Capítulo 9. Implantando a mesma configuração SELinux em vários sistemas

Esta seção fornece duas maneiras recomendadas para implantar sua configuração SELinux verificada em múltiplos sistemas:

  • Usando os papéis e as possibilidades do sistema RHEL
  • Usando semanage comandos de exportação e importação em seus scripts

9.1. Introdução ao papel do sistema SELinux

As funções do sistema RHEL são uma coleção de funções e módulos possíveis que fornecem uma interface de configuração consistente para gerenciar remotamente vários sistemas RHEL. A função do sistema SELinux permite as seguintes ações:

  • Limpeza de modificações políticas locais relacionadas a booleanos SELinux, contextos de arquivos, portas e logins.
  • Configurando a política SELinux booleans, contextos de arquivos, portas e logins.
  • Restauração de contextos de arquivos em arquivos ou diretórios especificados.

A tabela a seguir fornece uma visão geral das variáveis de entrada disponíveis na função do sistema SELinux.

Tabela 9.1. Variáveis de função do sistema SELinux

Função variávelDescriçãoAlternativa CLI

selinux_policy

Escolhe uma política de proteção de processos direcionados ou proteção de segurança multinível.

SELINUXTYPE em /etc/selinux/config

selinux_state

Troca os modos SELinux. Ver ansible-doc selinux

setenforce e SELINUX em /etc/selinux/config.

selinux_booleans

Habilita e desabilita as booleanas SELinux. Ver ansible-doc seboolean.

setsebool

selinux_fcontexts

Adiciona ou remove um mapeamento de contexto de arquivo SELinux. Ver ansible-doc sefcontext.

semanage fcontext

selinux_restore_dirs

Restaura as etiquetas SELinux na árvore do sistema de arquivos.

restorecon -R

selinux_ports

Define as etiquetas SELinux nos portos. Ver ansible-doc seport.

semanage port

selinux_logins

Define os usuários para o mapeamento de usuários SELinux. Ver ansible-doc selogin.

semanage login

O exemplo de playbook /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml, instalado pelo pacote rhel-system-roles, demonstra como definir a política direcionada no modo de aplicação. O playbook também aplica várias modificações de políticas locais e restaura contextos de arquivos no diretório /tmp/test_dir/.

Recursos adicionais

  • Para uma referência detalhada sobre as variáveis de função do SELinux, instale o pacote rhel-system-roles, e veja os arquivos README.md ou README.html no diretório /usr/share/doc/rhel-system-roles/selinux/.
  • Para mais informações sobre os papéis do Sistema RHEL, veja Introdução aos papéis do Sistema RHEL

9.2. Usando a função do sistema SELinux para aplicar as configurações do SELinux em vários sistemas

Siga os passos para preparar e aplicar um livro de exercícios possível com suas configurações SELinux verificadas.

Pré-requisitos

Procedimento

  1. Habilite o repositório RHEL Ansible, por exemplo:

    # subscription-manager repos --enable ansible-2-for-rhel-8-x86_64-rpms
  2. Instalar Motor Possível:

    # yum install ansible
  3. Instalar as funções do sistema RHEL:

    # yum install rhel-system-roles
  4. Aplique seu playbook com um papel no sistema SELinux.

    O seguinte comando aplica um exemplo de playbook, que faz parte do pacote rhel-system-roles. Você pode usar este playbook como um modelo:

    # ansible-playbook -i host1,host2,host3 /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml

Recursos adicionais

  • Para mais informações, instale o pacote rhel-system-roles, e consulte os diretórios /usr/share/doc/rhel-system-roles/selinux/ e /usr/share/ansible/roles/rhel-system-roles.selinux/.

9.3. Transferência de configurações SELinux para outro sistema com semanagem

Use os seguintes passos para transferir suas configurações SELinux personalizadas e verificadas entre os sistemas baseados no RHEL 8.

Pré-requisitos

  • O pacote policycoreutils-python-utils está instalado em seu sistema.

Procedimento

  1. Exporte suas configurações SELinux verificadas:

    # semanage export -f ./my-selinux-settings.mod
  2. Copie o arquivo com as configurações para o novo sistema:

    # scp ./my-selinux-settings.mod new-system-hostname:
  3. Faça o login no novo sistema:

    $ ssh root@new-system-hostname
  4. Importar as configurações no novo sistema:

    new-system-hostname# semanage import -f ./my-selinux-settings.mod

Recursos adicionais

  • semanage-export(8) e semanage-import(8) páginas man