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
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
############################ # 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 em vários estágios, consulte Compilações em 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 ClairHIGH
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
-
Automatização da conformidade de imagens usando o Amazon ECR e o AWS Security Hub
explica como revelar informações de vulnerabilidade do Amazon ECR no AWS Security Hub e automatizar a remediação bloqueando o acesso a imagens vulneráveis.
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.
-
As Ferramentas de segurança de aplicações de código aberto
incluem uma lista de ferramentas para detectar vulnerabilidades em aplicações.
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:
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.