Existem dois problemas que fazem com que isso falhe.
TL; DR
Para que isso funcione, você precisa:
- Execute
sandbox
com uma opção--level
. - 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.
- Seu usuário do SELinux (unconfined_u)
- Sua função (unconfined_r)
- Seu domínio (unconfined_t)
- Seu intervalo MLS (s0-s0)
- 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!