Práticas recomendadas de segurança para tarefas e contêineres do Amazon ECS - Amazon Elastic Container Service

Práticas recomendadas de segurança para tarefas e contêineres do Amazon ECS

Você deve considerar a imagem do contêiner como sua primeira linha de defesa contra um ataque. Uma imagem insegura e mal construída pode permitir que um invasor escape dos limites do contêiner e tenha acesso ao host. Você deve fazer o seguinte para reduzir o risco de isso acontecer.

Recomendamos fazer o seguinte ao configurar suas tarefas e contêineres.

Criar imagens mínimas ou usar imagens sem distribuição

Comece removendo todos os binários estranhos da imagem do contêiner. Se você estiver usando uma imagem desconhecida da Galeria Pública do Amazon ECR, inspecione a imagem para fazer referência ao conteúdo de cada uma das camadas do contêiner. É possível usar uma aplicação como o Dive para fazer isso.

Como alternativa, é possível usar imagens sem distribuição que incluam apenas sua aplicação e suas dependências de runtime. Elas não contêm gerenciadores de pacotes ou shells. Imagens sem distribuição melhoram a “relação sinal/ruído dos scanners e reduzem a carga de estabelecer a proveniência exatamente do que você precisa”. Para obter mais informações, consulte a documentação do GitHub sobre sem distribuição.

O Docker tem um mecanismo para a criação de imagens a partir de uma imagem mínima reservada conhecida como rascunho. Para obter mais informações, consulte Criação de uma imagem principal simples com o uso de rascunho na documentação do Docker. Com linguagens como Go, é possível criar um binário vinculado estático e referenciá-lo em seu Dockerfile. O exemplo a seguir mostra como fazer isso.

############################ # STEP 1 build executable binary ############################ FROM golang:alpine AS builder # Install git. # Git is required for fetching the dependencies. RUN apk update && apk add --no-cache git WORKDIR $GOPATH/src/mypackage/myapp/ COPY . . # Fetch dependencies. # Using go get. RUN go get -d -v # Build the binary. RUN go build -o /go/bin/hello ############################ # STEP 2 build a small image ############################ FROM scratch # Copy our static executable. COPY --from=builder /go/bin/hello /go/bin/hello # Run the hello binary. ENTRYPOINT ["/go/bin/hello"] This creates a container image that consists of your application and nothing else, making it extremely secure.

O exemplo anterior também é um exemplo de uma compilação em vários estágios. Esses tipos de compilações são atraentes do ponto de vista da segurança, pois podem ser usadas para minimizar o tamanho da imagem final enviada ao seu registro de contêiner. Imagens de contêiner sem ferramentas de criação e outros binários estranhos melhoram sua postura de segurança ao reduzir a superfície de ataque da imagem. Para obter mais informações sobre compilações de vários estágios, consulte criação de compilações de vários estágios.

Verifique suas imagens em busca de vulnerabilidades

De forma semelhante às de máquinas virtuais, as imagens de contêiner podem conter binários e bibliotecas de aplicações com vulnerabilidades ou desenvolver vulnerabilidades ao longo do tempo. A melhor maneira de se proteger contra ataques é verificar regularmente suas imagens com um verificador de imagens.

As imagens armazenadas no Amazon ECR podem ser verificadas por push ou sob demanda (uma vez a cada 24 horas). A verificação básica do Amazon ECR usa o Clair, uma solução de verificação de imagens de código aberto. A verificação aprimorada do Amazon ECR usa o Amazon Inspector. Depois que uma imagem é verificada, os resultados são registrados em log no fluxo de eventos do Amazon ECR no Amazon EventBridge. Você também pode ver os resultados de uma verificação no console do Amazon ECR ou chamando a API DescribeImageScanFindings. Imagens com uma vulnerabilidade HIGH ou CRITICAL devem ser excluídas ou recompiladas. Se uma imagem que foi implantada desenvolver uma vulnerabilidade, ela deverá ser substituída assim que possível.

O Docker Desktop Edge versão 2.3.6.0 ou posterior pode varrer imagens locais. As varreduras são executadas pelo Snyk, um serviço de segurança de aplicações. Quando as vulnerabilidades são descobertas, o Snyk identifica as camadas e as dependências com a vulnerabilidade no Dockerfile. Ele também recomenda alternativas seguras, como o uso de uma imagem base mais fina com menos vulnerabilidades ou atualizar um pacote específico para uma versão mais recente. Ao usar a varredura do Docker, os desenvolvedores podem resolver possíveis problemas de segurança antes de enviar suas imagens para o registro.

Remover permissões especiais de suas imagens

Os sinalizadores de direitos de acesso setuid e setgid permitem a execução um executável com as permissões do proprietário ou do grupo do executável. Remova todos os binários com esses direitos de acesso da sua imagem, pois esses binários podem ser usados para aumentar os privilégios. Considere remover todos os shells e utilitários como o nc e o curl que possam ser usados para fins maliciosos. É possível encontrar os arquivos com direitos de acesso setuid e setgid usando o comando a seguir.

find / -perm /6000 -type f -exec ls -ld {} \;

Para remover essas permissões especiais desses arquivos, adicione a diretiva a seguir à imagem do contêiner.

RUN find / -xdev -perm /6000 -type f -exec chmod a-s {} \; || true

Criar um conjunto de imagens selecionadas

Em vez de permitir que os desenvolvedores criem suas próprias imagens, crie um conjunto de imagens verificadas para as diferentes pilhas de aplicações em sua organização. Ao fazer isso, os desenvolvedores podem prescindir de aprender a compor Dockerfiles e se concentrar em escrever código. À medida que as alterações são mescladas em sua base de código, um pipeline de CI/CD pode compilar automaticamente o ativo e depois armazená-lo em um repositório de artefatos. E, por último, copie o artefato na imagem apropriada antes de enviá-lo a um registro do Docker, como o Amazon ECR. No mínimo, você deve criar um conjunto de imagens básicas a partir das quais os desenvolvedores possam criar seus próprios Dockerfiles. Evite extrair imagens do Docker Hub. Você nem sempre sabe o que está na imagem, e cerca de um quinto das 1000 imagens principais apresentam vulnerabilidades. Uma lista dessas imagens e suas vulnerabilidades pode ser encontrada em https://vulnerablecontainers.org/.

Varrer pacotes de aplicações e bibliotecas em busca de vulnerabilidades

O uso de bibliotecas de código aberto agora é comum. Assim como acontece com sistemas operacionais e pacotes de sistema operacional, essas bibliotecas podem ter vulnerabilidades. Como parte do ciclo de vida de desenvolvimento, essas bibliotecas devem ser varridas e atualizadas quando vulnerabilidades críticas forem encontradas.

O Docker Desktop executa varreduras locais usando o Snyk. Ele também pode ser usado para encontrar vulnerabilidades e possíveis problemas de licenciamento em bibliotecas de código aberto. Ele pode ser integrado diretamente aos fluxos de trabalho do desenvolvedor, oferecendo a capacidade de mitigar os riscos apresentados pelas bibliotecas de código aberto. Para obter mais informações, consulte os tópicos a seguir.

Executar análise estática de código

Você deve realizar uma análise estática de código antes de criar uma imagem de contêiner. Ela é executada em seu código-fonte e é usada para identificar erros de codificação e códigos que possam ser explorados por um agente mal-intencionado, como injeções de falhas. Você pode usar o Amazon Inspector. Para obter mais informações, consulte Verificação de imagens de contêiner do Amazon ECR com o Amazon Inspector no Guia do usuário do Amazon Inspector.

Executar contêineres como um usuário não raiz

Você deve executar contêineres como um usuário não raiz. Por padrão, os contêineres são executados como o usuário root, a menos que a diretiva USER esteja incluída em seu Dockerfile. Os recursos padrão do Linux atribuídos pelo Docker restringem as ações que podem ser executadas como root, mas apenas marginalmente. Por exemplo, um contêiner em execução como root ainda não tem permissão para acessar dispositivos.

Como parte do seu pipeline de CI/CD, você deve executar lint nos Dockerfiles para procurar a diretiva USER e fazer falhar a compilação caso ela estiver ausente. Para obter mais informações, consulte os tópicos a seguir.

  • O Dockerfile-lint é uma ferramenta de código aberto da RedHat que pode ser usada para verificar se o arquivo está em conformidade com as práticas recomendadas.

  • O Hadolint é outra ferramenta para a compilação de imagens do Docker que está em conformidade com as práticas recomendadas.

Usar um sistema de arquivos raiz somente para leitura

Você deve usar um sistema de arquivos raiz somente para leitura. O sistema de arquivos raiz de um contêiner é gravável por padrão. Quando você configura um contêiner com um sistema de arquivos raiz RO (somente leitura), ele força você a definir explicitamente onde os dados podem ser persistidos. Isso reduz sua superfície de ataque, pois o sistema de arquivos do contêiner não pode ser gravado, a menos que as permissões sejam concedidas especificamente.

nota

Ter um sistema de arquivos raiz somente para leitura pode causar problemas com determinados pacotes de sistema operacional que esperam poder gravar no sistema de arquivos. Se você planeja usar sistemas de arquivos raiz somente para leitura, faça um teste minucioso com antecedência.

Configurar tarefas com limites de CPU e memória (Amazon EC2)

Você deve configurar tarefas com limites de CPU e memória para minimizar o risco a seguir. Os limites de recursos de uma tarefa definem um limite superior para a quantidade de CPU e memória que pode ser reservada por todos os contêineres em uma tarefa. Se nenhum limite for definido, as tarefas terão acesso à CPU e à memória do host. Isso pode causar problemas em que tarefas implantadas em um host compartilhado podem privar outras tarefas de recursos do sistema.

nota

O Amazon ECS, em tarefas do AWS Fargate, exige que você especifique limites de CPU e memória, pois ele usa esses valores para fins de cobrança. Uma tarefa que consuma todos os recursos do sistema não é um problema para o Amazon ECS Fargate, pois cada tarefa é executada em sua própria instância dedicada. Se você não especificar um limite de memória, o Amazon ECS alocará um mínimo de 4 MB para cada contêiner. Da mesma forma, se nenhum limite de CPU for definido para a tarefa, o agente de contêiner do Amazon ECS atribuirá a ela um mínimo de 2 CPUs.

Usar tags imutáveis com o Amazon ECR

Com o Amazon ECR, é possível e deve usar imagens de configuração com tags imutáveis. Isso evita enviar uma versão alterada ou atualizada de uma imagem para o seu repositório de imagens com uma tag idêntica. Isso protege contra um invasor que faça push de uma versão comprometida de uma imagem sobre a sua imagem com a mesma tag. Ao usar tags imutáveis, você efetivamente se força a enviar uma nova imagem com uma tag diferente para cada alteração.

Evitar executar contêineres como privilegiados (Amazon EC2)

Você deve evitar executar contêineres como privilegiados. Para o segundo plano, contêineres executados como privileged são executados com privilégios estendidos no host. Isso significa que o contêiner herda todos os recursos do Linux atribuídos a root no host. Seu uso deve ser severamente restrito ou proibido. Recomendamos definir a variável de ambiente ECS_DISABLE_PRIVILEGED do agente de contêiner do Amazon ECS como true, para evitar que os contêineres sejam executados como privileged em determinados hosts, caso o privileged não seja necessário. Como alternativa, é possível usar AWS Lambda para varrer suas definições de tarefas para o uso do parâmetro privileged.

nota

Não há suporte para a execução de um contêiner como privileged no o Amazon ECS no AWS Fargate.

Remover recursos desnecessários do Linux do contêiner

A seguir há uma lista dos recursos padrão do Linux atribuídos aos contêineres do Docker. Para obter mais informações sobre cada recurso, consulte Visão geral dos recursos do Linux.

CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_FOWNER, CAP_FSETID, CAP_KILL, CAP_SETGID, CAP_SETUID, CAP_SETPCAP, CAP_NET_BIND_SERVICE, CAP_NET_RAW, CAP_SYS_CHROOT, CAP_MKNOD, CAP_AUDIT_WRITE, CAP_SETFCAP

Se um contêiner não exigir todos os recursos do kernel do Docker listados acima, considere retirá-los do contêiner. Para obter mais informações sobre cada recurso de kernel do Docker, consulte KernelCapabilities. É possível descobrir quais recursos estão em uso fazendo o seguinte:

  • Instale o pacote do sistema operacional libcap-ng e execute o utilitário pscap para listar os recursos que cada processo está usando.

  • Você também pode usar o capsh para decifrar quais recursos um processo está usando.

Usar uma chave gerenciada pelo cliente (CMK) para criptografar imagens enviadas ao Amazon ECR.

Você deve usar uma chave gerenciada pelo cliente (CMK) para criptografar imagens enviadas ao Amazon ECR. As imagens enviadas para o Amazon ECR são automaticamente criptografadas em repouso com uma chave gerenciada AWS Key Management Service (AWS KMS). Se você preferir usar sua própria chave, o Amazon ECR agora oferece suporte à criptografia do AWS KMS com chaves gerenciadas pelo cliente (CMK). Antes de habilitar a criptografia do lado do servidor com uma CMK, revise as considerações listadas na documentação sobre criptografia em repouso.