IT

도커 및 보안 비밀번호

lottoking 2020. 6. 27. 10:37
반응형

도커 및 보안 비밀번호


나는 최근에 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

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


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

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

Example:

Dockerfile

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

build image command

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

during the build it print

$ 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

Hope it helps! Bye.


run-time only solution

docker-compose also provides a non-swarm mode solution (since v1.11: Secrets using bind mounts).

The secrets are mounted as files below /run/secrets/ by docker-compose. This solves the problem at run-time (running the container), but not at build-time (building the image), because /run/secrets/ is not mounted at build-time. Furthermore this behavior depends on running the container with docker-compose.


Example:

Dockerfile

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

To build, execute:

docker-compose up -d

Further reading:


My approach seems to work, but is probably naive. Tell me why it is wrong.

ARGs set during docker build are exposed by the history subcommand, so no go there. However, when running a container, environment variables given in the run command are available to the container, but are not part of the image.

So, in the Dockerfile, do setup that does not involve secret data. Set a CMD of something like /root/finish.sh. In the run command, use environmental variables to send secret data into the container. finish.sh uses the variables essentially to finish build tasks.

To make managing the secret data easier, put it into a file that is loaded by docker run with the --env-file switch. Of course, keep the file secret. .gitignore and such.

For me, finish.sh runs a Python program. It checks to make sure it hasn't run before, then finishes the setup (e.g., copies the database name into Django's settings.py).


There is a new docker command[1] for "secrets" management, but that only works for swarm clusters.

docker service create
--name my-iis
--publish target=8000,port=8000
--secret src=homepage,target="\inetpub\wwwroot\index.html"
microsoft/iis:nanoserver 

[1]https://docs.docker.com/engine/swarm/secrets/


The 12-Factor app methodology tells, that any configuration should be stored in environment variables.

Docker compose could do variable substitution in configuration, so that could be used to pass passwords from host to docker.


While I totally agree there is no simple solution. There continues to be a single point of failure. Either the dockerfile, etcd, and so on. Apcera has a plan that looks like sidekick - dual authentication. In other words two container cannot talk unless there is a Apcera configuration rule. In their demo the uid/pwd was in the clear and could not be reused until the admin configured the linkage. For this to work, however, it probably meant patching Docker or at least the network plugin (if there is such a thing).

참고URL : https://stackoverflow.com/questions/22651647/docker-and-securing-passwords

반응형