Compartilhar via


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.

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

Perfis de AppArmor em uso em um cluster do AKS para limitar as 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. Conecte-se por SSH a um nó do 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,
    }
    

Perfis de AppArmor são adicionados usando o comando apparmor_parser.

  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 corretamente e aplicado ao AppArmor, você não verá nenhuma saída e retornará ao prompt de comando.

  3. 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" ]
    
  4. 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

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

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

    Demora alguns minutos para o status exibir Registrado.

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

    az feature show --namespace "Microsoft.ContainerService" --name "KubeletDefaultSeccompProfilePreview"
    
  3. 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.

  1. Conecte-se por SSH a um nó do AKS.

  2. Crie um filtro de 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. 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
    
  5. Implante o pod de exemplo usando o comando kubectl apply:

    kubectl apply -f ./aks-seccomp.yaml
    
  6. 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.