Mantenha segredos fora das imagens de contêineres

DockerBeginner
Pratique Agora

Introdução

Um arquivo removido de uma imagem de contêiner ainda pode existir em uma camada anterior da imagem. As regras de exclusão do Git também não controlam o que o Docker recebe durante uma construção.

Você investigará uma imagem preparada, restringirá suas entradas de construção e verificará cada camada de uma nova imagem. O worker e o fluxo de Docker seguem o laboratório anterior. Todas as credenciais são dados fictícios de teste local; a base em cache e os auxiliares de inspeção estão preparados.

Inspecione as entradas de construção preparadas

Nesta etapa, você separará as regras de exclusão do controle de versão das entradas de construção do Docker.

cd /home/labex/project/ticket-image
ls -a

ls -a inclui arquivos cujos nomes começam com ponto. Este projeto contém o worker, a configuração pública, os diretórios de entrada/saída, private.env e debug.txt. Os dois últimos são entradas privadas locais, não arquivos de entrega.

cat .gitignore

O Git ignora os dois nomes privados. Isso afeta o fluxo de rastreamento do Git, não o contexto de construção do Docker.

cat .dockerignore

O arquivo está vazio atualmente. .dockerignore controla quais caminhos o Docker exclui ao receber o contexto de construção. Um arquivo pode ser ignorado pelo Git e ainda assim ser enviado a uma construção Docker.

cat Dockerfile

COPY . /app/ copia todo o contexto disponível. O RUN rm ... posterior remove os arquivos privados do sistema de arquivos final, mas não desfaz a camada anterior da imagem.

Encontre a cópia oculta na camada

Nesta etapa, você comparará o sistema de arquivos final com as camadas salvas da imagem.

A tag legada preparada ticket-image:legacy foi construída a partir deste Dockerfile. Execute um contêiner de inspeção pontual. --rm remove automaticamente este contêiner temporário após o término de ls; seu comando substitui a inicialização padrão do worker da imagem:

sudo docker run --rm ticket-image:legacy ls -a /app

O /app final não deve listar private.env nem debug.txt. Ele ainda contém o worker e a configuração pública.

docker history mostra as instruções de construção da imagem. --no-trunc mantém o texto completo das instruções:

sudo docker history --no-trunc ticket-image:legacy

Localize a cópia ampla seguida da remoção. O histórico explica a sequência, mas não o conteúdo de todos os arquivos. O auxiliar preparado course-image-scan salva esta imagem real e lê cada camada salva, além da configuração da imagem:

sudo course-image-scan ticket-image:legacy

Espere detecções que indiquem arquivos privados em uma camada anterior e uma credencial de prática alvo com o valor ocultado. O código de saída 1 significa detecções; 2 ou CHECK ERROR significa que a inspeção falhou. O escopo fixo do auxiliar são estes nomes privados listados e esta credencial falsa, não um scanner completo de segredos para produção.

Exclusões em camadas posteriores não apagam os bytes anteriores. Portanto, passar em um ls do sistema de arquivos final é insuficiente.

Exclua entradas privadas da construção

Nesta etapa, você manterá os arquivos privados locais e os excluirá do contexto do Docker.

nano .dockerignore

Use este arquivo completo:

private.env
debug.txt
input/
output/

Cada linha é um caminho ou diretório a excluir. Esses padrões removem a configuração privada, o material de depuração e os dados de execução das entradas de construção; o worker e config.public continuam disponíveis.

Salve com Ctrl+O, Enter e saia com Ctrl+X. Não exclua os arquivos privados locais. Ignorar um caminho deve limitar sua inclusão, não destruir a configuração local.

Limite o escopo de cópia do Dockerfile

Nesta etapa, você tornará explícitas as entradas necessárias à imagem.

A instrução antiga de exclusão agora é desnecessária e falharia porque os arquivos excluídos do contexto não estão disponíveis. Abra o Dockerfile:

nano Dockerfile

Use este arquivo completo:

FROM desklite-base:1.37.0
WORKDIR /app
COPY worker.sh config.public /app/
USER nobody
CMD ["sh", "/app/worker.sh"]

COPY worker.sh config.public /app/ lista apenas os dois arquivos de negócio necessários. Preserve USER nobody e o comando original de inicialização do laboratório anterior. Salve com Ctrl+O, Enter, Ctrl+X.

Os dois controles funcionam em conjunto: .dockerignore restringe as entradas disponíveis para construção, e o COPY explícito restringe o que esta imagem inclui. Nenhum deles depende de excluir um segredo depois de ele entrar em uma camada.

Construa e inspecione o novo artefato

Nesta etapa, você inspecionará uma imagem de entrega recém-construída em vez de alterar o significado das evidências antigas.

sudo docker build -t ticket-image:delivery .

Espere uma construção local bem-sucedida. A nova tag é distinta de ticket-image:legacy.

sudo course-image-scan ticket-image:delivery

Espere um PASS para cada camada salva e para a configuração da imagem. Esse resultado específico para o alvo não afirma que todos os segredos ou vulnerabilidades possíveis foram detectados.

Agora verifique o contexto de forma independente:

sudo course-context-check .

Este auxiliar preparado constrói uma imagem temporária com uma sondagem fixa de COPY ., aplica a mesma inspeção real de camadas e depois remove essa imagem temporária. Espere PASS. Isso demonstra que os arquivos privados foram excluídos do contexto, em vez de apenas omitidos pelo seu COPY de entrega mais restrito.

A imagem legada ainda pode conter a detecção original. Reconstruir um artefato de entrega sem esses dados não reescreve imagens já distribuídas nem revoga credenciais vazadas. Exposições reais exigem o processo de substituição de credenciais aprendido anteriormente e a remoção apropriada das cópias antigas. Aqui, o token alvo é deliberadamente falso, e a aceitação diz respeito à nova imagem de entrega.

Execute o relatório original a partir da nova imagem

Nesta etapa, você comprovará que remover as entradas privadas de construção preservou os arquivos e o comportamento necessários ao worker.

O diretório de saída já pertence ao UID 65534 e tem acesso privado de gravação. Reutilize o fluxo de worker não root e montagens bind do laboratório anterior:

sudo docker run -d --name ticket-image-worker --network none --mount type=bind,src=/home/labex/project/ticket-image/input,dst=/data/input,readonly --mount type=bind,src=/home/labex/project/ticket-image/output,dst=/data/output ticket-image:delivery
sudo docker exec ticket-image-worker id -u

Espere 65534.

sudo docker logs ticket-image-worker

Espere mode=report e tickets=2. A primeira linha vem da configuração pública necessária; a segunda vem da leitura da entrada original e da gravação do relatório real.

sudo docker exec ticket-image-worker cat /data/output/report.txt

Espere tickets=2. O worker continua com entrada somente leitura e saída gravável, sem precisar de configuração privada dentro da imagem.

Confirme as fontes locais e as evidências de entrega

Nesta etapa, você terminará com as entradas privadas locais e o artefato seguro de entrega intactos.

Liste os arquivos-fonte privados sem imprimir seu conteúdo:

ls -l private.env debug.txt

Ambos devem continuar existindo localmente. Excluí-los contornaria o exercício pretendido de restrição da construção.

sudo course-image-scan ticket-image:delivery
sudo docker ps

A varredura de entrega deve passar, e ticket-image-worker deve estar em execução. A verificação do curso também sonda o contexto real de construção, verifica o ID da imagem em execução e confere o relatório original. Não há um arquivo de investigação escrito separado para entregar.

Resumo

Você restringiu as entradas reais de construção do Docker, copiou apenas os arquivos de negócio necessários, inspecionou todas as camadas salvas e a configuração da imagem e preservou o worker original não root. Um sistema de arquivos final sem os arquivos privados, por si só, não teria comprovado essa restrição.