Partilhar via


Acesso de contêiner de segurança a recursos usando recursos de segurança Linux integrados

Neste artigo, você aprenderá a proteger o acesso de contêiner a recursos para suas cargas de trabalho do Serviço Kubernetes do Azure (AKS).

Importante

Desde 30 de novembro de 2025, o Azure Kubernetes Service (AKS) já não suporta nem fornece atualizações de segurança para o Azure Linux 2.0. A imagem da máquina virtual do Azure Linux 2.0 está congelada na versão 202512.06.0. A partir de 31 de março de 2026, as imagens dos nós serão removidas e não conseguirá escalar os seus pools de nós. Migre para uma versão Azure Linux suportada atualizando os seus pools de nós para uma versão Kubernetes suportada ou migrando para o osSku AzureLinux3. Para obter mais informações, consulte [Desativação] Pools de nós do Azure Linux 2.0 no AKS.

Descrição geral

Da mesma forma que você deve conceder aos usuários ou grupos os privilégios mínimos necessários, você também deve limitar os contêineres apenas às ações e processos necessários. Para minimizar o risco de ataque, evite configurar aplicativos e contêineres que exijam privilégios escalonados ou acesso raiz.

Você pode usar os contextos internos de segurança de pod Kubernetes para definir mais permissões, como o usuário ou grupo sob o qual executar, as capacidades do Linux a expor, ou a configuração de allowPrivilegeEscalation: false no manifesto do pod. Para obter mais práticas recomendadas, consulte Proteger o acesso do pod aos recursos.

Para melhorar o isolamento do host e diminuir o movimento lateral no Linux, você pode usar namespaces de usuário.

Para um controle ainda mais granular das ações do contêiner, você pode usar recursos de segurança internos do Linux, como AppArmor e seccomp.

  1. Defina os recursos de segurança do Linux no nível do nó.
  2. Implemente funcionalidades através de um manifesto de pod.

Os recursos de segurança integrados do Linux só estão disponíveis em nodos e pods Linux.

Nota

Atualmente, os ambientes Kubernetes não são completamente seguros para uso hostil por múltiplos locatários. Recursos de segurança adicionais, como Microsoft Defender for Containers, AppArmor, seccomp, user-namespaces, Pod Security Admission ou Kubernetes RBAC for nodes, bloqueiam explorações de forma eficiente.

Para uma verdadeira segurança ao executar cargas de trabalho multilocatárias hostis, confie apenas em um hipervisor. O domínio de segurança para Kubernetes passa a incluir todo o cluster, não um nó individual.

Para estes tipos de cargas de trabalho multilocatárias hostis, deve-se usar clusters fisicamente isolados.

Namespaces de usuário

Os pods Linux são executados usando vários namespaces por padrão: um namespaces de rede para isolar a identidade de rede e um namespace PID para isolar os processos. Um namespace de usuário isola os usuários dentro do contêiner dos usuários no host. Ele também limita o escopo de recursos e as interações do pod com o resto do sistema.

Os UIDs e GIDs dentro do contêiner são mapeados para usuários sem privilégios no host, portanto, toda a interação com o resto do host acontece como esses UID e GID sem privilégios. Por exemplo, a raiz dentro do contêiner (UID 0) pode ser mapeada para o usuário 65536 no host. O Kubernetes cria o mapeamento para garantir que ele não se sobreponha a outros pods usando namespaces de usuário no sistema.

A implementação do Kubernetes tem alguns benefícios importantes:

  • Maior isolamento do host: se um contêiner escapar dos limites do pod, mesmo que seja executado como root dentro do contêiner, ele não terá privilégios no host. O motivo é porque os UIDs e GIDs do contêiner são mapeados para usuários sem privilégios no host. Se houver um escape de contêiner, os namespaces de usuário protegem muito quais arquivos no host um contêiner pode ler/gravar, para qual processo ele pode enviar sinais. Os recursos concedidos são válidos apenas dentro do namespace do usuário e não no host.

  • Prevenção de movimento lateral: Como os UIDs e GIDs para contêineres diferentes são mapeados para UIDs e GIDs diferentes e não sobrepostos no host, os contêineres têm mais dificuldade em atacar uns aos outros. Por exemplo, suponha que o contêiner A seja executado com UIDs e GIDs diferentes no host do que o contêiner B. No caso de uma quebra de contêiner, as operações que ele pode fazer nos arquivos e processos do contêiner B são limitadas: apenas ler/gravar o que um arquivo permite a outros. Mas nem isso acaba sendo possível, pois há uma prevenção extra no diretório pai do volume raiz do pod para garantir que apenas o GID do pod possa acessá-lo.

  • Princípio de Honra de Privilégios Mínimos: Como os UIDs e GIDs são mapeados para usuários sem privilégios no host, somente os usuários que precisam do privilégio no host (e desabilitam namespaces de usuário) o obtêm. Sem namespaces de utilizador, não há separação entre os utilizadores do contentor e os utilizadores do anfitrião. Não podemos evitar conceder privilégios ao host a processos que não precisam, quando eles precisam de privilégios logo dentro do contentor.

  • Ativação de novos casos de uso: os namespaces de usuário permitem que os contêineres ganhem determinados recursos dentro de seu próprio namespace de usuário sem afetar o host. Os recursos concedidos restritos ao pod desbloqueiam novas possibilidades, como executar aplicativos que exigem operações privilegiadas sem conceder acesso root total no host. Novos casos de uso comuns que podem ser implementados com segurança são: execução de contêineres aninhados e compilações de contêineres sem privilégios.

  • Configuração de contêiner sem privilégio: a maioria da criação e configuração do contêiner não é executada como raiz no host, o que limita significativamente o impacto de muitas CVEs.

Nenhuma dessas coisas é verdadeira quando namespaces de usuário não são usados. Se o contêiner for executado como root, quando os namespaces de usuário não forem usados, o processo será executado como root no host, os recursos serão válidos no host e a configuração do contêiner será feita como root no host.

Antes de começar

Antes de começar, certifique-se de que tem o seguinte:

  • Um cluster AKS existente. Se você não tiver um cluster, crie um usando a CLI do Azure, o Azure PowerShell ou o portal do Azure.
  • Kubernetes mínimo versão 1.33 para o plano de controle e nós de trabalho. Se você não estiver usando o kubernetes versão 1.33 ou superior, precisará atualizar sua versão do kubernetes.
  • Nós de trabalho executando o Azure Linux 3.0 ou Ubuntu 24.04. Se você não estiver usando essas versões do sistema operacional, não terá os requisitos mínimos de pilha para habilitar namespaces de usuário. Você precisará atualizar sua versão do sistema operacional.

Limitações

Habilitar namespaces de usuário

Não há configurações necessárias para usar esse recurso. Se usar a versão AKS necessária, tudo funciona fora da caixa.

  1. Crie um arquivo nomeado mypod.yaml e copie no seguinte manifesto:

    Para usar user-namespaces, o yaml precisa ter o campo hostUsers: false.

    apiVersion: v1
    kind: Pod
    metadata:
      name: userns
    spec:
      hostUsers: false
      containers:
      - name: shell
        command: ["sleep", "infinity"]
        image: debian
    
  2. Implante o aplicativo usando o kubectl apply comando e especifique o nome do seu manifesto YAML.

    kubectl apply -f mypod.yaml
    
  3. Verifique o status dos pods implantados usando o kubectl get pods comando.

    kubectl get pods
    
  4. Exec no pod para verificar /proc/self/uid_map usando o kubectl exec comando:

    kubectl exec -ti userns -- bash
    # Now inside the pod run
    cat /proc/self/uid_map
    

A saída deve ter 65536 na última coluna. Por exemplo:

0  833617920      65536

CVEs atenuadas

Aqui estão alguns CVEs que são totalmente/parcialmente atenuados com namespaces de usuário.

Tenha em mente que a lista não é exaustiva, é apenas uma seleção de CVEs com pontuação alta que são mitigadas:

Para saber mais, leia esta postagem de blog com informações adicionais sobre namespaces de usuário.

App Armadura

Para limitar as ações do contêiner, você pode usar o módulo de segurança do kernel do AppArmor Linux. O AppArmor está disponível como parte do SO subjacente do nó AKS e está ativado por predefinição. Você cria perfis do AppArmor que restringem leitura, gravação ou execução de ações, ou funções do sistema, como a montagem de sistemas de arquivos. Os perfis padrão do AppArmor restringem o acesso a várias localizações /proc e /sys e fornecem um meio lógico de isolar os contentores do nó subjacente. O AppArmor funciona para qualquer aplicativo executado em Linux, não apenas para pods Kubernetes.

Nota

O Azure Linux 3.0 não oferece suporte ao AppArmor. Para nós do Azure Linux 3.0, a recomendação é aproveitar o SELinux em vez do AppArmor para controle de acesso obrigatório.

Perfis do AppArmor em uso em um cluster AKS para limitar ações de contêiner

Para ver o AppArmor em ação, o exemplo a seguir cria um perfil que impede a gravação em arquivos.

  1. SSH para um nó AKS.

  2. Crie um arquivo chamado deny-write.profile.

  3. 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,
    }
    

Os perfis do AppArmor são adicionados usando o apparmor_parser comando.

  1. Adicione o perfil ao AppArmor.

  2. Especifique o nome do perfil criado na etapa anterior:

    sudo apparmor_parser deny-write.profile
    

    Se o perfil for analisado e aplicado corretamente ao AppArmor, você não verá nenhuma saída e retornará ao prompt de comando.

  3. A partir da sua máquina local, crie um manifesto de pod chamado aks-apparmor.yaml. Este manifesto:

    • Define uma anotação para container.apparmor.security.beta.kubernetes.
    • Faz referência ao perfil de negação-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" ]
    
  4. Com o pod implantado, execute o seguinte comando e verifique se o pod hello-apparmor mostra um status Running :

    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 o AppArmor, consulte Perfis do AppArmor no Kubernetes.

Computação segura (seccomp)

Enquanto o AppArmor funciona para qualquer aplicação Linux, seccomp (secure computing) funciona a nível de processo. Seccomp também é um módulo de segurança do kernel Linux e é suportado nativamente pelo containerd tempo de execução usado nos nós AKS. Com 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 chamadas do sistema exploradas por agentes mal-intencionados e permite especificar um perfil padrão para todas as cargas de trabalho no nó.

Configurar um perfil seccomp padrão (pré-visualização)

Você pode aplicar perfis seccomp padrão usando configurações de nó personalizadas ao criar um novo pool de nós Linux. Há dois valores suportados no AKS: RuntimeDefault e Unconfined. Algumas cargas de trabalho podem exigir um número menor de restrições nas chamadas de sistema do que outras. Isso significa que eles podem falhar durante o tempo de execução com o perfil 'RuntimeDefault'. Para atenuar essa falha, você pode especificar o Unconfined perfil. 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.
  • O SeccompDefault está disponível a partir da API 2024-09-02-preview.

Importante

As funcionalidades de pré-visualização do AKS estão disponíveis com base de auto-serviço e adesão voluntária. As visualizações prévias são fornecidas "como estão" e "conforme disponíveis" e são excluídas dos contratos de nível de serviço e da garantia limitada. As pré-visualizações do AKS são parcialmente cobertas pelo suporte ao cliente com base no melhor esforço possível. Como tal, estas funcionalidades não se destinam a utilização em produção. Para obter mais informações, consulte os seguintes artigos de suporte:

Registar a funcionalidade de sinalizador KubeletDefaultSeccompProfilePreview

  1. Registre o KubeletDefaultSeccompProfilePreview sinalizador de recurso usando o az feature register comando.

    az feature register --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
    

    Leva alguns minutos para que o status mostre Registrado.

  2. Verifique o status do registro usando o az feature show comando.

    az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
    
  3. Quando o estado refletir Registrado, atualize o registo do provedor de recursos Microsoft.ContainerService usando o comando az provider register.

    az provider register --namespace Microsoft.ContainerService
    

Restrinja as chamadas de sistema do seu contentor com seccomp

1. Siga as etapas para aplicar um perfil seccomp em sua configuração kubelet, especificando "seccompDefault": "RuntimeDefault".

RuntimeDefault Usa o perfil Seccomp padrão do Containerd, restringindo determinadas chamadas do sistema para aumentar a segurança. As chamadas de sistema restritas falharão. Para obter mais informações, consulte o perfil padrão seccomp 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. Solucione problemas de falhas de carga de trabalho.

Quando SeccompDefault está habilitado, o perfil seccomp padrão do tempo de execução 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 de sistema (syscalls) bloqueadas. Se tiver ocorrido uma falha na carga de trabalho, poderá ver erros como:

  • A carga de trabalho surge inesperadamente depois de o recurso ser ativado, com o erro "permissão negada".
  • As mensagens de erro Seccomp também podem ser vistas em auditd 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 a syscalls, permitindo que todas as chamadas do sistema sejam feitas, o que reduz a segurança.

Configurar um perfil seccomp personalizado

Com um perfil seccomp personalizado, é possível obter um controlo mais granular sobre as chamadas de sistema restritas. Alinhar-se à prática recomendada de conceder ao contêiner apenas a permissão mínima necessária para executar:

  • Definir com filtros quais ações permitir ou negar.
  • Anotação dentro do manifesto YAML de um pod para associar ao filtro seccomp.

Para ver o seccomp em ação, crie um filtro que impeça a alteração de permissões em um arquivo.

  1. SSH para um nó AKS.

  2. Crie um filtro seccomp chamado /var/lib/kubelet/seccomp/prevent-chmod.

  3. 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"
        }
      ]
    }
    
  4. Na sua máquina local, crie um manifesto de pod chamado aks-seccomp.yaml e cole o seguinte conteúdo. Este 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
    
  5. Implante o pod de exemplo usando o comando kubectl apply :

    kubectl apply -f ./aks-seccomp.yaml
    
  6. Visualize o status do pod usando o comando kubectl get pods .

    • O pod relata um erro.
    • O chmod comando é impedido de ser executado pelo filtro seccomp, como mostrado na saída de exemplo:
    kubectl get pods
    
    NAME                      READY     STATUS    RESTARTS   AGE
    chmod-prevented           0/1       Error     0          7s
    

Para obter ajuda na solução de problemas do seu perfil seccomp, consulte o artigo Solucionar problemas de configuração do perfil seccomp no Serviço Kubernetes do Azure.

Opções de perfil de segurança Seccomp

Os perfis de segurança Seccomp são um conjunto de syscalls definidos que são permitidos ou restritos. A maioria dos tempos de execução de contêiner tem um perfil seccomp padrão que é semelhante, se não o mesmo que o Docker usa. Para obter mais informações sobre perfis disponíveis, consulte Perfis seccomp padrão do Docker ou containerD .

O AKS usa o perfil seccomp padrão do containerD para RuntimeDefault ao configurar seccomp usando configuração de nó personalizada.

Chamadas de sistema significativas bloqueadas pelo perfil padrão

Tanto o Docker quanto o containerD mantêm listas de permissões de syscalls seguras. Esta tabela lista as syscalls significativas (mas não todas) que são efetivamente bloqueadas porque não estão na lista de permissões. Se alguma das chamadas de sistema bloqueadas for necessária para a sua carga de trabalho, não use o perfil seccomp RuntimeDefault.

Quando são feitas alterações no Docker e no containerD, o AKS atualiza sua configuração padrão para corresponder. As atualizações a esta lista podem causar falha na carga de trabalho. Para atualizações de versão, consulte as notas de versão do AKS.

Chamada de sistema bloqueada Descrição
acct Syscall de contabilidade que pode permitir que os contêineres desativem seus próprios limites de recursos ou processem a contabilidade. Também controlado por CAP_SYS_PACCT.
add_key Impeça que os contêineres usem o conjunto de chaves do kernel, que não é namespaced.
bpf Negar o carregamento de programas bpf potencialmente persistentes no kernel, já controlado por CAP_SYS_ADMIN.
clock_adjtime Hora/data não estão num namespace. Também controlado por CAP_SYS_TIME.
clock_settime Hora/data não estão num namespace. Também controlado por CAP_SYS_TIME.
clone Negar clonagem de novos namespaces. Também controlado por CAP_SYS_ADMIN for CLONE_* bandeiras, exceto CLONE_NEWUSER.
create_module Negar manipulação e funções em módulos do kernel. Obsoleto. Também controlado por CAP_SYS_MODULE.
delete_module Negar manipulação e funções em módulos do kernel. Também controlado por CAP_SYS_MODULE.
finit_module Negar manipulação e funções em módulos do kernel. Também controlado 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 de NUMA. Já fechado por CAP_SYS_NICE.
init_module Negar manipulação e funções em módulos do kernel. Também controlado por CAP_SYS_MODULE.
ioperm Impeça que os contêineres modifiquem os níveis de privilégio de E/S do kernel. Já fechado por CAP_SYS_RAWIO.
iopl Impeça que os contêineres modifiquem os níveis de privilégio de E/S do kernel. Já fechado por CAP_SYS_RAWIO.
kcmp Restrinja as capacidades de inspeção de processos, já bloqueadas pela remoção CAP_SYS_PTRACE.
kexec_file_load A syscall irmã de kexec_load que faz a mesma coisa, apenas com argumentos ligeiramente diferentes. Também controlado por CAP_SYS_BOOT.
kexec_load Negar o carregamento de um novo kernel para execução posterior. Também controlado por CAP_SYS_BOOT.
keyctl Impeça que os contêineres usem o conjunto de chaves do kernel, que não é namespaced.
lookup_dcookie Syscall de rastreamento ou criação de perfil, que pode vazar informações sobre o host. Também controlado por CAP_SYS_ADMIN.
mbind Syscall que modifica a memória do kernel e as configurações de NUMA. Já fechado por CAP_SYS_NICE.
mount Negar montagem, já bloqueado por CAP_SYS_ADMIN.
move_pages Syscall que modifica a memória do kernel e as configurações de NUMA.
nfsservctl Negar interação com o daemon nfs do kernel. Obsoleto desde Linux 3.1.
open_by_handle_at Causa de um rompimento de contêiner antigo. Também controlado por CAP_DAC_READ_SEARCH.
perf_event_open Syscall de rastreamento ou criação de perfil, que pode vazar informações sobre o host.
personality Impeça que o contêiner habilite a emulação BSD. Não é inerentemente perigoso, mas mal testado, com potencial de vulnerabilidades no kernel.
pivot_root Negar pivot_root, deve ser uma operação privilegiada.
process_vm_readv Restrinja as capacidades de inspeção de processos, já bloqueadas pela remoção CAP_SYS_PTRACE.
process_vm_writev Restrinja as capacidades de inspeção de processos, já bloqueadas pela remoção CAP_SYS_PTRACE.
ptrace Syscall para rastreamento/perfilação. Bloqueado nas versões do kernel Linux anteriores à 4.8 para evitar o desvio do seccomp. O rastreamento/criação de perfis de processos arbitrários já está bloqueado ao descartar CAP_SYS_PTRACE, porque pode vazar informações sobre o host.
query_module Negar manipulação e funções em módulos do kernel. Obsoleto.
quotactl Syscall de cota que pode permitir que os contêineres desativem seus próprios limites de recursos ou processem a contabilidade. Também controlado por CAP_SYS_ADMIN.
reboot Não permita que os contêineres reiniciem o host. Também controlado por CAP_SYS_BOOT.
request_key Impeça que os contêineres usem o conjunto de chaves do kernel, que não é namespaced.
set_mempolicy Syscall que modifica a memória do kernel e as configurações de NUMA. Já fechado por CAP_SYS_NICE.
setns Negar a associação de um thread a um namespace. Também controlado por CAP_SYS_ADMIN.
settimeofday Hora/data não estão num namespace. Também controlado por CAP_SYS_TIME.
stime Hora/data não estão num namespace. Também controlado por CAP_SYS_TIME.
swapon Recusar o início/fim da troca para ficheiro/dispositivo. Também controlado por CAP_SYS_ADMIN.
swapoff Recusar o início/fim da troca para ficheiro/dispositivo. Também controlado por CAP_SYS_ADMIN.
sysfs Syscall obsoleto.
_sysctl Obsoleto, substituído por /proc/sys.
umount Deve ser uma operação privilegiada. Também controlado por CAP_SYS_ADMIN.
umount2 Deve ser uma operação privilegiada. Também controlado por CAP_SYS_ADMIN.
unshare Negar a clonagem de novos namespaces para processos. Também controlado por CAP_SYS_ADMIN, com exceção de unshare --user.
uselib Antigo syscall relacionado a bibliotecas partilhadas, não usado há muito tempo.
userfaultfd O tratamento de falhas de página no espaço do utilizador é amplamente necessário para a migração de processos.
ustat Syscall obsoleto.
vm86 Modo real do kernel x86 em máquina virtual. Também controlado por CAP_SYS_ADMIN.
vm86old Modo real do kernel x86 em máquina virtual. Também controlado por CAP_SYS_ADMIN.

Próximos passos

Para obter as práticas recomendadas associadas, consulte Práticas recomendadas para segurança de cluster e atualizações no AKS e Práticas recomendadas para segurança de pod no AKS.