Acesso de contêiner de segurança a recursos usando recursos de segurança internos do Linux
Neste artigo, você aprenderá a proteger o acesso de contêiner aos recursos para suas cargas de trabalho do AKS (Serviço de Kubernetes do Azure).
Visão geral
Da mesma forma que deve conceder a usuários ou grupos os privilégios mínimos necessários, você também deve limitar os contêineres apenas às ações e aos processos necessários. Para minimizar o risco de ataques, evite configurar aplicativos e contêineres que exijam privilégios elevados ou acesso à raiz.
Você pode usar contextos de segurança de pod internos do Kubernetes para definir mais permissões, como o usuário ou grupo a ser executado como, as funcionalidades do Linux a serem expostas ou configuradas allowPrivilegeEscalation: false
no manifesto do pod. Para obter mais práticas recomendadas, confira Proteger o acesso do pod a recursos.
Para um controle ainda mais granular das ações de contêiner, você pode usar recursos de segurança internos do Linux, como AppArmor e seccomp.
- Defina os recursos de segurança do Linux no nível do nó.
- Implemente recursos por meio de um manifesto de pod.
Os recursos de segurança internos do Linux estão disponíveis apenas em nós e pods do Linux.
Observação
Atualmente, os ambientes do Kubernetes não são completamente seguros para uso hostil multilocatário. Recursos de segurança adicionais, como Microsoft Defender para contêineres, AppArmor, seccomp, Admissãode Segurança de Pod ou RBAC do Kubernetes para nós, bloqueiam explorações com eficiência.
Para a segurança verdadeira ao executar cargas de trabalho multilocatários hostis, confie apenas em um hipervisor. O domínio de segurança para o Kubernetes se torna o cluster inteiro, não um nó individual.
Para esses tipos de cargas de trabalho multilocatário hostis, você deve usar clusters fisicamente isolados.
Armadura de aplicativo
Para limitar as ações de contêineres, use o módulo de segurança de kernel do Linux AppArmor. AppArmor está disponível como parte do sistema operacional de nó do AKS subjacente e está habilitado por padrão. Você cria perfis do AppArmor que restringem ações de leitura, gravação ou execução, bem como funções de sistema como a montagem de sistemas de arquivos. Perfis padrão do AppArmor restringem o acesso a vários locais /proc
e /sys
e fornecem um meio para isolar logicamente os contêineres do nó subjacente. O AppArmor funciona para qualquer aplicativo executado no Linux, não apenas para os pods do Kubernetes.
Para ver o AppArmor em ação, o exemplo a seguir cria um perfil que impede a gravação em arquivos.
Conecte-se por SSH a um nó do AKS.
Crie um arquivo chamado deny-write.profile.
Copie e cole o seguinte conteúdo:
#include <tunables/global> profile k8s-apparmor-example-deny-write flags=(attach_disconnected) { #include <abstractions/base> file, # Deny all file writes. deny /** w, }
Perfis de AppArmor são adicionados usando o comando apparmor_parser
.
Adicione o perfil ao AppArmor.
Especifique o nome do perfil criado na etapa anterior:
sudo apparmor_parser deny-write.profile
Se o perfil for analisado corretamente e aplicado ao AppArmor, você não verá nenhuma saída e retornará ao prompt de comando.
No computador local, crie um manifesto de pod chamado aks-apparmor.yaml. Esse manifesto:
- Define uma anotação para
container.apparmor.security.beta.kubernetes
. - Faz referência ao perfil de negação de gravação criado nas etapas anteriores.
apiVersion: v1 kind: Pod metadata: name: hello-apparmor annotations: container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write spec: containers: - name: hello image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
- Define uma anotação para
Com o pod implantado, execute o seguinte comando e verifique se o pod hello-apparmor mostra um status Em execução:
kubectl get pods NAME READY STATUS RESTARTS AGE aks-ssh 1/1 Running 0 4m2s hello-apparmor 0/1 Running 0 50s
Para obter mais informações sobre AppArmor, confira Perfis do AppArmor no Kubernetes.
Computação segura (seccomp)
Enquanto o AppArmor funciona para qualquer aplicativo do Linux, o seccomp (computação segura) funciona no nível do processo. O Seccomp também é um módulo de segurança de kernel do Linux e tem suporte nativo pelo containerd
runtime usado pelos nós do AKS. Com o seccomp, você pode limitar as chamadas do sistema de um contêiner. O Seccomp estabelece uma camada extra de proteção contra vulnerabilidades comuns de chamada do sistema exploradas por atores mal-intencionados e permite que você especifique um perfil padrão para todas as cargas de trabalho no nó.
Configurar um perfil seccomp padrão (versão prévia)
Você pode aplicar perfis seccomp padrão usando configurações de nó personalizadas ao criar um novo pool de nós do Linux. Há dois valores com suporte no AKS: RuntimeDefault
e Unconfined
. Algumas cargas de trabalho podem exigir um número menor de restrições de syscall do que outras. Isso significa que eles podem falhar durante o runtime com o perfil 'RuntimeDefault'. Para atenuar essa falha, você pode especificar o perfil de Unconfined
. Se sua carga de trabalho exigir um perfil personalizado, consulte Configurar um perfil seccomp personalizado.
Limitações
- SeccompDefault não é um parâmetro suportado para pools de nós do Windows.
- SeccompDefault estará disponível a partir da API 2024-09-02-preview.
Importante
As versões prévias do recurso AKS estão disponíveis em uma base de autoatendimento e aceitação. As visualizações são fornecidas "como estão" e "conforme disponíveis" e estão excluídas dos acordos de nível de serviço e da garantia limitada. As versões prévias do AKS são parcialmente cobertas pelo suporte ao cliente em uma base de melhor esforço. Dessa forma, esses recursos não são destinados ao uso em produção. Para obter mais informações, consulte os seguintes artigos:
Registrar o sinalizador de recurso KubeletDefaultSeccompProfilePreview
Registre o sinalizador de recurso
KubeletDefaultSeccompProfilePreview
usando o comandoaz feature register
.az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
Demora alguns minutos para o status exibir Registrado.
Verifique o status do registro usando o comando
az feature show
.az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
Quando o status reflete Registrado, atualize o registro do provedor de recursos Microsoft.ContainerService usando o comando
az provider register
.az provider register --namespace Microsoft.ContainerService
Restringir as chamadas do sistema do contêiner com seccomp
1. Siga as etapas para aplicar um perfil seccomp na configuração do kubelet especificando "seccompDefault": "RuntimeDefault"
.
RuntimeDefault
usa o perfil de seccomp padrão do contêiner, restringindo determinadas chamadas do sistema para aprimorar a segurança. As chamadas restritas falharão. Para obter mais informações, consulte o perfil de seccomp padrão containerD.
2. Verifique se a configuração foi aplicada.
Você pode confirmar se as configurações são aplicadas aos nós conectando-se ao host e verificando se as alterações de configuração foram feitas no sistema de arquivos.
3. Solucionar problemas de falhas de carga de trabalho.
Quando SeccompDefault está habilitado, o perfil de seccomp padrão do runtime do contêiner é usado por padrão para todas as cargas de trabalho agendadas no nó. Isso pode fazer com que as cargas de trabalho falhem devido a chamadas bloqueadas. Se uma falha de carga de trabalho tiver ocorrido, você poderá ver erros como:
- A carga de trabalho é existente inesperadamente depois que o recurso é habilitado, com erro de "permissão negada".
- Mensagens de erro seccomp também podem ser vistas em auditoria ou syslog substituindo SCMP_ACT_ERRNO por SCMP_ACT_LOG no perfil padrão.
Se você tiver os erros acima, recomendamos que você altere seu perfil seccomp para Unconfined
. Unconfined
não impõe restrições às chamadas, permitindo todas as chamadas do sistema, o que reduz a segurança.
Configurar um perfil de seccomp personalizado
Com um perfil seccomp personalizado, você pode ter um controle mais granular sobre chamadas restritas. Alinhe-se à melhor prática de conceder ao contêiner as permissões mínimas para sua execução ao:
- Definir com filtros as ações a serem permitidas ou negadas.
- Anotar em um manifesto YAML do pod para associação ao filtro de seccomp.
Para ver o seccomp em ação, crie um filtro que impeça a alteração das permissões em um arquivo.
Conecte-se por SSH a um nó do AKS.
Crie um filtro de seccomp chamado /var/lib/kubelet/seccomp/prevent-chmod.
Copie e cole o seguinte conteúdo:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "name": "chmod", "action": "SCMP_ACT_ERRNO" }, { "name": "fchmodat", "action": "SCMP_ACT_ERRNO" }, { "name": "chmodat", "action": "SCMP_ACT_ERRNO" } ] }
Na versão 1.19 e posterior, você precisa configurar:
{ "defaultAction": "SCMP_ACT_ALLOW", "syscalls": [ { "names": ["chmod","fchmodat","chmodat"], "action": "SCMP_ACT_ERRNO" } ] }
No computador local, crie um manifesto de pod chamado aks-seccomp.yaml e cole o conteúdo a seguir. Esse manifesto:
- Define uma anotação para
seccomp.security.alpha.kubernetes.io
. - Faz referência ao filtro prevent-chmod criado na etapa anterior.
apiVersion: v1 kind: Pod metadata: name: chmod-prevented annotations: seccomp.security.alpha.kubernetes.io/pod: localhost/prevent-chmod spec: containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
Na versão 1.19 e posterior, você precisa configurar:
apiVersion: v1 kind: Pod metadata: name: chmod-prevented spec: securityContext: seccompProfile: type: Localhost localhostProfile: prevent-chmod containers: - name: chmod image: mcr.microsoft.com/dotnet/runtime-deps:6.0 command: - "chmod" args: - "777" - /etc/hostname restartPolicy: Never
- Define uma anotação para
Implante o pod de exemplo usando o comando kubectl apply:
kubectl apply -f ./aks-seccomp.yaml
Veja o status do pod usando o comando kubectl get pods.
- O pod relata um erro.
- O comando
chmod
é impedido de ser executado pelo filtro seccomp, conforme mostrado na saída de exemplo:
kubectl get pods NAME READY STATUS RESTARTS AGE chmod-prevented 0/1 Error 0 7s
Opções de perfil de segurança seccomp
Os perfis de segurança seccomp são um conjunto de chamadas syscalls definidas permitidas ou restritas. A maioria dos runtimes de contêiner tem um perfil seccomp padrão semelhante, se não o mesmo que o que o Docker usa. Para obter mais informações sobre perfis disponíveis, consulte os perfis de seccomp padrão do Docker ou containerD.
O AKS usa o perfil de seccomp padrão containerD para nosso RuntimeDefault quando você configura o seccomp usando a configuração de nó personalizado.
Chamadas syscalls significativas bloqueadas pelo perfil padrão
O Docker e containerD mantêm listas de permissões de chamadas seguras. Esta tabela lista as chamadas syscalls significativas (mas não todas) que são efetivamente bloqueadas porque não estão na lista de permissões. Se qualquer uma das chamadas bloqueadas for necessária para sua carga de trabalho, não use o perfil RuntimeDefault
seccomp.
Quando são feitas alterações no Docker e no containerD, o AKS atualiza sua configuração padrão para corresponder. As atualizações dessa lista podem causar falha na carga de trabalho. Para ver as atualizações de versão, consulte as notas de versão do AKS.
Chamada de syscall bloqueada | Descrição |
---|---|
acct |
Syscall de contabilidade que pode permitir que os contêineres desabilitem seus próprios limites de recurso ou contabilidade de processo. Também fechado por CAP_SYS_PACCT . |
add_key |
Impedir que os contêineres usem o keyring do kernel, que não é espaçado por nomes. |
bpf |
Negar o carregamento de programas bpf potencialmente persistentes no kernel, já fechado por CAP_SYS_ADMIN . |
clock_adjtime |
A hora/data não está com o nome espaçado. Também fechado por CAP_SYS_TIME . |
clock_settime |
A hora/data não está com o nome espaçado. Também fechado por CAP_SYS_TIME . |
clone |
Negar a clonagem de novos namespaces. Também fechado por sinalizadores CAP_SYS_ADMIN for CLONE_* , exceto CLONE_NEWUSER . |
create_module |
Negar manipulação e funções em módulos de kernel. Obsoleto. Também fechado por CAP_SYS_MODULE . |
delete_module |
Negar manipulação e funções em módulos de kernel. Também fechado por CAP_SYS_MODULE . |
finit_module |
Negar manipulação e funções em módulos de kernel. Também fechado por CAP_SYS_MODULE . |
get_kernel_syms |
Negar a recuperação de símbolos de kernel e módulo exportados. Obsoleto. |
get_mempolicy |
Syscall que modifica a memória do kernel e as configurações NUMA. Já fechado por CAP_SYS_NICE . |
init_module |
Negar manipulação e funções em módulos de kernel. Também fechado por CAP_SYS_MODULE . |
ioperm |
Impedir que os contêineres modifiquem os níveis de privilégio de E/S do kernel. Já fechado por CAP_SYS_RAWIO . |
iopl |
Impedir que os contêineres modifiquem os níveis de privilégio de E/S do kernel. Já fechado por CAP_SYS_RAWIO . |
kcmp |
Restrinja os recursos de inspeção do processo, já bloqueados por remoção CAP_SYS_PTRACE . |
kexec_file_load |
Irmã syscall de kexec_load que faz a mesma coisa, argumentos ligeiramente diferentes. Também fechado por CAP_SYS_BOOT . |
kexec_load |
Negue o carregamento de um novo kernel para execução posterior. Também fechado por CAP_SYS_BOOT . |
keyctl |
Impedir que os contêineres usem o keyring do kernel, que não é espaçado por nomes. |
lookup_dcookie |
Syscall de rastreamento/criação de perfil, que pode vazar informações no host. Também fechado por CAP_SYS_ADMIN . |
mbind |
Syscall que modifica a memória do kernel e as configurações NUMA. Já fechado por CAP_SYS_NICE . |
mount |
Negar montagem, já fechado por CAP_SYS_ADMIN . |
move_pages |
Syscall que modifica a memória do kernel e as configurações NUMA. |
nfsservctl |
Negar interação com o daemon nfs do kernel. Obsoleto desde o Linux 3.1. |
open_by_handle_at |
Causa de uma fuga de contêiner antiga. Também fechado por CAP_DAC_READ_SEARCH . |
perf_event_open |
Syscall de rastreamento/criação de perfil, que pode vazar informações no host. |
personality |
Impedir que o contêiner habilite a emulação do BSD. Não inerentemente perigoso, mas mal testado, potencial para vulns kernel. |
pivot_root |
Negar pivot_root, deve ser uma operação privilegiada. |
process_vm_readv |
Restrinja os recursos de inspeção do processo, já bloqueados por remoção CAP_SYS_PTRACE . |
process_vm_writev |
Restrinja os recursos de inspeção do processo, já bloqueados por remoção CAP_SYS_PTRACE . |
ptrace |
Syscall de rastreamento/criação de perfil. Bloqueado nas versões do kernel do Linux antes da 4.8 para evitar o bypass do seccomp. Os processos arbitrários de rastreamento/criação de perfil já estão bloqueados descartando CAP_SYS_PTRACE, pois podem vazar informações sobre o host. |
query_module |
Negar manipulação e funções em módulos de kernel. Obsoleto. |
quotactl |
Chamada de cota que pode permitir que os contêineres desabilitem seus próprios limites de recursos ou contabilidade de processo. Também fechado por CAP_SYS_ADMIN . |
reboot |
Não permita que os contêineres reinicializem o host. Também fechado por CAP_SYS_BOOT . |
request_key |
Impedir que os contêineres usem o keyring do kernel, que não é espaçado por nomes. |
set_mempolicy |
Syscall que modifica a memória do kernel e as configurações NUMA. Já fechado por CAP_SYS_NICE . |
setns |
Negar associar um thread a um namespace. Também fechado por CAP_SYS_ADMIN . |
settimeofday |
A hora/data não está com o nome espaçado. Também fechado por CAP_SYS_TIME . |
stime |
A hora/data não está com o nome espaçado. Também fechado por CAP_SYS_TIME . |
swapon |
Negar a troca inicial/parada para o arquivo/dispositivo. Também fechado por CAP_SYS_ADMIN . |
swapoff |
Negar a troca inicial/parada para o arquivo/dispositivo. Também fechado por CAP_SYS_ADMIN . |
sysfs |
Chamada obsoleta. |
_sysctl |
Obsoleto, substituído por /proc/sys. |
umount |
Deve ser uma operação privilegiada. Também fechado por CAP_SYS_ADMIN . |
umount2 |
Deve ser uma operação privilegiada. Também fechado por CAP_SYS_ADMIN . |
unshare |
Negar a clonagem de novos namespaces para processos. Também fechado por CAP_SYS_ADMIN , com exceção de unshare --user. |
uselib |
Chamadas mais antigas relacionadas a bibliotecas compartilhadas, não usadas por muito tempo. |
userfaultfd |
Tratamento de falhas de página do userspace, em grande parte necessário para migração de processo. |
ustat |
Chamada obsoleta. |
vm86 |
Na máquina virtual do modo real do kernel x86. Também fechado por CAP_SYS_ADMIN . |
vm86old |
Na máquina virtual do modo real do kernel x86. Também fechado por CAP_SYS_ADMIN . |
Próximas etapas
Para obter as práticas recomendadas associadas, confira Práticas recomendadas de segurança e atualizações de cluster no AKS e Práticas recomendadas de segurança de pod no AKS.
Azure Kubernetes Service