[security] 도커 및 보안 비밀번호

나는 최근에 Docker를 사용하여 놀 수있는 서비스를 구축하는 것을 실험 해 왔으며 계속 잔소리하는 것이 Dockerfile에 암호를 넣고 있습니다. 나는 개발자이므로 소스에 암호를 저장하면 얼굴이 펀치처럼 느껴집니다. 이것이 문제가되어야합니까? Dockerfile에서 비밀번호를 처리하는 방법에 대한 좋은 규칙이 있습니까?



답변

확실히 걱정입니다. Dockerfile은 일반적으로 리포지토리에 체크인되어 다른 사람들과 공유됩니다. 대안은 런타임시 환경 변수로 모든 신임 정보 (사용자 이름, 비밀번호, 토큰, 민감한 것)를 제공하는 것 입니다. 이것은 -e인수 (CLI의 개별 변수의 경우) 또는 --env-file인수 (파일의 여러 변수의 경우)를 통해 가능 docker run합니다. docker-compose와 함께 환경을 사용하려면 이것을 읽으십시오 .

사용 --env-file하는 ps경우 로그 또는 로그 에 표시되는 비밀로부터 보호하기 때문에 사용하는 것이 더 안전한 옵션 set -x입니다.

그러나 환경 변수는 특히 안전하지 않습니다. 이들은를 통해 볼 수 docker inspect있으므로 docker명령 을 실행할 수있는 모든 사용자가 사용할 수 있습니다 . (물론 docker호스트에서 액세스 할 수있는 모든 사용자 어쨌든 루트가지고 있습니다.)

내가 선호하는 패턴은 래퍼 스크립트를 ENTRYPOINT또는 로 사용하는 것 CMD입니다. 랩퍼 스크립트는 먼저 런타임시 외부 위치에서 컨테이너로 비밀을 가져온 다음 애플리케이션을 실행하여 비밀을 제공 할 수 있습니다. 이것의 정확한 메커니즘은 런타임 환경에 따라 다릅니다. AWS에서는 IAM 역할, 키 관리 서비스 및 S3 의 조합을 사용하여 암호화 된 비밀을 S3 버킷에 저장할 수 있습니다. HashiCorp Vault 또는 credstash 와 같은 것이 또 다른 옵션입니다.

AFAIK는 빌드 프로세스의 일부로 중요한 데이터를 사용하기위한 최적의 패턴이 없습니다. 사실, 나는 이 주제에 대한 SO 질문 이 있습니다. docker-squash 를 사용 하여 이미지에서 레이어를 제거 할 수 있습니다 . 그러나이 목적을 위해 Docker에는 기본 기능이 없습니다.

컨테이너의 구성에 대한 수줍음 설명이 유용 할 수 있습니다.


답변

Google 팀은 리포지토리에 자격 증명을 넣지 않기 때문에에 허용되지 않습니다 Dockerfile. 응용 프로그램 내에서 우리의 모범 사례는 환경 변수의 cred를 사용하는 것입니다.

우리는 이것을 사용하여 해결합니다 docker-compose.

docker-compose.yml에서 컨테이너의 환경 변수가 포함 된 파일을 지정할 수 있습니다.

 env_file:
- .env

반드시 추가 할 수 있도록 .env하기 위해 .gitignore, 다음 내 자격 증명 설정 .env등의 파일을 :

SOME_USERNAME=myUser
SOME_PWD_VAR=myPwd

.env파일을 로컬 또는 팀의 다른 팀이 확보 할 수있는 안전한 위치에 저장하십시오 .

참조 : https://docs.docker.com/compose/environment-variables/#/the-env-file


답변

Docker now (버전 1.13 또는 17.06 이상)는 비밀 정보 관리를 지원합니다. 여기의 개요 및 자세한 설명서

비슷한 기능의 존재 는 KubernetesDCOS


답변

이미지를 다운로드 할 수있는 사람에게 자격 증명을 브로드 캐스트하지 않는 한 컨테이너에 자격 증명을 추가해서는 안됩니다. 특히 creds 파일이 중간 파일 시스템 계층의 최종 이미지에 남아 있기 때문에 ADD credsand 이후의 작업 RUN rm creds은 안전하지 않습니다. 이미지에 액세스 할 수있는 사람이라면 누구나 쉽게 추출 할 수 있습니다.

종속성을 체크 아웃하기 위해 cred가 필요할 때 본 전형적인 솔루션은 컨테이너를 사용하여 다른 컨테이너를 만드는 것입니다. 즉, 일반적으로 기본 컨테이너에 빌드 환경이 있으며 앱 컨테이너를 빌드하려면 해당 환경을 호출해야합니다. 따라서 간단한 해결책은 앱 소스를 추가 한 다음 RUN빌드 명령 을 추가하는 것 입니다. 만약 당신이 그 안에 신념이 필요하다면 이것은 안전하지 않습니다 RUN. 대신 로컬 소스에 소스를 넣고 docker run컨테이너 에서 (와 같이 ) 로컬 소스 디렉토리를 볼륨으로 마운트하고 creds를 다른 볼륨으로 주입하거나 마운트하여 빌드 단계를 수행하십시오. 빌드 단계가 완료되면 ADD이제 빌드 된 아티팩트가 포함 된 로컬 소스 디렉토리를 간단히 보내 최종 컨테이너를 빌드하십시오 .

Docker 가이 모든 것을 단순화하기 위해 몇 가지 기능을 추가하기를 희망합니다!

업데이트 : 앞으로 메소드가 중첩 된 빌드를 갖는 것처럼 보입니다. 간단히 말해서, dockerfile은 런타임 환경을 구축하는 데 사용되는 첫 번째 컨테이너와 모든 컨테이너를 최종 컨테이너에 조립할 수있는 두 번째 중첩 컨테이너 빌드를 설명합니다. 이렇게하면 빌드 타임이 두 번째 컨테이너에 없습니다. 앱을 빌드하는 데 JDK가 필요하지만 실행을 위해 JRE 만 필요한 Java 앱입니다. https://github.com/docker/docker/issues/7115 에서 시작 하여 대체 제안에 대한 링크 중 일부를 따르는 것이 가장 좋습니다 .


답변

환경 변수를 많이 사용하는 경우 혼란 스러울 수있는 환경 변수를 사용하는 대신 볼륨을 사용하여 호스트의 디렉토리를 컨테이너에서 액세스 할 수 있습니다.

모든 자격 증명을 해당 폴더에 파일로 저장하면 컨테이너가 파일을 읽고 원하는대로 사용할 수 있습니다.

예를 들면 다음과 같습니다.

$ echo "secret" > /root/configs/password.txt
$ docker run -v /root/configs:/cfg ...

In the Docker container:

# echo Password is `cat /cfg/password.txt`
Password is secret

많은 프로그램이 별도의 파일에서 자격 증명을 읽을 수 있으므로이 방법으로 프로그램을 파일 중 하나를 가리킬 수 있습니다.


답변

런타임 전용 솔루션

docker-compose는 비-스웜 모드 솔루션을 제공합니다 (v1.11부터 :
bind mounts를 사용하는 비밀 ).

비밀은 /run/secrets/docker-compose에 의해 아래 파일로 마운트됩니다 . 이렇게하면 빌드 타임에 /run/secrets/마운트되지 않으므로 런타임 (컨테이너 실행)에서는 문제가 해결되지만 빌드 타임 (이미지 빌드)에서는 문제 가 해결되지 않습니다. 또한이 동작은 docker-compose로 컨테이너를 실행하는 데 달려 있습니다.


예:

도커 파일

FROM alpine
RUN cat /run/secrets/password
CMD sleep inifinity

docker-compose.yml

version: '3.1'
services:
  app:
    build: .
    secrets:
      - password

secrets:
  password:
    file: password.txt

빌드하려면 다음을 실행하십시오.

docker-compose up -d

더 읽을 거리 :


답변

으로 도커 v1.9 개발자 당신은 사용할 수 ARG 명령 에 이미지에 명령 라인으로 전달 된 인수 가져 빌드 작업을 . 간단히 –build-arg 플래그를 사용하십시오 . 따라서 Dockerfile에 명시 적 암호 (또는 다른 합리적인 정보)를 유지하지 않고 즉시 전달할 수 있습니다.

출처 : https://docs.docker.com/engine/reference/commandline/build/ http://docs.docker.com/engine/reference/builder/#arg

예:

도커 파일

FROM busybox
ARG user
RUN echo "user is $user"

이미지 빌드 명령

docker build --build-arg user=capuccino -t test_arguments -f path/to/dockerfile .

빌드하는 동안 인쇄

$ docker build --build-arg user=capuccino -t test_arguments -f ./test_args.Dockerfile .

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM busybox
 ---> c51f86c28340
Step 2 : ARG user
 ---> Running in 43a4aa0e421d
 ---> f0359070fc8f
Removing intermediate container 43a4aa0e421d
Step 3 : RUN echo "user is $user"
 ---> Running in 4360fb10d46a
**user is capuccino**
 ---> 1408147c1cb9
Removing intermediate container 4360fb10d46a
Successfully built 1408147c1cb9

그것이 도움이되기를 바랍니다! 안녕.