Ir para o conteúdoIr para navegação de página: página anterior [tecla de acesso p]/próxima página [tecla de acesso n]
documentation.suse.com / Solucionando problemas do SELinux

Solucionando problemas do SELinux

Data de Publicação: 12/12/2024
O QUE É?

Um sistema com o SELinux no modo enforcing pode causar negações de acesso que podem impedir que os aplicativos sejam executados corretamente. Você pode usar audit2allow ou setroubleshoot para analisar as mensagens de negação de uma forma amigável.

POR QUÊ?

Este artigo apresenta instruções sobre como resolver negações de acesso causadas pelo SELinux sem reduzir a segurança do seu sistema.

DEDICAÇÃO

A leitura do artigo leva aproximadamente 30 minutos.

META

Você poderá usar uma das ferramentas descritas a seguir para depurar negações do SELinux.

REQUISITOS
  • Um sistema em execução com o SELinux habilitado.

1 O arquivo /var/log/audit/audit.log

Por padrão, se o SELinux causar o não funcionamento de qualquer componente, uma mensagem de registro a esse respeito será enviada para o arquivo /var/log/audit/audit.log.

Nota
Nota: /var/log/audit/audit.log vazio

Se o /var/log/audit/audit.log estiver vazio, isso geralmente significa que o serviço auditd não está em execução. Nesse caso, faça o seguinte:

  1. Inicie o serviço auditd:

    > sudo systemctl start auditd
  2. Habilite o serviço nos destinos do seu sistema, usando:

    > sudo systemctl enable auditd

O arquivo /var/log/audit/audit.log armazena mensagens de negações de acesso, eventos de serviço e assim por diante.

No Exemplo 1: “Exemplo de linhas do /etc/audit/audit.log, você pode ver um exemplo parcial do conteúdo do /var/log/audit/audit.log.

Exemplo 1: Exemplo de linhas do /etc/audit/audit.log
type=DAEMON_START msg=audit(1348173810.874:6248): auditd start, ver=1.7.7 format=raw kernel=3.0.13-0.27-default auid=0 pid=4235 subj=system_u:system_r:auditd_t res=success
type=AVC msg=audit(1348173901.081:292): avc:  denied  { write } for  pid=3426 comm="smartd" name="smartmontools" dev=sda6 ino=581743 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:293): avc:  denied  { remove_name } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:294): avc:  denied  { unlink } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:295): avc:  denied  { rename } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582373 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:296): avc:  denied  { add_name } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state~" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=dir
type=AVC msg=audit(1348173901.081:297): avc:  denied  { create } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:298): avc:  denied  { write open } for  pid=3426 comm="smartd" name="smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.081:299): avc:  denied  { getattr } for  pid=3426 comm="smartd" path="/var/lib/smartmontools/smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file
type=AVC msg=audit(1348173901.309:300): avc:  denied  { append } for  pid=1316

Uma única mensagem tem a seguinte aparência:

type=AVC msg=audit(1348173901.081:299): avc:  denied  { getattr } for  pid=3426 comm="smartd" path="/var/lib/smartmontools/smartd.WDC_WD2500BEKT_75PVMT0-WD_WXC1A21E0454.ata.state" dev=sda6 ino=582390 scontext=system_u:system_r:fsdaemon_t tcontext=system_u:object_r:var_lib_t tclass=file

Cada linha da mensagem pode ser dividida em seções. Por exemplo, as seções na última linha são:

type=AVC:

Todas as linhas do registro de auditoria relacionado ao SELinux começam com a identificação de tipo, por exemplo, type=AVC. Observe que uma mensagem com type=SYSCALL que vem depois de uma com um tipo diferente e que tem o mesmo valor de msg pode fornecer mais informações sobre o evento.

msg=audit(1348173901.309:300):

Trata-se da marcação de horário, que é gravada em horário de época, com o número de segundos decorridos desde 1º de janeiro de 1970. Você pode usar date -d na parte até o ponto na notação de horário de época para descobrir quando o evento ocorreu:

> date -d @1348173901
Thu Sep 20 16:45:01 EDT 2012
avc: denied { append }:

A ação específica que foi negada. Nesse caso, o sistema negou a anexação de dados a um arquivo. Ao navegar pelo arquivo de registro de auditoria, você pode ver outras ações do sistema, como write open, getattr etc.

for pid=1316:

o ID do processo do comando ou processo que iniciou a ação

comm="rsyslogd":

o comando específico associado a esse PID

name="smartmontools":

o nome do assunto da ação

dev=sda6 ino=582296:

o dispositivo de blocos e o número de inode do arquivo envolvido

scontext=system_u:system_r:syslogd_t:

o contexto de origem, que é o contexto do iniciador da ação

tclass=file:

uma identificação de classe do assunto

2 Analisando /var/log/audit/audit.log com audit2allow

Em vez de você mesmo interpretar os eventos em /var/log/audit/audit.log, é possível usar o comando audit2allow.

O comando ajuda a analisar as mensagens de registro criptografadas em /var/log/audit/audit.log. Uma sessão de solução de problemas do audit2allow sempre consiste em três comandos diferentes. Primeiro, você usa audit2allow -w -a para apresentar as informações de auditoria de uma forma mais legível. Por padrão, o audit2allow -w -a funciona no arquivo audit.log. Para analisar uma mensagem específica no arquivo audit.log, copie-a para um arquivo temporário e analise o arquivo com:

> sudo audit2allow -w -i FILENAME
Exemplo 2: Analisando mensagens de auditoria
> sudoaudit2allow -w -i testfile
type=AVC msg=audit(1348173901.309:300): avc:  denied  { append } for  pid=1316
comm="rsyslogd" name="acpid" dev=sda6 ino=582296
scontext=system_u:system_r:syslogd_t tcontext=system_u:object_r:apmd_log_t tclass=file
Isso foi causado por:

Uma regra de permissão de imposição de tipo (TE, Type Enforcement) ausente.

Para gerar um módulo carregável que permita esse acesso, execute:

> sudo audit2allow

Para descobrir qual regra específica negou o acesso, você pode usar audit2allow -a para mostrar as regras de imposição de todos os eventos que foram registrados no arquivo audit.log ou audit2allow -i FILENAME para mostrar a regra para as mensagens que você armazenou em um arquivo específico:

Exemplo 3: Visualizando quais linhas negam acesso
> sudoaudit2allow -i testfile
#============= syslogd_t ==============
allow syslogd_t apmd_log_t:file append;

Para criar um módulo do SELinux chamado mymodule que você pode carregar para permitir o acesso que foi negado anteriormente, execute:

> sudo audit2allow -a -R -M mymodule

Para fazer isso para todos os eventos que foram registrados no arquivo audit.log, use os argumentos de comando -a -M. Para fazer isso apenas para as mensagens específicas que estão em um determinado arquivo, use -i -M como no exemplo abaixo:

Exemplo 4: Criando um módulo de política que permite uma ação negada anteriormente
> sudoaudit2allow -i testfile -M example
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i example.pp

Conforme indicado pelo comando audit2allow, agora você pode executar esse módulo usando o comando semodule -i, seguido do nome do módulo que o comando audit2allow criou para você (no exemplo acima, example.pp).

3 Analisando mensagens do AVC com setroubleshoot

Para analisar as mensagens de negação do AVC de uma forma amigável, você pode usar a ferramenta setroubleshoot.

3.1 Visão geral do setroubleshoot

3.1.1 O que é o comando setroubleshoot?

setroubleshoot é uma ferramenta que coleta eventos de auditoria do SELinux do kernel e os analisa. Se esse tipo de evento ocorrer, o setroubleshoot informa o administrador.

3.1.2 Componentes do setroubleshoot

O processo de solução de problemas do SELinux envolve os componentes a seguir, todos instalados no SLE Micro por padrão.

  • O setroubleshoot-server oferece as seguintes ferramentas:

    • setroubleshootd: o daemon principal que processa as solicitações recebidas e as definições de plug-in. O daemon é ativado sob demanda e não requer execução por meio do serviço systemd. Ele pode ser gerenciado apenas por um usuário com privilégios e um usuário setroubleshoot dedicado.

    • um banco de dados de alertas no arquivo /var/lib/setroubleshoot/setroubleshoot_database.xml.

    • sealert: uma interface do usuário de linha de comando para analisar o /var/log/audit.log.

    • sedispatch: um dispatcher de auditoria que verifica as mensagens do AVC do SELinux e as transforma em uma mensagem DBus, que depois é enviada ao daemon.

  • setroubleshoot-plugins: os plug-ins são usados para análise de mensagens do AVC e fornecem sugestões sobre como corrigir problemas.

3.1.3 Como funciona o setroubleshoot?

O setroubleshoot inclui um daemon e plug-ins de análise. Quando um plug-in detecta um problema, ele é relatado ao daemon, que verifica se esse é um problema conhecido. Se não for, o novo problema será adicionado ao banco de dados junto com uma solução sugerida.

3.1.4 Benefícios do setroubleshoot

O setroubleshoot oferece as seguintes funcionalidades para ajudar você a resolver problemas em seus sistemas protegidos pelo SELinux:

  • Enviar alertas ao administrador quando há uma negação do AVC.

  • Análise automática de negações do AVC.

  • Sugerir possíveis correções, como ajustar a configuração do sistema ou instalar atualizações, entre outras.

  • Procurar alertas anteriores.

3.2 Configurando setroubleshoot

Mesmo que a configuração do setroubleshoot não exija ajuste, talvez você encontre casos de uso específicos em que seja necessário mudar os padrões. As seções a seguir apresentam os casos de uso comuns.

O arquivo de configuração para setroubleshoot é /etc/setroubleshoot. Normalmente, você não precisa modificar a configuração além de definir as notificações por e-mail. No entanto, se você precisar mudar a configuração, poderá editar o arquivo ou usar o comando setroubleshootd para configurar um item específico. A sintaxe do comando é a seguinte:

# setroubleshootd -c
SECTION.OPTION=VALUE

Por exemplo, para definir a opção from_address, execute o comando da seguinte maneira:

# setroubleshootd -c
email.from_address="example@mail.com"

3.2.1 Configurando o nível de registro de setroubleshoot

O nível de registro padrão (o valor de sealert_log e setroubleshootd_log) é definido como warning. No entanto, você pode definir o valor como um dos seguintes:

crítico

Somente erros graves que impedem o funcionamento do sistema são registrados.

erro

Erros graves que podem influenciar o sistema são relatados.

aviso

Uma indicação de que algo inesperado aconteceu ou que um problema poderá ocorrer em um futuro próximo. No entanto, o sistema funciona conforme o esperado.

info

Uma confirmação de que o sistema está sendo executado corretamente é registrada.

depurar

Informações detalhadas para fins de depuração são registradas.

3.2.2 Configurando o setroubleshoot para enviar notificações por e-mail

O setroubleshoot poderá enviar notificações por e-mail se houver uma negação do AVC no sistema.

Para obter essas notificações, faça o seguinte:

  1. Abra a pasta /etc/setroubleshoot/setroubleshoot.conf.

  2. No arquivo, ajuste os seguintes itens de configuração de acordo com as suas necessidades:

    smtp_host

    Se o servidor SMTP não for executado no host local, preencha o endereço do servidor.

    smtp_port

    O padrão é 25. Normalmente, esse valor não requer nenhum ajuste.

    from_address

    Adicione o endereço do remetente.

    assunto

    Configure um assunto genérico de todas as mensagens.

    recipients_filepath

    Especifique o local da lista de destinatários da notificação.

    use_sendmail

    Defina como true se você usa SendMail.

  3. Crie o arquivo de destinatários de e-mail no caminho definido pela opção recipients_filepath (por padrão, /var/lib/setroubleshoot/email_alerts-recipients).

    Cada endereço de e-mail deve ser separado por uma linha separada. Os comentários são indicados com o símbolo #.

3.2.3 Configurando o banco de dados de setroubleshoot

Você pode mudar a quantidade de registros no banco de dados de setroubleshootd, sua localização ou o prefixo do nome de arquivo.

database_dir

Especifique um caminho absoluto para o diretório em que o arquivo XML do banco de dados deve residir.

filename

Configure um prefixo personalizado do nome do arquivo de banco de dados. O nome de arquivo terá esta aparência: FILENAME_PREFIX_database.xml.

max_alerts

Define o número máximo de registros no banco de dados. Especifique 0 para um número ilimitado de registros.

max_alert_age

Os alertas mais antigos do que o limite definido serão apagados do banco de dados. Você pode usar as unidades: ano, mês, dia, hora, minuto e segundo, mesmo no plural, e usar mais de uma unidade, por exemplo, 3 weeks 2 days, que é igual a 23 dias. Se ficar em branco, não haverá limite.

3.2.4 Configurar o setroubleshoot para coletar informações de servidores remotos

Você pode configurar o setroubleshoot para reunir dados de auditoria do SELinux de servidores remotos. Para isso, configure a lista de endereços.

[listen_for_client] address_list

No lado do servidor.

[client_connect_to] address_list

No lado do cliente.

Os endereços na lista estão neste formato:

          [{FAMILY}]ADDRESS[:PORT_NUMBER]

Em que {FAMILY} é {inet} ou {unix}%{path}s. Se a família de endereços for inet, você poderá especificar um número de porta; do contrário, o número da porta será definido como o padrão especificado pela opção de configuração default_port. O valor padrão {unix}%{path}s hostname significa escutar no soquete de domínio do Unix local.

3.3 Executando a análise de /var/log/audit/audit.log

Para permitir que a ferramenta setroubleshoot analise o arquivo de registro de auditoria, execute o comando:

> sudo sealert -a /var/log/audit/audit.log

Na saída de exemplo a seguir, há dois valores de porta atribuídos ao serviço SSHD:

100% done
found 1 alerts in /var/log/audit/audit.log
--------------------------------------------------------------------------------

SELinux is preventing sshd from name_bind access on the tcp_socket port 2222.

*****  Plugin bind_ports (92.2 confidence) suggests   ************************ 

If you want to allow sshd to bind to network port 2222
Then you need to modify the port type.
Do
# semanage port -a -t PORT_TYPE -p tcp 2222  1
    where PORT_TYPE is one of the following: ssh_port_t, vnc_port_t, xserver_port_t.

*****  Plugin catchall_boolean (7.83 confidence) suggests   ******************

If you want to allow nis to enabled
Then you must tell SELinux about this by enabling the 'nis_enabled' boolean.

Do
setsebool -P nis_enabled 1

*****  Plugin catchall (1.41 confidence) suggests   **************************

If you believe that sshd should be allowed name_bind access on the port 2222 tcp_socket 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 'sshd' --raw | audit2allow -M my-sshd
# semodule -X 300 -i my-sshd.pp

Additional Information:
...

First Seen                    2024-02-07 14:26:27 UTC
Last Seen                     2024-02-08 03:30:12 UTC
Local ID                      b5cbdd75-3f8d-425d-af75-f6cbf1540ffd 

Raw Audit Messages
type=AVC msg=audit(1707363012.797:25): avc:  denied  { name_bind } for  pid=841 comm="sshd" src=2222 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=system_u:object_r:unreserved_port_t:s0 tclass=tcp_socket permissive=0


Hash: sshd,sshd_t,unreserved_port_t,tcp_socket,name_bind

1

O plug-in bind_ports apresenta a solução mais adequada para esse problema.