도커 컨테이너 내에서 SSH 키 사용


324

git clone & git push 실행과 같은 Git을 사용하여 다양한 재미있는 물건을 실행하는 앱이 있으며도 커화하려고합니다.

컨테이너 'user'가 사용할 컨테이너에 SSH 키를 추가해야 할 때 문제가 발생했습니다.

에 복사하고 /root/.ssh/변경 $HOME하고 git ssh 래퍼를 만들 려고했지만 여전히 운이 없습니다.

다음은 참조 용 Dockerfile입니다.

#DOCKER-VERSION 0.3.4                                                           

from  ubuntu:12.04                                                              

RUN  apt-get update                                                             
RUN  apt-get install python-software-properties python g++ make git-core openssh-server -y
RUN  add-apt-repository ppa:chris-lea/node.js                                   
RUN  echo "deb http://archive.ubuntu.com/ubuntu precise universe" >> /etc/apt/sources.list
RUN  apt-get update                                                             
RUN  apt-get install nodejs -y                                                  

ADD . /src                                                                       
ADD ../../home/ubuntu/.ssh/id_rsa /root/.ssh/id_rsa                             
RUN   cd /src; npm install                                                      

EXPOSE  808:808                                                                 

CMD   [ "node", "/src/app.js"]

app.js git 명령을 다음과 같이 실행합니다 git pull


3
이 질문에 접근하는 사람은 최종 게임을 통해 보안 허점을 쉽게 만들 수 있다고 생각하고 조심하지 않으면 여기에서 잊어 버려야합니다. 모든 답을 읽고 현명하게 선택하십시오.
Josh Habdas

답변:


144

빌드시 SSH를 사용해야하는 경우 더 어려운 문제입니다. 예를 들어, 당신은 사용하는 경우 git clone, 또는 내 경우 pipnpm개인 저장소에서 다운로드.

내가 찾은 해결책은 --build-arg플래그를 사용하여 키를 추가하는 것 입니다. 그런 다음 새로운 실험 --squash명령 (1.13 추가)을 사용하여 레이어를 병합하여 제거 후 키를 더 이상 사용할 수 없게합니다. 내 해결책은 다음과 같습니다.

빌드 명령

$ docker build -t example --build-arg ssh_prv_key="$(cat ~/.ssh/id_rsa)" --build-arg ssh_pub_key="$(cat ~/.ssh/id_rsa.pub)" --squash .

도커 파일

FROM python:3.6-slim

ARG ssh_prv_key
ARG ssh_pub_key

RUN apt-get update && \
    apt-get install -y \
        git \
        openssh-server \
        libmysqlclient-dev

# Authorize SSH Host
RUN mkdir -p /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan github.com > /root/.ssh/known_hosts

# Add the keys and set permissions
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
    echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub && \
    chmod 600 /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa.pub

# Avoid cache purge by adding requirements first
ADD ./requirements.txt /app/requirements.txt

WORKDIR /app/

RUN pip install -r requirements.txt

# Remove SSH keys
RUN rm -rf /root/.ssh/

# Add the rest of the files
ADD . .

CMD python manage.py runserver

업데이트 : Docker 1.13을 사용하고 실험 기능 --squash이있는 경우 레이어를 병합하는 빌드 명령에 추가 하여 SSH 키를 제거하고에서 숨길 수 있습니다 docker history.


13
이 GitHub 이슈 스레드 는이 접근 방식이 여전히 안전하지 않음을 나타냅니다. 다른 유사한 솔루션에 대해서는 이 의견 을 참조하십시오 .
eczajk

4
스쿼시 대신 다른 해결책은 동일한 RUN 명령에서 키를 추가 및 제거하고 추가 및 제거 사이에서 필요한 키를 사용하는 것입니다.
Benjamin Hammer Nørgaard

2
id_rsa.pub필요하지 않은 파일 작성을위한 행을 제거 할 수 있습니다 .
LCB


키가 비밀번호로 보호 된 경우 $(openssl rsa -in ~/.ssh/id_rsa)대신 사용하십시오
BroiSatse

89

Ubuntu를 사용할 때 ssh_config가 올바르지 않습니다. 당신은 추가해야합니다

RUN  echo "    IdentityFile ~/.ssh/id_rsa" >> /etc/ssh/ssh_config

ssh 키를 인식하기 위해 Dockerfile에 연결하십시오.


2
또한 다음과 같이 올바른 사용자 이름을 설정해야합니다RUN echo " Host example.com" >> /root/.ssh/config RUN echo " User <someusername>" >> /root/.ssh/config
monofone

1
누군가 누군가 개인 키를 호스트 시스템에서 컨테이너로 복사하는 이유는 무엇입니까? 지휘는 괜찮지 만 위에서 언급 한 내용은 이해가되지 않습니다 ...
Vladimir Djuricic

12
이것은 안전하지 않습니다! Docker의 최신 1.13 버전은 아래 솔루션을 참조하십시오. @ebensing
다니엘 반 플라이 먼

1
@VladimirDjuricic 배포 키와 같은 것들이 있습니다.
Zelphir Kaltstahl

실제로 우분투 최소 컨테이너에서 ssh를 올바르게 설정하려면 ssh-keygen -A를 실행해야합니다. 그런 다음 pub / priv 키를 추가하고 sshd를 시작할 수 있습니다. 내 dockerfile에 다음 항목 중 하나 인 'RUN ssh-keygen -A'가 있습니다.
piotrektt

84

노트 :이 방법은 개인 이미지 이며 항상 사용되는 이미지에만 사용하십시오 !

ssh 키는 추가 한 후에 레이어 명령에서 키를 제거하더라도 이미지 내에 저장된 상태로 유지됩니다 ( 이 게시물의 주석 참조 ).

내 경우에는 이것이 정상이므로 이것이 내가 사용하는 것입니다.

# Setup for ssh onto github
RUN mkdir -p /root/.ssh
ADD id_rsa /root/.ssh/id_rsa
RUN chmod 700 /root/.ssh/id_rsa
RUN echo "Host github.com\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config

91
이렇게하면 키를 이미지에 보관할 수 있습니다.
CppLearner

12
@CppLearner 당신이 맞습니다. 이것은 이미지에 키를 저장하며 경우에 따라 보안 문제 일 수 있습니다. 강조해 주셔서 감사합니다. 그러나 이것이 완벽하게 저장되는 많은 상황이 있습니다. 예를 들어 개인 저장소에 저장된 이미지 또는 로컬 키를 이미지에 복사하는 프로덕션 서버에 직접 빌드 된 이미지의 경우.
yellowcap

2
또한 Dockerfile 내에 공급 업체를 설치하는 경우 공급 업체가 설치되면 ssh 키를 제거하지 않아도됩니다.
SebScoFr

2
@SebScoFr, 나중에 명령에서 키를 제거하더라도 키는 레이어 중 하나에 저장됩니다 (업데이트 된 답변의 링크 참조). 따라서 이미지는 항상 ssh 키를 노출하므로 솔루션은 개인 이미지에만 사용해야합니다!
yellowcap

1
@yellowcap 당신이 빌드를 찌그러 뜨리면
Anoyz

56

docker compose를 사용하는 경우 SSH 에이전트를 다음과 같이 전달하는 쉬운 선택이 있습니다.

something:
    container_name: something
    volumes:
        - $SSH_AUTH_SOCK:/ssh-agent # Forward local machine SSH key to docker
    environment:
        SSH_AUTH_SOCK: /ssh-agent

23
유닉스 도메인 소켓이 프록시되지 않기 때문에 Docker-machine (VirtualBox를 통한) 또는 Mac 용 Docker (xhyve를 사용하는)를 사용하든 Mac 호스트에서는 이것이 작동하지 않습니다.
Joe Shaw

SSH_AUTH_SOCK는 ssh-agent에 대한 경로를 포함하는 변수입니다.
Aistis


1
ssh 전달은 이제 macOS 호스트에서도 지원됩니다. 경로를 마운트하는 대신 $SSH_AUTH_SOCK이 경로를 마운트해야합니다 /run/host-services/ssh-auth.sock.
Jakub Kukul

47

Peter Grainger의 답변을 확장 하여 Docker 17.05부터 다단계 빌드 를 사용할 수있었습니다 . 공식 페이지 상태 :

다단계 빌드에서는 FROMDockerfile에서 여러 명령문 을 사용 합니다. 각 FROM명령어는 다른베이스를 사용할 수 있으며 각 명령어는 새로운 빌드 단계를 시작합니다. 최종 이미지에서 원하지 않는 모든 것을 남겨두고 한 단계에서 다른 단계로 아티팩트를 선택적으로 복사 할 수 있습니다.

이 점을 염두에 두는 것은 Dockerfile세 가지 빌드 단계 를 포함하는 나의 예입니다 . 클라이언트 웹 애플리케이션의 프로덕션 이미지를 작성하기위한 것입니다.

# Stage 1: get sources from npm and git over ssh
FROM node:carbon AS sources
ARG SSH_KEY
ARG SSH_KEY_PASSPHRASE
RUN mkdir -p /root/.ssh && \
    chmod 0700 /root/.ssh && \
    ssh-keyscan bitbucket.org > /root/.ssh/known_hosts && \
    echo "${SSH_KEY}" > /root/.ssh/id_rsa && \
    chmod 600 /root/.ssh/id_rsa
WORKDIR /app/
COPY package*.json yarn.lock /app/
RUN eval `ssh-agent -s` && \
    printf "${SSH_KEY_PASSPHRASE}\n" | ssh-add $HOME/.ssh/id_rsa && \
    yarn --pure-lockfile --mutex file --network-concurrency 1 && \
    rm -rf /root/.ssh/

# Stage 2: build minified production code
FROM node:carbon AS production
WORKDIR /app/
COPY --from=sources /app/ /app/
COPY . /app/
RUN yarn build:prod

# Stage 3: include only built production files and host them with Node Express server
FROM node:carbon
WORKDIR /app/
RUN yarn add express
COPY --from=production /app/dist/ /app/dist/
COPY server.js /app/
EXPOSE 33330
CMD ["node", "server.js"]

.dockerignore의 내용을 반복 .gitignore(그것을 방지 파일 node_modules및 결과 dist복사되는 프로젝트의 디렉토리) :

.idea
dist
node_modules
*.log

이미지를 빌드하는 명령 예 :

$ docker build -t ezze/geoport:0.6.0 \
  --build-arg SSH_KEY="$(cat ~/.ssh/id_rsa)" \
  --build-arg SSH_KEY_PASSPHRASE="my_super_secret" \
  ./

개인 SSH 키에 암호가 없으면 빈 SSH_KEY_PASSPHRASE인수를 지정하십시오 .

이것이 작동하는 방식입니다.

1). 첫 번째 단계에서 package.json, yarn.lock파일과 개인 SSH 키라는 이름의 첫 번째 중간 이미지로 복사됩니다 sources. 더 이상의 SSH 키 암호 문구 프롬프트를 피하기 위해 자동으로 추가됩니다 ssh-agent. 드디어yarn 명령은 NPM에서 필요한 모든 종속성을 설치하고 SSH를 통해 Bitbucket에서 개인 git 리포지토리를 복제합니다.

2). 두 번째 단계는 웹 애플리케이션의 소스 코드를 빌드 및 축소 dist하여 다음 중간 이미지의 디렉토리에 배치합니다 production. 설치된 소스 코드 는 첫 번째 단계에서 생성 된 node_modules이미지에서 sources다음 줄로 복사됩니다 .

COPY --from=sources /app/ /app/

아마도 다음 줄이 될 수도 있습니다.

COPY --from=sources /app/node_modules/ /app/node_modules/

node_modules여기 첫 번째 중간 이미지의 디렉토리 만 SSH_KEY있으며 SSH_KEY_PASSPHRASE더 이상 인수가 없습니다. 빌드에 필요한 나머지는 모두 프로젝트 디렉토리에서 복사됩니다.

삼). 세 번째 단계 에서는 이름이 지정된 두 번째 중간 이미지의 디렉토리 ezze/geoport:0.6.0만 포함 하고 웹 서버를 시작하기 위해 Node Express를 설치 하여 태그 될 최종 이미지의 크기를 줄 입니다.distproduction

이미지 나열은 다음과 같은 출력을 제공합니다.

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ezze/geoport        0.6.0               8e8809c4e996        3 hours ago         717MB
<none>              <none>              1f6518644324        3 hours ago         1.1GB
<none>              <none>              fa00f1182917        4 hours ago         1.63GB
node                carbon              b87c2ad8344d        4 weeks ago         676MB

태그가 지정되지 않은 이미지는 첫 번째 및 두 번째 중간 빌드 단계에 해당합니다.

당신이 실행하는 경우

$ docker history ezze/geoport:0.6.0 --no-trunc

당신은 어떤이의 언급이 표시되지 않습니다 SSH_KEYSSH_KEY_PASSPHRASE최종 이미지에서.


오래된 게시물이지만 나는 이것이 18.09 이전에 그것을하는 가장 좋은 방법이라고 강조하고 싶습니다. 스쿼시는 불필요하고 위험합니다. 다단계를 사용하면 원하는 아티팩트 만 가져오고 있음을 알 수 있습니다. 스쿼시를 원하지 않는 파일의 옵트 아웃으로, 다단계를 옵트 인으로 생각하십시오. 이 답변은 더 높아야합니다. 이미지에서 ssh 키를 굽는 것은 끔찍한 연습입니다.
mritalian

@ ezze이 매우 유용한 게시물에 대해 대단히 감사합니다 :) SSH 에이전트가 나를 미치게합니다. 나는 무엇을했는지와 비슷한 것을했습니다 : 도커 빌드 로그에서 올바르게 볼 수 Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)있지만 다른 RUN 또는 동일한 RUN에서 체크인 할 때 수행하여 명령은 ssh-add -l이 "에이전트가 어떤 정체성이 없다"고 알려줍니다. 내 머리카락을 벗기 시작, 어떤 생각?
Alex

40

컨테이너 내에 ssh 키를 주입하기 위해 여러 솔루션이 있습니다.

  1. ADD지침 과 함께 Dockerfile을 사용하면 빌드 프로세스 중에 Dockerfile을 삽입 할 수 있습니다

  2. 단순히 다음과 같은 일을 cat id_rsa | docker run -i <image> sh -c 'cat > /root/.ssh/id_rsa'

  3. docker cp컨테이너가 실행되는 동안 파일을 주입 할 수 있는 명령을 사용합니다.


2
그래서 지금은 /root/.ssh/id_rsa에 복사하려고 시도했지만 여전히 "호스트 키 확인에 실패했습니다. 치명적 : 원격 끝이 예기치 않게 끊어졌습니다"라는 오류가 Git에서 나타납니다. 어떤 이유로 든 키를 사용하지 않습니다. 그래서 시스템이 실제로 ssh 키로 사용하도록 시스템에 알리기 위해해야 ​​할 다른 것이 있다고 생각합니다. 이 디버깅 방법을 정확히 모르십시오. (이 키는 호스트에서 문제없이 실행되기 때문에 작동한다는 것을 알고 있습니다)
ebensing

/ etc / ssh / ssh_config가 올바른 키 파일을 대상으로 할 수 있습니까?
creack

1
도커 컨테이너 파일을 검사하는 좋은 방법이 있습니까? 아니면 올바른 구성으로 시도하고 복사해야합니까?

3
방금 'base'이미지로 시도하고 apt-get install openssh-server키를 /root/.ssh/id_rsa에 넣고 넣었습니다. 어떤 이미지를 사용하고 있습니까?
creack

컨테이너 파일을 검사 해야하는 경우 가장 좋은 방법은 결과 이미지를 'cat'으로 커밋하고 실행하는 것입니다.
creack

15

플랫폼 간 솔루션 중 하나는 바인드 마운트 를 사용 하여 호스트 .ssh폴더를 컨테이너 에 공유하는 것입니다 .

docker run -v /home/<host user>/.ssh:/home/<docker user>/.ssh <image>

에이전트 전달과 유사하게이 접근 방식은 컨테이너에 공개 키에 액세스 할 수있게합니다. 또 다른 단점은 루트가 아닌 사용자와도 작동하여 GitHub에 연결된다는 것입니다. 그러나 고려해야 할 한 가지주의 사항은 .ssh폴더의 모든 내용 (개인 키 포함) 이 공유되므로이 방법은 개발 및 신뢰할 수있는 컨테이너 이미지에만 바람직하다는 것입니다.


1
이것은 작동 할 수 있지만 다음 기간 docker build에만 해당되는 것은 아닙니다.docker run
Alexander Mills

3
그것이 바로 요점입니다. ssh 키를 docker 파일에 넣지 않으려 고합니다.
모하마드 아짐

2
SSH 에이전트 전달이 Linux 외부에서 작동하지 않는다면 개발 환경에서 많은 번거 로움이없는 훌륭한 솔루션이됩니다.
Josh Habdas

docker-compose up로컬 Windows 10에서 도커를 사용 하고 있습니다. 해당 시나리오에서 어떻게 솔루션을 사용해야합니까?
llaaalu

본질적으로 docker compose에서 볼륨을 매핑하는 방법을 묻습니다. 위의 답변이 있습니다. 특히 윈도우이 힘 도움말에 대한 stackoverflow.com/questions/41334021/...
모하마드 아짐

14

Docker 컨테이너는 자체 '서비스'로 표시되어야합니다. 우려를 분리하려면 기능을 분리해야합니다.

1) 데이터는 데이터 컨테이너에 있어야합니다. 연결된 볼륨을 사용하여 리포지를 복제하십시오. 그런 다음 해당 데이터 컨테이너를 필요한 서비스에 연결할 수 있습니다.

2) 컨테이너를 사용하여 데이터 컨테이너를 실행할 때 데이터 컨테이너를 연결하는 자식 복제 작업 (즉, 작업 만 복제 중)을 실행하십시오.

3) ssh 키와 동일 : 볼륨 (위에서 제안한대로)을 넣고 필요할 때 git clone 서비스에 연결하십시오.

이렇게하면 복제 작업과 키가 모두 임시적이고 필요할 때만 활성화됩니다.

이제 앱 자체가 git 인터페이스 인 경우 작업을 수행하기 위해 github 또는 bitbucket REST API를 직접 고려할 수 있습니다. 이것이 바로 그것이 설계된 것입니다.


13

이 줄은 문제입니다 :

ADD ../../home/ubuntu/.ssh/id_rsa /root/.ssh/id_rsa

이미지에 복사 할 파일을 지정할 때 Dockerfile이있는 디렉토리와 관련된 상대 경로 만 사용할 수 있습니다. 따라서 대신 다음을 사용해야합니다.

ADD id_rsa /root/.ssh/id_rsa

그리고 id_rsa 파일을 Dockerfile과 동일한 디렉토리에 넣으십시오.

자세한 내용은 http://docs.docker.io/reference/builder/#add에서 확인 하십시오.


4
이것은 쉽게 잊어 버릴 수있는 이미지에 개인 키를 넣기 때문에 보안 문제이기도합니다.
Mike D

docker cp이미지가 아닌 컨테이너에 넣습니다.
Alexander Mills

13

docker build time에서 npm install을 할 때 비슷한 문제가 발생했습니다.

Daniel van Flymen의 솔루션에서 영감을 얻어 git url rewrite 와 결합 하여 개인 github repos에서 npm 설치를 인증하는 더 간단한 방법을 찾았습니다. 키 대신 oauth2 토큰을 사용했습니다.

이 경우 npm 종속성은 "git + https://github.com/ ..." 로 지정되었습니다 .

컨테이너 인증의 경우 ssh 인증 (ssh : //git@github.com/) 또는 토큰 인증 (https : // $ {GITHUB_TOKEN} @ github.com /)에 적합하도록 URL을 다시 작성해야합니다.

빌드 명령 :

docker build -t sometag --build-arg GITHUB_TOKEN=$GITHUB_TOKEN . 

불행히도, 나는 docker 1.9를 사용하고 있으므로 --squash 옵션이 아직 없으므로 결국 추가해야합니다.

도커 파일 :

FROM node:5.10.0

ARG GITHUB_TOKEN

#Install dependencies
COPY package.json ./

# add rewrite rule to authenticate github user
RUN git config --global url."https://${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"

RUN npm install

# remove the secret token from the git config file, remember to use --squash option for docker build, when it becomes available in docker 1.13
RUN git config --global --unset url."https://${GITHUB_TOKEN}@github.com/".insteadOf

# Expose the ports that the app uses
EXPOSE 8000

#Copy server and client code
COPY server /server 
COPY clients /clients

11

ssh 인증 소켓을 컨테이너로 전달하십시오.

docker run --rm -ti \
        -v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock \
        -e SSH_AUTH_SOCK=/tmp/ssh_auth.sock \
        -w /src \
        my_image

당신의 스크립트는 git clone .

추가 : 복제 된 파일을 특정 사용자에게 속하게 chown하려면 컨테이너 내부의 루트 이외의 다른 사용자 를 사용 하면git 실패 합니다.

이 환경을 컨테이너 환경에 게시하면 몇 가지 추가 변수를 사용할 수 있습니다.

docker run ...
        -e OWNER_USER=$(id -u) \
        -e OWNER_GROUP=$(id -g) \
        ...

복제 한 후에 chown $OWNER_USER:$OWNER_GROUP -R <source_folder>는 컨테이너 외부에있는 루트가 아닌 사용자가 파일에 액세스 할 수 있도록 컨테이너를 떠나기 전에 적절한 소유권을 설정 하도록 실행해야합니다 .


1
최신 Docker 버전에서는 -u root:$(id -u $USER)최소한 사용자와 동일한 기본 그룹이 소유 한 파일을 소유하도록 전달할 수 있으므로 권한이있는 파일을 만들지 sudo않는 한 모든 파일을 읽을 수 있어야 합니다 0600.
dragon788

@ dragon788 난 당신이 오타를 줄 생각 -u root:$(id -u $USER)해야한다 -g.
edupo

좋은 전화! 나는 모바일에서 그것을 고칠 수없는 것 같습니다, 곧 데스크톱에서 시도 할 것입니다.
dragon788

내가 가진 /tmp/ssh_auth.sock: No such file or directory그것의 지금 /tmp/ssh-vid8Zzi8UILE/agent.46016내 호스트 시스템에
vladkras

@ vladkras 오류는 매우 일반적입니다. /tmp컨테이너 내부에 대한 권한으로 인해 발생할 수 있습니다 . 또는 docker run 명령의 오타가 있습니다. 바인드 명령문이 올바른지 확인하십시오 -v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock. 순서는 중요하고 세미콜론도 중요합니다. 추가 도움이 필요하면 docker documentation 을 확인하십시오 .
edupo

10

eczajk가 Daniel van Flymen의 답변에서 이미 언급했듯이 키를 제거하고 사용하는 것이 안전하지 않은 것으로 보입니다. 키 --squash는 여전히 역사에서 볼 수 있기 때문입니다 ( docker history --no-trunc).

Docker 18.09 대신 "빌드 비밀"기능을 사용할 수 있습니다. 필자의 경우 Dockerfile에서 호스트 SSH 키를 사용하여 개인 git repo를 복제했습니다.

# syntax=docker/dockerfile:experimental

[...]

RUN --mount=type=ssh git clone [...]

[...]

이를 사용하려면 다음을 실행하기 전에 새로운 BuildKit 백엔드를 활성화해야합니다 docker build.

export DOCKER_BUILDKIT=1

그리고에 --ssh default매개 변수를 추가해야 합니다 docker build.

여기에 대한 자세한 정보 : https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066


1
최고의 솔루션 IMHO. 1) ssh-agent에 개인 키를 ssh-add ~/.ssh/id_rsa추가하고 2) known_hosts에 git 호스트를 추가하십시오 (예 : bitbucket).RUN ssh-keyscan -H bitbucket.org >> ~/.ssh/known_hosts
Moritz Ringler

나는 이것을 전혀 작동시키지 못했습니다. 여전히 권한 오류가 발생합니다. 도커 빌드에서 플래그를 Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access and the repository exists.전달 하고 실행 명령 where을 --ssh default사용 하더라도 마찬가지 입니다. 빌드 시스템에서 동일한 리포지토리를 문제없이 복제 할 수 있습니다. 도커 빌드 컨테이너에서 단순히 실패합니다. Docker의 Mac 버전이 실제로 ssh 클라이언트를 전달하지 않는 것 같습니다. --mount=type=sshgit clone
PMende

@PMende도 동일한 문제에 직면했기 때문에 언급 한이 문제를 파악할 수있었습니다.
Sadan A.

@SadanArshad이 기능은 현재 Linux 시스템에서 Docker를 실행하는 경우에만 지원됩니다. Mac에서 Docker 명령을 실행하는 경우 작동하지 않습니다 (확인할 수는 없지만 Windows도 가능합니다).
PMende

docker-compose와 함께 작동하지 않는 것이 너무 나쁩니다 ... github.com/docker/compose/issues/6440
Alexis Wilke

9

이 문제는 실제로 성가신 문제입니다. dockerfile 컨텍스트 외부의 파일을 추가 / 복사 할 수 없으므로 ~ / .ssh / id_rsa를 이미지의 /root/.ssh/id_rsa에 연결하는 것은 불가능하며 썰매 작업을 수행 할 키가 필요할 때 도커 이미지를 만드는 동안 개인 저장소 링크의 git clone과 같은.

어쨌든, 나는 설득력이 없지만 해결책을 찾았습니다.

  1. 도커 파일에서 :

    • 이 파일을 /root/.ssh/id_rsa로 추가하십시오
    • git clone, composer와 같이 원하는 것을하십시오 ...
    • 마지막에 rm /root/.ssh/id_rsa
  2. 한 번의 촬영으로 할 스크립트 :

    • dockerfile을 보유하는 폴더에 키를 cp
    • 도커 빌드
    • 복사 된 키를 rm
  3. ssh 요구 사항이있는이 이미지에서 컨테이너를 실행해야 할 때마다 다음과 같이 실행 명령에 -v를 추가하십시오.

    docker run -v ~ / .ssh / id_rsa : /root/.ssh/id_rsa-이름 컨테이너 이미지 명령

이 솔루션을 사용하면 프로젝트 소스와 빌드 된 도커 이미지 모두에 개인 키가 없으므로 더 이상 걱정할 보안 문제가 없습니다.


1
"dockerfile 컨텍스트 외부에있는 파일을 추가 / 복사 할 수 없으므로" 보셨습니까 docker cp? "컨테이너와 호스트 사이의 파일 / 폴더 복사"에 사용됩니다.
Jonathon Reinhart

@JonathonReinhart, 지적 해 주셔서 감사합니다. 예, docker cp트릭을 할 수 있습니다. 그러나이 상황에서 이미지를 빌드하는 동안 ssh_key가 필요했으며 그 당시 컨테이너가 없었습니다. 어쨌든 내 불명확 한 표현을 업데이트 할 것입니다.
ImLeo

9

나는 오늘 같은 문제에 부딪 혔고 이전 게시물이있는 약간 수정 된 버전이 접근법이 나에게 더 유용하다는 것을 알았습니다

docker run -it -v ~/.ssh/id_rsa:/root/.my-key:ro image /bin/bash

(읽기 전용 플래그이므로 컨테이너는 어떤 경우에도 내 ssh 키를 엉망으로 만들지 않습니다.)

내부 컨테이너를 이제 실행할 수 있습니다.

ssh-agent bash -c "ssh-add ~/.my-key; git clone <gitrepourl> <target>"

Bad owner or permissions on /root/.ssh/..@kross에 의해 지적 된 오류가 발생 하지 않습니다.


감사합니다! 이것이 나를 위해 일하는 열쇠였습니다 : ssh-agent와 ssh-add를 다음과 같은 단일 명령으로 사용하십시오 ssh-agent bash -c "ssh-add...". 그런 다음 그 권리를 docker run에 전달할 수 있습니다. 내가 찾은 이전의 모든 예제 eval ssh-agent와 ssh-add eval는 docker run 명령 을 통해 전달하는 방법을 알 수 없었습니다 .
ryanman

7

'원격 서버가 마치 마치 서버에서 실행중인 것처럼 로컬 ssh 에이전트에 액세스하도록 할 수 있습니다'

https://developer.github.com/guides/using-ssh-agent-forwarding/


4
docker run -i -t -v $ (readlink -f $ SSH_AUTH_SOCK) : / ssh-agent -e SSH_AUTH_SOCK = / ssh-agent 우분투 / bin / bash
Pavel Hlobil

1
fruitl00p는 다음과 같은 방식으로 docker-tunnel 컨테이너를 만들었습니다 : github.com/kingsquare/docker-tunnel
Martin Suchanek

6

호스트와 컨테이너 사이에 .ssh 디렉토리를 연결할 수도 있습니다.이 방법에 보안 관련이 있는지는 모르겠지만 가장 쉬운 방법 일 수 있습니다. 이와 같은 것이 작동해야합니다.

$ sudo docker run -it -v /root/.ssh:/root/.ssh someimage bash

docker는 sudo로 실행한다는 것을 기억하십시오 (그렇지 않은 경우).이 경우 루트 ssh 키를 사용하게됩니다.


이 방법을 사용하면 docker 0.11에서 작동하지만 fig를 사용하면 패닉 오류가 발생합니다. 이유를 모르겠습니다
Luis Elizondo 님이

3
이것은 선호되는 방법이며, 권한이없는 호스트 사용자의 키를 컨테이너의 루트로 사용하는 것이 트릭입니다. 언급했듯이 호스트 루트 사용자가 아닌 것으로 시도하십시오 Bad owner or permissions on /root/.ssh/config.
KROSS

이 기능은 기간 동안에 만 사용할 수 docker run있지만 기간 동안에는 사용할 수 없습니다 docker build.
ccpizza

3
@ ccpizza, 나는 그것을 이점으로 본다. 이러한 답변 중 많은 부분이 개인 키를 이미지에 저장합니다. 후속 레이어 명령에서 키를 제거한 후에도 키는 저장된 상태로 유지됩니다. 실행 중 (빌드 아님)에만 개인 키를 도입하면 컨테이너 (이미지 아님)에만 존재할 수 있습니다.
cowlinator

6

docker API 1.39+( Docker docker version빌드로 API 버전 확인) 에서 시작 --ssh하면 Docker Engine이 SSH 에이전트 연결을 전달할 수 있도록 에이전트 소켓 또는 키가 있는 옵션이 있습니다.

빌드 명령

export DOCKER_BUILDKIT=1
docker build --ssh default=~/.ssh/id_rsa .

도커 파일

# syntax=docker/dockerfile:experimental
FROM python:3.7

# Install ssh client (if required)
RUN apt-get update -qq
RUN apt-get install openssh-client -y

# Download public key for github.com
RUN --mount=type=ssh mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts

# Clone private repository
RUN --mount=type=ssh git clone git@github.com:myorg/myproject.git myproject

더 많은 정보:


1
물결표 확장은 저에게 효과적이지 않았습니다. 나는 : could not parse ssh: [default=~/.ssh/id_rsa]: stat ~/.ssh/id_rsa: no such file or directory. 작동하지 않으면 전체 경로를 사용하십시오.
slhck

3

SSH 키의 보안에 신경 쓰지 않는다면 여기에 많은 대답이 있습니다. 당신이한다면, 내가 찾은 가장 좋은 대답 은 diegocsandrim 의이 GitHub 의견 에 대한 위의 의견 링크에서 얻은 것 입니다. 그래서 다른 사람들이 그것을 볼 가능성이 높으며, repo가 ​​사라질 경우를 대비하여 해당 답변의 편집 버전이 있습니다.

여기서 대부분의 솔루션은 이미지에 개인 키를 남겨 둡니다. 이미지에 액세스 할 수있는 사람은 누구나 개인 키에 액세스 할 수 있으므로 이는 나쁩니다. 의 동작에 대해 충분히 알지 못하므로 squash키를 삭제하고 해당 레이어를 스쿼시하더라도 여전히 문제가 될 수 있습니다.

사전 서명 URL을 생성하여 aws s3 cli를 사용하여 키에 액세스하고 약 5 분 동안 액세스를 제한하고,이 사전 서명 URL을 repo 디렉토리의 파일에 저장 한 다음 dockerfile에서 이미지에 추가합니다.

dockerfile에는 다음 단계를 모두 수행하는 RUN 명령이 있습니다. pre-sing URL을 사용하여 ssh 키를 가져오고 npm install을 실행하고 ssh 키를 제거하십시오.

하나의 단일 명령으로이 작업을 수행하면 ssh 키가 어떤 계층에도 저장되지 않지만 사전 서명 URL이 저장되며 5 분 후에 URL이 유효하지 않기 때문에 문제가되지 않습니다.

빌드 스크립트는 다음과 같습니다.

# build.sh
aws s3 presign s3://my_bucket/my_key --expires-in 300 > ./pre_sign_url
docker build -t my-service .

Dockerfile은 다음과 같습니다.

FROM node

COPY . .

RUN eval "$(ssh-agent -s)" && \
    wget -i ./pre_sign_url -q -O - > ./my_key && \
    chmod 700 ./my_key && \
    ssh-add ./my_key && \
    ssh -o StrictHostKeyChecking=no git@github.com || true && \
    npm install --production && \
    rm ./my_key && \
    rm -rf ~/.ssh/*

ENTRYPOINT ["npm", "run"]

CMD ["start"]

1
이 솔루션의 문제점은 pre_sign_url이 매번 변경되기 때문에 packages.json 파일을 변경하지 않아도 npm 설치를 캐시 할 수 없다는 것입니다. build.sh에서 키를 가져 와서 매번 바뀌지 않도록 빌드 인수로 설정하는 것이 좋습니다.
York Yang


3

Docker 컨테이너 내부의 SSH 문제에 대한 간략한 개요는 여기자세히 설명되어 있습니다 . 비밀을 유출하지 않고 컨테이너 내에서 신뢰할 수있는 원격 장치에 연결하는 방법에는 몇 가지가 있습니다.

이 외에도 Compose를 사용할 때 런타임에 액세스 가능한 별도의 도커 컨테이너에서 실행되는 키 저장소를 사용할 수도 있습니다. 여기서 결점은 Vashi by HashiCorp 와 같은 키 저장소를 작성하고 관리하는 데 필요한 기계로 인해 추가 복잡성 입니다.

독립형 Docker 컨테이너에서 SSH 키를 사용하려면 위에 링크 된 방법을 참조하고 특정 요구에 따라 각 방법의 단점을 고려하십시오. 그러나 Compose에서 실행 중이고 런타임에 앱의 키를 공유하려면 (OP의 실용성을 반영) 다음을 시도하십시오.

  • docker-compose.env파일을 작성하여 파일에 추가 .gitignore하십시오.
  • 키를 요구하는 서비스를 업데이트 docker-compose.yml하고 추가 하십시오 env_file.
  • 예를 들어 process.node.DEPLOYER_RSA_PUBKEYNode.js 애플리케이션의 경우 애플리케이션 런타임시 환경에서 공개 키에 액세스 합니다.

위의 접근 방식은 개발 및 테스트에 이상적이며 생산 요구 사항을 충족 할 수 있지만 생산에서는 위에서 식별 된 다른 방법 중 하나를 사용하는 것이 좋습니다.

추가 자료 :


3

다단계 빌드를 사용하여 컨테이너를 빌드 할 수 있습니다 할 수 있습니다.이 방법은 다음과 같습니다.

ssh로 이미지를 구축하는 1 단계

FROM ubuntu as sshImage
LABEL stage=sshImage
ARG SSH_PRIVATE_KEY
WORKDIR /root/temp

RUN apt-get update && \
    apt-get install -y git npm 

RUN mkdir /root/.ssh/ &&\
    echo "${SSH_PRIVATE_KEY}" > /root/.ssh/id_rsa &&\
    chmod 600 /root/.ssh/id_rsa &&\
    touch /root/.ssh/known_hosts &&\
    ssh-keyscan github.com >> /root/.ssh/known_hosts

COPY package*.json ./

RUN npm install

RUN cp -R node_modules prod_node_modules

2 단계 : 컨테이너 제작

FROM node:10-alpine

RUN mkdir -p /usr/app

WORKDIR /usr/app

COPY ./ ./

COPY --from=sshImage /root/temp/prod_node_modules ./node_modules

EXPOSE 3006

CMD ["npm", "run", "dev"] 

작성 파일에 env 속성을 추가하십시오.

   environment:
      - SSH_PRIVATE_KEY=${SSH_PRIVATE_KEY}

그런 다음 빌드 스크립트에서 args를 다음과 같이 전달하십시오.

docker-compose build --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)"

그리고 보안을 위해 중간 컨테이너를 제거하십시오. 건배에 도움이됩니다.


2

Docker 이미지 레이어에 키를 저장하지 않거나 ssh_agent 체조를 거치지 않고 간단하고 안전한 방법은 다음과 같습니다.

  1. 의 단계 중 하나로서 다음 을 추가 Dockerfile하여 .ssh디렉토리를 만듭니다 .

    RUN mkdir -p /root/.ssh

  2. 아래는 ssh 디렉토리를 볼륨으로 마운트하고자 함을 나타냅니다.

    VOLUME [ "/root/.ssh" ]

  3. ssh_config다음 줄을 추가 하여 컨테이너가 공개 키를 찾을 수있는 위치를 알고 있는지 확인하십시오 .

    RUN echo " IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config

  4. .ssh런타임에 로컬 사용자의 디렉토리를 컨테이너에 노출하십시오 .

    docker run -v ~/.ssh:/root/.ssh -it image_name

    또는 dockerCompose.yml서비스 볼륨 키 아래에 이것을 추가하십시오.

    - "~/.ssh:/root/.ssh"

결승 Dockerfile에는 다음과 같은 내용이 포함되어야합니다.

FROM node:6.9.1

RUN mkdir -p /root/.ssh
RUN  echo "    IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config

VOLUME [ "/root/.ssh" ]

EXPOSE 3000

CMD [ "launch" ]

1

다른 방법으로 문제를 해결하려고합니다. 이미지에 공개 ssh 키 추가. 그러나 내 시험에서 "docker cp"는 컨테이너에서 호스트로 FROM을 복사하는 것임을 발견했습니다. creak의 답변에서 항목 3은 docker cp를 사용하여 파일을 컨테이너에 주입 할 수 있다고 말합니다. https://docs.docker.com/engine/reference/commandline/cp/를 참조 하십시오

발췌

컨테이너의 파일 시스템에서 호스트 경로로 파일 / 폴더를 복사하십시오. 경로는 파일 시스템의 루트를 기준으로합니다.

  Usage: docker cp CONTAINER:PATH HOSTPATH

  Copy files/folders from the PATH to the HOSTPATH

이 URL은 현재 고장난 것 같습니다.
slm

사용되지 않거나 올바르지 않습니다. 최신 1.8.2부터는 어느 방향 으로든 복사 할 수 있습니다.
Jonathon Reinhart

1

공유 폴더를 사용하여 승인 된 키를 컨테이너에 전달하고 다음과 같이 docker 파일을 사용하여 권한을 설정할 수 있습니다.

FROM ubuntu:16.04
RUN apt-get install -y openssh-server
RUN mkdir /var/run/sshd
EXPOSE 22
RUN cp /root/auth/id_rsa.pub /root/.ssh/authorized_keys
RUN rm -f /root/auth
RUN chmod 700 /root/.ssh
RUN chmod 400 /root/.ssh/authorized_keys
RUN chown root. /root/.ssh/authorized_keys
CMD /usr/sbin/sshd -D

그리고 docker run에는 다음과 같은 것이 포함되어 호스트의 auth 디렉토리 (authorized_keys를 보유)를 컨테이너와 공유 한 다음 호스트의 포트 7001을 통해 액세스 할 수있는 ssh 포트를 엽니 다.

-d -v /home/thatsme/dockerfiles/auth:/root/auth -–publish=127.0.0.1:7001:22

컨테이너에서 쉘을 열고 컨테이너 내에서 명령을 실행하는 또 다른 방법 으로 보이는 https://github.com/jpetazzo/nsenter 를 볼 수 있습니다 .


1

파티에 늦게까지, 호스트 운영 체제 키를 컨테이너 내부에서 루트로 사용할 수있게 만드는 방법은 다음과 같습니다.

docker run -v ~/.ssh:/mnt -it my_image /bin/bash -c "ln -s /mnt /root/.ssh; ssh user@10.20.30.40"

컨테이너를 반복하면 개인 키가 남을 수 있으므로 Dockerfile을 사용하여 키를 설치하는 것은 좋지 않습니다.


0

비밀 정보를 사용하여 런타임에 컨테이너에 필요한 중요한 데이터를 관리 할 수 ​​있지만 다음과 같이 이미지 나 소스 제어에 저장하고 싶지 않습니다.

  • 아이디와 비밀번호
  • TLS 인증서 및 키
  • SSH 키
  • 데이터베이스 또는 내부 서버 이름과 같은 기타 중요한 데이터
  • 일반 문자열 또는 이진 콘텐츠 (최대 500kb 크기)

https://docs.docker.com/engine/swarm/secrets/

런타임 (빌드 아님) 중에 사용할 서명 키를 컨테이너에 추가하는 방법을 알아 내려고이 질문을 보았습니다. 도커 비밀은 내 유스 케이스의 해결책 인 것처럼 보이며 아무도 언급하지 않았으므로 추가 할 것입니다.


0

제 경우에는 원격 저장소의 nodejs 및 'npm i'에 문제가있었습니다. nodejs 컨테이너에 'node'사용자를 추가하고 컨테이너의 ~ / .ssh에 700을 추가했습니다.

도커 파일 :

USER node #added the part
COPY run.sh /usr/local/bin/
CMD ["run.sh"]

run.sh :

#!/bin/bash
chmod 700 -R ~/.ssh/; #added the part

docker-compose.yml :

nodejs:
      build: ./nodejs/10/
      container_name: nodejs
      restart: always
      ports:
        - "3000:3000"
      volumes:
        - ../www/:/var/www/html/:delegated
        - ./ssh:/home/node/.ssh #added the part
      links:
        - mailhog
      networks:
        - work-network

그 후 그것은 작동하기 시작했다



-1

실행중인 도커 컨테이너에서 docker -i (interactive) 옵션으로 ssh-keygen을 실행할 수 있습니다. 그러면 도커 컨테이너 안에 키를 만들라는 메시지가 컨테이너에 전달됩니다.


1
그 다음엔? 이 작업을 수행 할 권한이 없기 때문에이 작업 후에는 아무것도 할 수 없습니다.
Jonathon Reinhart

-1

데비안 / 루트 / authorized_keys의 경우 :

RUN set -x && apt-get install -y openssh-server

RUN mkdir /var/run/sshd
RUN mkdir -p /root/.ssh
RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN  echo "ssh-rsa AAAA....yP3w== rsa-key-project01" >> /root/.ssh/authorized_keys
RUN chmod -R go= /root/.ssh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.