Política de segurança para contêineres confidenciais no Serviço de Kubernetes do Azure
Conforme descrito pelo Consórcio de Computação Confidencial (CCC), "Computação Confidencial é a proteção de dados em uso executando computação em um Ambiente de Execução Confiável (TEE) baseado em hardware e atestado." Os contêineres confidenciais do AKS foram projetados para proteger os dados dos pods do Kubernetes em uso contra acesso não autorizado de fora desses pods. Cada pod é executado em uma UVM (Máquina Virtual de Utilitário) protegida pelo AMD SEV-SNP TEE, criptografando os dados em uso e impedindo o acesso aos dados pelo SO (Sistema Operacional) Host. Os engenheiros da Microsoft colaboraram com as comunidades de código aberto Contêineres Confidenciais (CoCo) e Contêineres Kata no projeto e na implementação de Contêineres Confidenciais.
Visão geral da política de segurança
Um dos principais componentes da arquitetura do sistema Contêineres Kata é o Agent Kata. Ao usar os Contêineres Kata para implementar Contêineres Confidenciais, o agente será executado dentro do TEE baseado em hardware e, portanto, fará parte da Base de Computação Confiável (TCB) do pod. Conforme mostrado no diagrama a seguir, o agente Kata fornece um conjunto de APIs ttrpc que permitem que os componentes do sistema fora do TEE criem e gerenciem pods do Kubernetes baseados em informações confidenciais. Esses outros componentes (por exemplo, o Kata Shim) não fazem parte do TCB do pod. Portanto, o agente deve se proteger de chamadas de API com possíveis bugs ou mal-intencionadas.
Nos Contêineres Confidenciais do AKS, a autoproteção da API do agente Kata é implementada usando uma política de segurança (também conhecida como Política do Agente Kata), especificada pelos proprietários dos pods confidenciais. O documento da política contém regras e dados correspondentes a cada pod, usando a linguagem de política Rego padrão do setor. A aplicação da política dentro da UVM (VM de utilitário) é implementada usando o OPA (Open Policy Agent) – um projeto graduado da CNCF (Cloud Native Computing Foundation).
Conteúdo da política
A política de segurança descreve todas as chamadas para as APIs ttrpc do agente (e os parâmetros dessas chamadas de API) que são esperadas para criar e gerenciar o pod Confidential. O documento de política de cada pod é um arquivo de texto, usando a linguagem Rego. Há três seções de alto nível do documento de política.
Dados
Os dados da política são específicos para cada pod. Eles contêm, por exemplo:
- Uma lista de contêineres que se espera que sejam criados no pod.
- Uma lista de APIs bloqueadas pela política por padrão (por motivos de confidencialidade).
Exemplos de dados incluídos no documento de política para cada um dos contêineres em um pod:
- Informações de integridade da imagem.
- Comandos executados no contêiner.
- Volumes e montagens de armazenamento.
- Contexto de segurança da execução. Por exemplo, o sistema de arquivos raiz é somente leitura?
- O processo tem permissão para obter novos privilégios?
- Variáveis de ambiente.
- Outros campos da configuração de runtime do contêiner da Open Container Initiative (OCI).
Regras
As regras de política, especificadas no formato Rego, são executadas pelo OPA para cada chamada à API do agente Kata de fora da UVM (VM de Utilitário). O agente fornece todas as entradas de API ao OPA, e o OPA usa as regras para verificar se as entradas são consistentes com os dados da política. Se as regras e os dados da política não permitirem entradas de API, o agente rejeitará a chamada à API retornando uma mensagem de erro "bloqueado pela política". Aqui estão alguns exemplos de regras:
- Cada camada de contêiner é exposta como um dispositivo de bloco virtio somente leitura para a UVM (VM de Utilitário). A integridade desses dispositivos de bloco é protegida usando a tecnologia dm-verity do kernel do Linux. O valor esperado da raiz da árvore de hash dm-verity é incluído nos dados da política e verificado no runtime pelas regras da política.
- As regras rejeitam a criação de contêineres quando uma linha de comando inesperada, montagem de armazenamento, contexto de segurança de execução ou variável de ambiente é detectada.
Por padrão, a política de regras é comum a todos os pods. A ferramenta genpolicy gera os dados da política e é específica para cada pod.
Valores padrão
Ao avaliar as regras Rego usando os dados da política e as entradas da API como parâmetros, o OPA tenta encontrar pelo menos um conjunto de regras que retorna um valor true
com base nos dados de entrada. Se as regras não retornarem true
, o OPA retornará ao agente o valor padrão para essa API. Exemplos de valores padrão da Política:
default CreateContainerRequest := false
- significa que qualquer chamada à API CreateContainer é rejeitada, a menos que um conjunto de regras da Política permita explicitamente essa chamada.default GuestDetailsRequest := true
- significa que as chamadas de fora do TEE para a API GuestDetails são sempre permitidas porque os dados retornados por essa API não são confidenciais para a confidencialidade das cargas de trabalho do cliente.
Envio da política para o agente Kata
Todas as UVMs (VMs de Utilitário) do Contêineres Confidenciais do AKS são iniciados usando uma política genérica e padrão incluída no sistema de arquivos raiz das UVMs (VMs de Utilitário). Portanto, uma política que corresponda à carga de trabalho real do cliente deve ser fornecida ao agente em tempo de execução. O texto da política é inserido em seu arquivo de manifesto YAML, conforme descrito anteriormente, e é fornecido dessa forma ao agente no início da inicialização da UVM (VM de Utilitário). A anotação da política passa pelos componentes kubelet, containerd e Kata shim do sistema de Contêineres Confidenciais do AKS. Em seguida, o agente que trabalha em conjunto com o OPA impõe a política para todas as chamadas às suas próprias APIs.
A política é fornecida usando componentes que não fazem parte do seu TCB, portanto, inicialmente, essa política não é confiável. A confiabilidade da política deve ser estabelecida por meio do Atestado Remoto, conforme descrito na seção a seguir.
Estabelecer a confiança no documento da política
Antes de criar a UVM (VM de Utilitário), o shim do Kata calcula o hash SHA256 do documento de política e anexa esse valor de hash ao TEE. Essa ação cria uma forte ligação entre o conteúdo da Política e a UVM (VM de Utilitário). Esse campo TEE não pode ser modificado posteriormente pelo software executado dentro da UVM (VM de Utilitário) ou fora dela.
Ao receber a política, o agente verificará se o hash da política corresponde ao campo TEE imutável. O agente rejeita a política recebida se detectar uma incompatibilidade de hash.
Antes de lidar com informações confidenciais, suas cargas de trabalho devem executar etapas de Atestado Remoto para provar a qualquer Parte Confiável que a carga de trabalho é executada usando as versões esperadas das versões de TEE, SO, agente, OPA e sistema de arquivos raiz. O atestado é implementado em um contêiner executado dentro da UVM (VM de Utilitário) que obtém evidências de atestado assinadas do hardware AMD SEV-SNP. Um dos campos da evidência de atestado é o campo TEE de hash de política descrito anteriormente. Portanto, o serviço de atestado pode verificar a integridade da política, comparando o valor desse campo com o hash esperado da política do pod.
Imposição de política
O agente Kata é responsável por aplicar a política. A Microsoft contribuiu para a comunidade Kata e CoCo com o código do agente responsável por verificar a política para cada chamada à API ttrpc do agente. Antes de executar as ações correspondentes à API, o agente usa a API REST do OPA para verificar se as regras e os dados da política permitem ou bloqueiam a chamada.