컨테이너 이미지에서 비밀 정보 제외하기

DockerBeginner
지금 연습하기

소개

컨테이너 이미지에서 제거한 파일이 이전 이미지 계층에는 여전히 남아 있을 수 있습니다. Git 무시 규칙도 Docker가 빌드 중에 받는 내용을 제어하지 않습니다.

준비된 이미지를 조사하고, 빌드 입력을 제한하며, 새 이미지의 모든 계층을 검증합니다. 작업자와 Docker 작업 흐름은 이전 실습을 따릅니다. 모든 자격 증명은 가상의 로컬 테스트 데이터이며 캐시된 기본 이미지와 확인 도우미가 준비되어 있습니다.

준비된 빌드 입력 확인하기

이 단계에서는 소스 관리 무시 규칙과 Docker 빌드 입력을 구분합니다.

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

ls -a는 점으로 시작하는 파일도 표시합니다. 이 프로젝트에는 작업자, 공개 설정, 입력/출력 디렉터리, private.env, debug.txt가 있습니다. 마지막 두 파일은 전달 파일이 아니라 비공개 로컬 입력입니다.

cat .gitignore

Git은 비공개 파일 이름 두 개를 무시합니다. 이는 Docker 빌드 컨텍스트가 아니라 Git의 추적 작업 흐름에 영향을 줍니다.

cat .dockerignore

파일은 현재 비어 있습니다. **.dockerignore**는 Docker가 빌드 컨텍스트를 받을 때 제외할 경로를 제어합니다. Git에서 무시되는 파일도 Docker 빌드에 전송될 수 있습니다.

cat Dockerfile

COPY . /app/는 사용 가능한 컨텍스트 전체를 복사합니다. 이후의 RUN rm ...은 최종 파일 시스템에서 비공개 파일을 제거하지만 이전 이미지 계층을 되돌리지는 않습니다.

계층에 숨은 복사본 찾기

이 단계에서는 최종 파일 시스템과 저장된 이미지 계층을 비교합니다.

준비된 기존 태그 ticket-image:legacy는 이 Dockerfile에서 빌드되었습니다. 일회성 확인 컨테이너를 실행하세요. --rm은 ls가 끝난 뒤 이 임시 컨테이너를 자동으로 제거합니다. 지정한 명령은 이미지의 기본 작업자 시작 명령 대신 실행됩니다.

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

최종 /app에는 private.env나 debug.txt가 표시되지 않아야 합니다. 작업자와 공개 설정은 여전히 포함되어 있습니다.

docker history는 이미지 빌드 지시문을 보여줍니다. --no-trunc는 지시문 텍스트 전체를 유지합니다.

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

넓은 범위의 복사 다음에 제거가 있는지 찾으세요. 이력은 순서를 설명하지만 모든 파일의 내용을 보여주지는 않습니다. 준비된 course-image-scan 도우미는 이 실제 이미지를 저장하고 저장된 모든 계층과 이미지 설정을 읽습니다.

sudo course-image-scan ticket-image:legacy

이전 계층의 비공개 파일 이름과 값이 가려진 대상 연습용 자격 증명이 탐지되어야 합니다. 종료 코드 1은 탐지 결과가 있음을, 2 또는 CHECK ERROR는 확인 실패를 의미합니다. 도우미의 고정 범위는 나열된 비공개 파일 이름과 이 가짜 자격 증명이며, 완전한 운영 환경용 비밀 정보 검사기가 아닙니다.

나중 계층의 삭제는 이전 바이트를 지우지 않습니다. 따라서 최종 파일 시스템의 ls를 통과하는 것만으로는 충분하지 않습니다.

비공개 빌드 입력 제외하기

이 단계에서는 로컬 비공개 파일을 유지하면서 Docker 컨텍스트에서 제외합니다.

nano .dockerignore

다음 전체 파일을 사용하세요.

private.env
debug.txt
input/
output/

각 줄은 제외할 경로나 디렉터리입니다. 이 패턴들은 비공개 설정, 디버그 자료, 실행 시 데이터를 빌드 입력에서 제거합니다. 작업자와 config.public은 계속 사용할 수 있습니다.

Ctrl+O, Enter로 저장하고 Ctrl+X로 종료하세요. 로컬 비공개 파일을 삭제하지 마세요. 경로를 무시하는 것은 포함 범위를 제한해야 하는 것이지 로컬 설정을 없애는 것이 아닙니다.

Dockerfile 복사 범위 제한하기

이 단계에서는 이미지에 필요한 입력을 명시적으로 지정합니다.

이전 삭제 지시문은 이제 불필요하며 제외된 파일을 사용할 수 없으므로 실패하게 됩니다. Dockerfile을 여세요.

nano Dockerfile

다음 전체 파일을 사용하세요.

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/는 필요한 업무 파일 두 개만 나열합니다. 이전 실습의 USER nobody와 원래 시작 명령을 유지하세요. Ctrl+O, Enter, Ctrl+X로 저장하세요.

두 제어 방법은 함께 동작합니다. .dockerignore는 사용 가능한 빌드 입력을 제한하고, 명시적인 COPY는 이 이미지에 포함되는 내용을 제한합니다. 어느 쪽도 비밀 정보가 계층에 들어간 후 삭제하는 데 의존하지 않습니다.

새 산출물 빌드하고 확인하기

이 단계에서는 기존 증거의 의미를 바꾸는 대신 새로 빌드한 전달용 이미지를 확인합니다.

sudo docker build -t ticket-image:delivery .

로컬 빌드가 성공해야 합니다. 새 태그는 ticket-image:legacy와 구별됩니다.

sudo course-image-scan ticket-image:delivery

저장된 모든 계층과 이미지 설정에 대해 PASS가 예상됩니다. 이 특정 대상에 대한 결과는 가능한 모든 비밀 정보나 취약점을 탐지했다는 주장이 아닙니다.

이제 컨텍스트를 독립적으로 확인하세요.

sudo course-context-check .

준비된 이 도우미는 고정된 COPY . 점검으로 임시 이미지를 빌드하고, 동일한 실제 계층 검사를 적용한 다음 임시 이미지를 제거합니다. PASS가 예상됩니다. 이는 비공개 파일이 전달용 COPY의 좁은 범위에서 빠졌을 뿐인 것이 아니라 컨텍스트에서 제외되었음을 보여줍니다.

기존 이미지에는 원래 탐지 결과가 여전히 있을 수 있습니다. 깨끗한 전달용 산출물을 다시 빌드해도 이전에 배포한 이미지가 다시 작성되거나 유출된 자격 증명이 폐기되지는 않습니다. 실제 노출에는 앞서 배운 자격 증명 교체 절차와 이전 복사본의 적절한 정리가 필요합니다. 여기서 대상 토큰은 의도적인 가짜이며, 통과 기준은 새 전달용 이미지에 관한 것입니다.

새 이미지에서 원래 보고 작업 실행하기

이 단계에서는 비공개 빌드 입력을 제거한 뒤에도 작업자에게 필요한 파일과 동작이 유지되었음을 입증합니다.

출력 디렉터리는 이미 UID 65534 소유이며 접근 범위가 제한된 쓰기 권한이 있습니다. 이전 실습의 비 root 작업자와 바인드 마운트 작업 흐름을 다시 사용하세요.

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

65534가 예상됩니다.

sudo docker logs ticket-image-worker

mode=report와 tickets=2가 예상됩니다. 첫 줄은 필요한 공개 설정에서 오고, 두 번째 줄은 원래 입력을 읽고 실제 보고서를 쓰는 데서 나옵니다.

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

tickets=2가 예상됩니다. 작업자는 여전히 읽기 전용 입력과 쓰기 가능한 출력을 사용하며 이미지 안에 비공개 설정은 필요하지 않습니다.

로컬 원본과 전달 증거 확인하기

이 단계에서는 로컬 비공개 입력과 안전한 전달용 산출물을 모두 그대로 유지한 상태로 마무리합니다.

내용을 출력하지 않고 비공개 원본 파일을 나열하세요.

ls -l private.env debug.txt

두 파일 모두 로컬에 계속 존재해야 합니다. 삭제하면 의도한 빌드 경계 연습을 우회하게 됩니다.

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

전달용 이미지 검사가 통과하고 ticket-image-worker가 실행 중이어야 합니다. 교육 과정의 검증은 실제 빌드 컨텍스트도 점검하고, 실행 중인 이미지 ID를 확인하며, 원래 보고서를 검증합니다. 별도로 작성하여 제출할 조사 파일은 없습니다.

요약

실제 Docker 빌드 입력을 제한하고, 필요한 업무 파일만 복사했으며, 저장된 모든 계층과 이미지 설정을 확인하고, 기존 비 root 작업자를 유지했습니다. 최종 파일 시스템이 깨끗하다는 사실만으로는 이 경계를 입증할 수 없었습니다.