Marca negra - como o OpenShift protege contra vulnerabilidades de contêiner com o SELinux

Você já fez um trabalho difícil para o bem da sociedade, mas não percebeu seus esforços, porque se beneficia há tanto tempo que está acostumado a isso? Esse é o tipo de trabalho para você que todos os membros da comunidade do SELinux realizam.



E em 18 de fevereiro deste ano, graças em grande parte ao seu trabalho, o mundo foi salvo da vulnerabilidade perigosa de bater em contêineres CVE-2019-5736 .

Embora existam outros sistemas operacionais e outros projetos de código aberto que usam controles de tipo e categoria, é raro que todos os componentes configurados com o SELinux sejam incluídos imediatamente, por padrão, e prontos para uso. Mais raramente, essa configuração abrange todos os níveis, até a solução de orquestração de contêiner, com base na qual a nuvem pública trabalha.

Há oito anos, o Red Hat OpenShift usa mecanismos de controle de acesso forçado do Linux, como aplicação de tipo (TE) e segurança de categoria múltipla (MCS). O SELinux é usado no OpenShift desde 2011. No Red Hat OpenShift Online, um serviço de hospedagem disponível publicamente onde milhares de desenvolvedores executam código de contêiner diariamente, o SELinux tem sido usado desde o início. E a versão do OpenShift usada, por exemplo, no data center da sua operadora de celular favorita? De fato, o módulo de segurança SELinux está incluído no Red Hat OpenShift Container Platform por padrão, por padrão! E não apenas ligado, mas totalmente configurado e pronto para proteger contra ameaças reais.

Diferente de outras distribuições do Kubernetes, o Red Hat fecha a lacuna entre o Linux e a plataforma de orquestração de contêineres instalada em cima dele. Ou seja, o Red Hat OpenShift monitora e elimina ameaças à segurança em toda a pilha, e não apenas em uma camada. E isso é feito por padrão - desde o primeiro dia de trabalho.

O OpenShift usa essa configuração por padrão no Red Hat Enterprise Linux (você nem precisa saber o que está lá). O problema não se limita à execução do setenforce 1. Em um laptop, as regras de controle de acesso para os tipos e categorias que o inquilino aplica para trabalhar com contêineres em um cluster Kubernetes podem ser estendidas a centenas de nós que podem ser usados ​​por milhares de outros inquilinos.

Pense em como será a configuração do SELinux com o MCS após alguns anos de uso em uma grande empresa que distribui credenciais do OpenShift para a esquerda e para a direita. Agora imagine que você fornece suas credenciais para efetuar login no cluster do OpenShift, como fazemos no openshift.com. A lealdade do SELinux geralmente falha em ser reconhecida por tudo o que faz em uma solução OpenShift. Se lhe parece que o sistema operacional não é tão importante atualmente, pense se você estava protegido contra a vulnerabilidade CVE-2019-5736 até fevereiro deste ano. No OpenShift, o CVE-2019-5736 está protegido desde o início, e você pode seguir para esta solução agora .

Marcas SELinux


Um dos recursos de segurança padrão mais eficazes implementados no Red Hat OpenShift é o Linux com Segurança Avançada (SELinux). O SELinux é um módulo de segurança do kernel Linux que fornece controle de acesso baseado em políticas de segurança. A maneira como o SELinux funciona é atribuir rótulos (nomes) a todos os processos e objetos do sistema operacional. Assim, cada elemento envolvido nas operações do kernel é marcado e classificado e, em seguida, recebe acesso com base em um conjunto de regras existente.

As regras de política definem o relacionamento entre processos e objetos marcados. As regras definidas pelo usuário nas políticas são aplicadas no nível do kernel. Por padrão, tudo o que não é permitido é automaticamente negado - por analogia com um firewall que nega acesso a todos os processos para os quais as permissões explícitas não estão configuradas. As ilustrações abaixo ilustram casos de uso simples.

Imagine um sistema no qual você precise definir tipos para objetos como gatos e cães. Gato e cachorro são tipos de processos.


* Todos os desenhos são de Máirín Duffy

A classe de objetos com os quais os processos irão interagir é feed. Adicione tipos de feed: cat_chow e dog_chow (Ohm-nom-nom).


Damos permissão para o cachorro comer comida de cachorro (dog_chow) e para o gato - comida de gato (cat_chow). Nós escrevemos essas permissões como uma regra de política do SELinux:

allow cat cat_chow:food eat; allow dog dog_chow:food eat; 


De acordo com essas regras, o processo “gato” será permitido no nível do kernel para comer alimentos com o rótulo cat_chow e, para os cães - alimentos com o rótulo dog_chow.


Mas lembramos que no SELinux, por padrão, tudo é proibido. Portanto, se o cachorro tentar comer comida de gato, o núcleo não permitirá.


Esse é o controle de tipo, que desempenha um papel importante na proteção do sistema host dos processos do contêiner. Os processos de contêiner podem apenas ler e executar arquivos do diretório / usr e gravar dados apenas nos arquivos de contêiner. Essa restrição protege o host de contêineres de maneira confiável, mas não protege alguns contêineres de outros, porque todos são marcados com o mesmo tipo. Para proteger contêineres um do outro, você precisará implementar o controle de tag MCS.

MCS não puxa um gato pela cauda


O uso do MCS não está diretamente relacionado à proteção do OpenShift do CVE-2019-5736 , mas é útil familiarizar-se com este tópico para entender melhor os princípios do uso do SELinux no OpenShift. A atribuição de etiquetas MCS do ponto de vista do usuário ou administrador do sistema é bastante simples. Você só precisa configurar um conjunto de categorias que sejam rótulos de texto simples (por exemplo, Fido ou Spot) e adicionar usuários a eles. O administrador do sistema primeiro configura as categorias e depois adiciona usuários a elas, após o que os usuários podem usar esses rótulos conforme desejarem. Isso é conveniente porque o MCS permite que você use tags SELinux padrão para gerenciar objetos. Vamos voltar ao sistema imaginário a partir do exemplo acima.

Adicione outra parte do rótulo que será aplicada ao processo do cão e ao feed dog_chow. Atribua o processo “cachorro” a cachorro: random1 (Fido) e dog: random2 (Spot).


Vamos atribuir os rótulos dog_chow: random1 (Fido) e dog_chow: random2 (Spot) aos alimentos para cães.


De acordo com os princípios de operação do MCS, se as regras de controle forçado por tipo forem observadas e os tags arbitrários do MCS corresponderem exatamente, o acesso será permitido e, em todos os outros casos, será negado.

Tentativas de Fido (cão: random1) de comer cat_chow: os alimentos serão negados devido a controles forçados do tipo.


Defesa em profundidade


O módulo de segurança SELinux padrão usado pelo OpenShift é um excelente exemplo de defesa em profundidade. O OpenShift, como muitas outras plataformas baseadas no Kubernetes, usa políticas de SCC / PSP que proíbem a execução de contêineres com privilégios de root. Essa limitação também protege contra o CVE-2019-5736 . No OpenShift, os contêineres pertencentes ao usuário raiz são bloqueados por padrão, mas esse parâmetro pode ser alterado . Mesmo que você permita que os contêineres sejam executados como raiz, a configuração padrão do SELinux no OpenShift ainda protege contra o CVE-2019-5736 . Esse é outro nível de proteção que realmente compensa nessa situação e está longe de ser o único no OpenShift. Mais informações podem ser encontradas no documento 10 níveis de segurança do contêiner .

Para obter mais informações sobre o CVE-2019-5736 , incluindo o patch do Red Hat Enterprise Linux para o tempo de execução do contêiner, consulte a revisão de vulnerabilidades do Red Hat .

Source: https://habr.com/ru/post/pt443426/


All Articles