O sandbox SElinux falha ao iniciar a partir do serviço systemd

2

Eu tenho um servidor que executa o código enviado pelo usuário, para avaliação. Escrevi um serviço systemd que inicia um aplicativo python, esse aplicativo, em seguida, executa o código enviado usando o sandbox do SElinux.

O sandbox não inicia com o seguinte erro

/usr/bin/sandbox: User account must be setup with an MCS Range

No entanto, quando inicio meu servidor a partir da linha de comando como um usuário normal, em vez de um serviço systemd que o inicia, ele funciona sem problemas.

Esta é a saída de 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       *
system_u             system_u             s0-s0:c0.c1023       *

Meu conhecimento do SELinux é muito limitado, já que ele funciona quando lançado por um usuário normal. Acredito que isso tenha algo a ver com o system_u?

Executando o Fedora 20.

A aplicação python é na verdade um trabalhador de aipo.

    
por A. H. 01.01.2015 / 17:15

1 resposta

3

Existem dois problemas que fazem com que isso falhe.

TL; DR

Para que isso funcione, você precisa:

  1. Execute sandbox com uma opção --level .
  2. Instale a política que mostro abaixo.

Problema 1: intervalos de MCS

Quando você inicia o serviço a partir da linha de comando como um usuário normal, provavelmente está executando no seguinte contexto do SELinux. Você pode verificar com id -Z .

unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Existem cinco partes para esse contexto.

  1. Seu usuário do SELinux (unconfined_u)
  2. Sua função (unconfined_r)
  3. Seu domínio (unconfined_t)
  4. Seu intervalo MLS (s0-s0)
  5. Seu intervalo de MCS (c0.c1023)

Por padrão, a versão mais recente do sandbox requer que o usuário que está executando o comando sandbox tenha um intervalo de MCS definido (consulte commit 78b077c e envie 6c2ad1c a partir de 2011). Quando você está executando como usuário normal, tudo está OK, porque você tem um intervalo de MCS definido. No entanto, observe o contexto em que os serviços systemd são executados por padrão. (Eu obtive isso fazendo um script que imprimia seu contexto do SELinux para o syslog).

system_u:system_r:unconfined_service_t:s0

Opa! Nós não temos uma gama MCS! É por isso que você obteve seu erro ao executar o sandbox em um serviço systemd.

Felizmente, o sandbox tem um sinalizador de linha de comando que você pode usar para definir explicitamente as partes do MLS e do MCS do contexto de execução: --level . Isto é, quando você corre

sandbox --level "s0" /path/to/my/command

O sandbox não tentará mais extrair o intervalo de MCS do seu contexto atual.

Problema 2: emparelhamentos de domínio da caixa de areia

Se você fizer a alteração acima e tentar executar novamente seu serviço, receberá um novo erro.

/usr/bin/sandbox: Could not set exec context to system_u:system_r:sandbox_t:s0. Invalid argument

Esse erro significa que o SELinux não permitirá a transição do contexto systemd para o contexto da sandbox. A razão para isso é o emparelhamento entre as duas funções diferentes (system_r / unconfined_r) e o domínio da sandbox (sandbox_t).

O comando seinfo -rXXXXX -x mostra uma lista dos pares de domínios legais com a função "XXXXX". Vamos procurar sandbox_t.

$ sudo seinfo -runconfined_r -x | grep sandbox_t
     chrome_sandbox_t
     sandbox_t
$ sudo seinfo -rsystem_r -x | grep sandbox_t
     sshd_sandbox_t
     chrome_sandbox_t

Portanto, "sandbox_t" está disponível para emparelhar com "unconfined_r" mas não com "system_r". Eu não sei porque este é o caso; Meu melhor palpite é que o pessoal da Red Hat escreveu sandbox com a intenção de apenas usuários normais executá-lo. Felizmente, é razoavelmente fácil adicionar um emparelhamento entre "system_r" e "sandbox_t". Crie um arquivo de políticas (extensão * .te) com o seguinte conteúdo.

policy_module(sandbox_system, 1.0);
require {
    type sandbox_t;
}
role system_r types sandbox_t;

Se você nomear o arquivo "sandbox_system.te", poderá instalá-lo executando os seguintes comandos.

$ make -f /usr/share/selinux/devel/Makefile sandbox_system.pp
$ sudo semodule -i sandbox_system.pp

Agora, se você executar novamente o seinfo , verá o emparelhamento correto.

$ sudo seinfo -rsystem_r -x | grep sandbox_t
     sshd_sandbox_t
     chrome_sandbox_t
     sandbox_t

Dependendo da sua configuração, talvez seja necessário adicionar mais algumas regras ao seu arquivo de políticas, mas, a partir daqui, setroubleshoot e audit2allow poderão fazer mais a maior parte do trabalho.

Espero que isso ajude alguém!

    
por 25.02.2016 / 02:32