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).

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 contextos de segurança de pod Kubernetes internos para definir mais permissões, como o usuário ou grupo a ser executado como, os recursos do Linux a serem expostos ou a configuração allowPrivilegeEscalation: false no manifesto do pod. Para obter mais práticas recomendadas, consulte Proteger o acesso do pod aos recursos.

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 recursos por meio de um manifesto de pod.

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

Nota

Atualmente, os ambientes Kubernetes não são completamente seguros para uso multilocatário hostil. Recursos de segurança adicionais, como Microsoft Defender for Containers, AppArmor, seccomp, Pod Security Admission ou Kubernetes RBAC para nós, 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 do Kubernetes torna-se o cluster inteiro, não um nó individual.

Para esses tipos de cargas de trabalho multilocatárias hostis, você deve usar clusters fisicamente isolados.

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ários /proc locais /sys e fornecem um meio de isolar logicamente os contêineres do nó subjacente. O AppArmor funciona para qualquer aplicativo executado em Linux, não apenas para pods Kubernetes.

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 ao nível do processo. Seccomp também é um módulo de segurança do kernel Linux e é suportado containerd nativamente pelo tempo de execução usado pelos 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 (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 syscall 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

Os recursos de visualização do AKS estão disponíveis em uma base de autosserviço e opt-in. 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 visualizações do AKS são parcialmente cobertas pelo suporte ao cliente com base no melhor esforço. 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:

Registrar o sinalizador de KubeletDefaultSeccompProfilePreview recurso

  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 status refletir Registrado, atualize o registro do provedor de recursos Microsoft.ContainerService usando o az provider register comando.

    az provider register --namespace Microsoft.ContainerService
    

Restrinja as chamadas do sistema do seu contêiner 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. Syscalls restritos falharão. Para obter mais informações, consulte o perfil 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. 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 syscalls bloqueadas. Se tiver ocorrido uma falha na carga de trabalho, poderá ver erros como:

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

Configurar um perfil seccomp personalizado

Com um perfil seccomp personalizado, você pode ter um controle mais granular sobre syscalls restritos. Alinhe-se à prática recomendada de conceder permissão mínima ao contêiner apenas para ser executado por:

  • Definir com filtros quais ações permitir ou negar.
  • Anotação dentro de um manifesto YAML 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
    

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 containerD para nosso RuntimeDefault quando você configura seccomp usando a configuração de nó personalizada.

Syscalls 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 syscalls bloqueadas for exigida pela sua carga de trabalho, não use o RuntimeDefault perfil 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 a esta lista podem causar falha na carga de trabalho. Para atualizações de versão, consulte as notas de versão do AKS.

Syscall bloqueado Description
acct Syscall de contabilidade que pode permitir que os contêineres desativem seus próprios limites de recursos ou processem a contabilidade. Também fechado 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á fechado pelo CAP_SYS_ADMIN.
clock_adjtime Hora/data não é namespaced. Também fechado por CAP_SYS_TIME.
clock_settime Hora/data não é namespaced. Também fechado por CAP_SYS_TIME.
clone Negar clonagem de novos namespaces. Também fechado 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 fechado por CAP_SYS_MODULE.
delete_module Negar manipulação e funções em módulos do kernel. Também fechado por CAP_SYS_MODULE.
finit_module Negar manipulação e funções em módulos do 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 de NUMA. Já fechado por CAP_SYS_NICE.
init_module Negar manipulação e funções em módulos do kernel. Também fechado 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 os recursos de inspeção de processos, já bloqueados pela queda 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 Negar o carregamento de um novo kernel para execução posterior. Também fechado 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/criação de perfil, que pode vazar informações sobre o host. Também fechado 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á fechado 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 fechado por CAP_DAC_READ_SEARCH.
perf_event_open Syscall de rastreamento/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, potencial para vulns kernel.
pivot_root Negar pivot_root, deve ser operação privilegiada.
process_vm_readv Restrinja os recursos de inspeção de processos, já bloqueados pela queda CAP_SYS_PTRACE.
process_vm_writev Restrinja os recursos de inspeção de processos, já bloqueados pela queda CAP_SYS_PTRACE.
ptrace Syscall de rastreamento/criação de perfil. 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 fechado por CAP_SYS_ADMIN.
reboot Não permita que os contêineres reiniciem o host. Também fechado 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 fechado por CAP_SYS_ADMIN.
settimeofday Hora/data não é namespaced. Também fechado por CAP_SYS_TIME.
stime Hora/data não é namespaced. Também fechado por CAP_SYS_TIME.
swapon Negar iniciar/parar a troca para arquivo/dispositivo. Também fechado por CAP_SYS_ADMIN.
swapoff Negar iniciar/parar a troca para arquivo/dispositivo. Também fechado por CAP_SYS_ADMIN.
sysfs Syscall obsoleto.
_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 Syscall mais antigo relacionado a bibliotecas compartilhadas, sem uso há muito tempo.
userfaultfd Tratamento de falhas de página de espaço de usuário, amplamente necessário para a migração de processos.
ustat Syscall obsoleto.
vm86 No kernel x86 máquina virtual de modo real. Também fechado por CAP_SYS_ADMIN.
vm86old No kernel x86 máquina virtual de modo real. Também fechado 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.