การใช้คีย์ SSH ภายในคอนเทนเนอร์นักเทียบท่า


324

ฉันมีแอพที่ใช้งานสิ่งสนุก ๆ กับ Git (เช่นการเรียกใช้ git clone & git push) และฉันพยายามเทียบท่า

ฉันพบปัญหา แต่ฉันต้องสามารถเพิ่มคีย์ SSH ไปยังคอนเทนเนอร์เพื่อให้ 'ผู้ใช้' ของคอนเทนเนอร์ใช้งานได้

ฉันพยายามคัดลอกลง/root/.ssh/เปลี่ยนเปลี่ยน$HOMEสร้าง git ssh wrapper และยังไม่มีโชค

นี่คือ 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หรือในกรณีของฉันpipและnpmเพื่อดาวน์โหลดจากที่เก็บส่วนตัว

วิธีแก้ปัญหาที่ฉันพบคือการเพิ่มกุญแจของคุณโดยใช้--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 .

Dockerfile

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

ปรับปรุง:หากคุณกำลังใช้หาง 1.13 และมีคุณสมบัติในการทดลองคุณสามารถผนวก--squashกับการสร้างคำสั่งซึ่งจะผสานชั้นเอากุญแจ SSH docker historyและซ่อนพวกเขาจาก


13
เธรดปัญหา GitHub นี้จะระบุว่าวิธีการนี้ยังไม่ปลอดภัย ดูความคิดเห็นนี้สำหรับโซลูชันอื่นที่คล้ายคลึงกัน
eczajk

4
โซลูชันอื่นแทนการบีบคือการเพิ่มและลบคีย์ในคำสั่ง RUN เดียวกันและระหว่างการเพิ่มและลบคุณใช้สิ่งที่คุณต้องการ
Benjamin Hammer Nørgaard

2
บางทีคุณสามารถลบบรรทัดสำหรับสร้างid_rsa.pubไฟล์ตามที่ไม่จำเป็น
LCB

1
แทนการบีบ, ให้ใช้ภาพแบบหลายขั้นตอนการสร้าง
Richard Kiefer

หากรหัสของคุณได้รับการป้องกันด้วยรหัสผ่านให้ใช้$(openssl rsa -in ~/.ssh/id_rsa)แทน
BroiSatse

89

ปรากฎเมื่อใช้ Ubuntu, ssh_config ไม่ถูกต้อง คุณต้องเพิ่ม

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

ไปที่ Dockerfile ของคุณเพื่อให้มันจดจำคีย์ ssh ของคุณ


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
Daniel van Flymen

1
@VladimirDjuricic มีบางอย่างที่เหมือนกุญแจปรับใช้
Zelphir Kaltstahl

จริง ๆ แล้วคุณต้องรัน ssh-keygen -A เพื่อเซ็ตอัพ ssh อย่างถูกต้องบน Ubuntu น้อยที่สุด จากนั้นคุณสามารถเพิ่ม pub / priv keys และเริ่ม 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
@ เหลืองไม่ถ้าคุณ
วอช

56

หากคุณใช้นักเทียบท่าเขียนตัวเลือกที่ง่ายคือส่งต่อเอเจนต์ 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
เพียงทราบว่าสิ่งนี้ไม่ได้ผลสำหรับโฮสต์ Mac ไม่ว่าจะใช้นักเทียบท่าเครื่อง (ผ่าน VirtualBox) หรือ Docker for Mac (ซึ่งใช้ xhyve) เพราะซ็อกเก็ตโดเมน unix ไม่ได้ถูกพร็อกซี
โจชอว์

SSH_AUTH_SOCKเป็นตัวแปรซึ่งมีเส้นทางไปยัง ssh-agent
Aistis

2
รายละเอียดเพิ่มเติมเกี่ยวกับSSH_AUTH_SOCK blog.joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add
JuanPablo

1
SSH การส่งต่ออยู่ในขณะนี้นอกจากนี้ยังได้รับการสนับสนุนบนโฮสต์ MacOS - แทนการติดตั้งเส้นทางของ$SSH_AUTH_SOCKคุณจะต้องติดเส้นทางนี้ /run/host-services/ssh-auth.sock-
Jakub Kukul

47

การขยายคำตอบของ Peter Graingerฉันสามารถใช้โครงสร้างหลายขั้นตอนที่มีให้ตั้งแต่ Docker 17.05 รัฐหน้าอย่างเป็นทางการ:

ด้วยการสร้างหลายขั้นตอนคุณใช้หลายFROMข้อความใน Dockerfile ของคุณ แต่ละ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 และที่เก็บส่วนตัว git จากที่เก็บ Bitbucket บน SSH

2) ขั้นตอนที่สองสร้างและรหัส minifies แหล่งที่มาของโปรแกรมประยุกต์บนเว็บและสถานที่ในไดเรกทอรีของภาพกลางต่อไปที่มีชื่อ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อาร์กิวเมนต์อีกต่อไป ส่วนที่เหลือทั้งหมดที่จำเป็นสำหรับการสร้างจะถูกคัดลอกจากไดเรกทอรีโครงการของเรา

3) ในขั้นตอนที่สามเราลดขนาดของอิมเมจสุดท้ายที่จะถูกแท็กezze/geoport:0.6.0โดยการรวมเฉพาะdistไดเร็กทอรีจากอิมเมจระดับกลางที่สองที่ชื่อproductionและติดตั้ง Node Express เพื่อเริ่มต้นเว็บเซิร์ฟเวอร์

รายชื่อรูปภาพให้ผลลัพธ์เช่นนี้:

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

ที่ภาพที่ไม่ติดแท็ก correpsond ไปที่ขั้นตอนการสร้างขั้นกลางขั้นที่หนึ่งและที่สอง

ถ้าคุณวิ่ง

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

คุณจะไม่เห็นการกล่าวถึงSSH_KEYและSSH_KEY_PASSPHRASEในภาพสุดท้าย


โพสต์เก่า แต่ฉันต้องการเน้นนี้เป็นวิธีที่ดีที่สุดในการทำก่อน 18.09 สควอชนั้นไม่จำเป็นและมีความเสี่ยง ด้วยหลายขั้นตอนคุณรู้ว่าคุณนำสิ่งประดิษฐ์ที่คุณต้องการมาเท่านั้น คิดว่าสควอชเป็นการเลือกไม่ใช้ไฟล์ที่คุณไม่ต้องการและเป็นหลายขั้นตอนในการเลือกเข้าร่วม คำตอบนี้จะต้องสูงขึ้น การอบคีย์ ssh ของคุณในภาพเป็นการฝึกที่แย่มาก
mritalian

@ezze ขอบคุณมากสำหรับโพสต์ที่มีประโยชน์มาก :) ตัวแทน SSH กำลังทำให้ฉันบ้าฉันทำสิ่งที่คล้ายกับสิ่งที่คุณทำ: ฉันเห็นใน docker build logs อย่างถูกต้องIdentity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)แต่เมื่อฉันตรวจสอบ RUN อื่นหรือแม้แต่ใน RUN เดียวกัน คำสั่งโดยการทำssh-add -lมันบอกฉันว่า "ตัวแทนไม่มีตัวตน" เริ่มที่จะดึงผมออกความคิดอะไรบ้าง?
อเล็กซ์

40

ในการฉีดคุณคีย์ ssh ภายในคอนเทนเนอร์คุณมีหลายวิธี:

  1. การใช้ Dockerfile พร้อมADDคำแนะนำคุณสามารถฉีดในระหว่างกระบวนการสร้างของคุณ

  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
มีวิธีที่ดีในการตรวจสอบไฟล์ของ docker container หรือไม่? หรือฉันควรลองและคัดลอกในการกำหนดค่าที่ถูกต้อง?
ebensing

3
ฉันเพิ่งลองด้วยภาพ 'ฐาน' การทำ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 ของคุณในไฟล์นักเทียบท่า
Mohammad Azim

2
การส่งต่อเอเจนต์ของ SSH นั้นไม่ได้ทำงานนอกลินุกซ์นี่เป็นวิธีแก้ปัญหาที่ดีสำหรับการทำงานในสภาพแวดล้อมการพัฒนาโดยไม่ต้องยุ่งยากมากนัก
Josh Habdas

ฉันใช้นักเทียบท่าที่ใช้งานdocker-compose upอยู่ใน Windows 10 ของฉันฉันจะใช้วิธีแก้ปัญหาของคุณในสถานการณ์นั้นได้อย่างไร
llaaalu

เป็นหลักคุณจะถามวิธีแผนที่ปริมาณในนักเขียนประกอบ ด้านบนมีคำตอบสำหรับคำตอบนี้ โดยเฉพาะสำหรับ Windows สิ่งนี้อาจช่วยstackoverflow.com/questions/41334021/ …
Mohammad Azim

14

คอนเทนเนอร์นักเทียบท่าควรถูกมองว่าเป็น 'บริการ' ของตนเอง หากต้องการแยกข้อกังวลคุณควรแยกฟังก์ชันการทำงาน:

1) ข้อมูลควรอยู่ใน data container: ใช้ volume ที่เชื่อมโยงเพื่อโคลน repo คอนเทนเนอร์ข้อมูลนั้นสามารถเชื่อมโยงกับบริการที่ต้องการได้

2) ใช้คอนเทนเนอร์เพื่อเรียกใช้งานการโคลน git (นั่นคืองานเดียวคือการโคลน) เชื่อมโยงคอนเทนเนอร์ข้อมูลกับมันเมื่อคุณเรียกใช้

3) เหมือนกันสำหรับ ssh-key: ทำให้มันเป็นโวลุ่ม (ตามที่แนะนำข้างต้น) และเชื่อมโยงไปยังบริการ 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

เรามีปัญหาที่คล้ายกันเมื่อทำการติดตั้ง NPM ในเวลาสร้างนักเทียบท่า

ได้รับแรงบันดาลใจจากวิธีแก้ปัญหาจากDaniel van Flymenและรวมเข้ากับ git url rewriteเราพบวิธีที่ง่ายกว่าสำหรับการตรวจสอบการติดตั้ง npm จาก repos GitHub ส่วนตัวเราใช้โทเค็น oauth2 แทนปุ่ม

ในกรณีของเราการอ้างอิง npm ถูกระบุเป็น "git + https://github.com/ ... "

สำหรับการรับรองความถูกต้องในคอนเทนเนอร์ URL ต้องถูกเขียนใหม่เพื่อให้เหมาะสำหรับการรับรองความถูกต้อง ssh (ssh: //git@github.com/) หรือการตรวจสอบความถูกต้องของโทเค็น (https: // $ {GITHUB_TOKEN} @ github.com /)

คำสั่งสร้าง:

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

แต่น่าเสียดายที่ฉันอยู่ในนักเทียบท่า 1.9 ดังนั้น - ตัวเลือกสควอชยังไม่ได้มีในที่สุดจะต้องมีการเพิ่ม

Dockerfile:

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ภายในคอนเทนเนอร์ของคุณ หรือพิมพ์ผิดในคำสั่งเรียกใช้นักเทียบท่า ตรวจสอบให้แน่ใจว่าคำสั่งการผูกถูกต้อง-v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock: คำสั่งซื้อมีความสำคัญและเครื่องหมายอัฒภาคก็มีความสำคัญเช่นกัน โปรดตรวจสอบเอกสารนักเทียบท่าสำหรับความช่วยเหลือเพิ่มเติม
edupo

10

ตามที่ eczajk แสดงความคิดเห็นในคำตอบของ Daniel van Flymen แล้วดูเหมือนจะไม่ปลอดภัยที่จะเอากุญแจและการใช้งาน--squashออกไปเพราะมันจะยังคงปรากฏให้เห็นในประวัติศาสตร์ ( docker history --no-trunc)

แทนที่จะใช้ Docker 18.09 คุณสามารถใช้คุณสมบัติ "build secret" ในกรณีของฉันฉันโคลน repo git ส่วนตัวโดยใช้คีย์โฮสต์ SSH ของฉันด้วยสิ่งต่อไปนี้ใน Dockerfile ของฉัน:

# syntax=docker/dockerfile:experimental

[...]

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

[...]

เพื่อให้สามารถใช้สิ่งนี้ได้คุณต้องเปิดใช้งานแบ็กเอนด์ BuildKit ใหม่ก่อนที่จะทำงานdocker build:

export DOCKER_BUILDKIT=1

และคุณจำเป็นต้องเพิ่มพารามิเตอร์--ssh defaultdocker 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) เพิ่มโฮสต์ git เพื่อรู้จัก _hosts เช่นสำหรับ 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.นี้แม้จะผ่าน--ssh defaultธงในนักเทียบท่าที่ฉันสร้างและการใช้คำสั่งในการทำงานที่ฉัน--mount=type=ssh git cloneฉันสามารถโคลน repo เดียวกันไม่มีปัญหาในการสร้างเครื่อง มันก็ล้มเหลวในภาชนะสร้างนักเทียบท่า ฉันสงสัยว่ารุ่น mac ของ Docker ไม่ได้ส่งผ่านไคลเอ็นต์ ssh ตามจริง
PMende

@PMende คุณสามารถเข้าใจปัญหานี้ที่คุณพูดถึงเพราะฉันกำลังเผชิญกับสิ่งเดียวกัน
Sadan A.

@SadanArshad ปรากฎว่าขณะนี้ฟังก์ชั่นนี้รองรับเฉพาะเมื่อคุณเรียกใช้ Docker จากเครื่อง Linux มันไม่ทำงานหากคุณใช้คำสั่ง Docker จาก Mac (และอาจเป็น Windows เช่นกันแม้ว่าฉันจะไม่สามารถยืนยันได้)
PMende

แย่เกินไปที่ใช้ไม่ได้กับนักแต่งเพลง ... github.com/docker/compose/issues/6440
Alexis Wilke

9

ปัญหานี้เป็นเรื่องที่น่ารำคาญจริงๆ เนื่องจากคุณไม่สามารถเพิ่ม / คัดลอกไฟล์ใด ๆ ที่อยู่นอกบริบท dockerfile ซึ่งหมายความว่าเป็นไปไม่ได้ที่จะเชื่อมโยง ~ / .ssh / id_rsa ไปยัง /root/.ssh/id_rsa ของรูปภาพและเมื่อคุณจำเป็นต้องมีกุญแจสำคัญในการทำสิ่ง sshed เหมือนโคลนคอมไพล์จากลิงค์ repo ส่วนตัว ... ระหว่างการสร้างอิมเมจนักเทียบท่าของคุณ

อย่างไรก็ตามฉันพบวิธีแก้ไขปัญหาไม่ได้ชักชวน แต่ทำงานให้ฉันได้

  1. ใน dockerfile ของคุณ:

    • เพิ่มไฟล์นี้เป็น /root/.ssh/id_rsa
    • ทำในสิ่งที่คุณต้องการเช่น git clone นักแต่งเพลง ...
    • rm /root/.ssh/id_rsa ในตอนท้าย
  2. สคริปต์ที่ต้องทำในการถ่ายครั้งเดียว:

    • cp กุญแจของคุณไปยังโฟลเดอร์ที่เก็บ dockerfile
    • นักเทียบท่าสร้าง
    • rm คีย์ที่คัดลอก
  3. เมื่อใดก็ตามที่คุณต้องเรียกใช้คอนเทนเนอร์จากอิมเมจนี้ด้วยข้อกำหนด ssh เพียงเพิ่ม -v สำหรับคำสั่ง run เช่น:

    นักเทียบท่า run -v ~ / .ssh / id_rsa: /root/.ssh/id_rsa --name คำสั่งอิมเมจคอนเทนเนอร์

วิธีการแก้ปัญหานี้ส่งผลให้ไม่มีรหัสส่วนตัวในทั้งแหล่งที่มาของโครงการและอิมเมจ Docker ในตัวดังนั้นจึงไม่มีปัญหาด้านความปลอดภัยที่จะต้องกังวลอีกต่อไป


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 และ SSH ssh-agent bash -c "ssh-add..."เพิ่มในคำสั่งเดียวที่ชอบ: จากนั้นฉันก็สามารถผ่านไปทางขวาเข้าสู่การทำงานของนักเทียบท่า ตัวอย่างก่อนหน้านี้ทั้งหมดที่ฉันพบว่าใช้eval ssh-agentแล้วตามด้วย ssh-add และฉันไม่สามารถหาวิธีการส่งevalผ่านคำสั่งเรียกใช้นักเทียบท่าได้
ryanman

7

'คุณสามารถเลือกให้เซิร์ฟเวอร์ระยะไกลเข้าถึง ssh-agent ในพื้นที่ของคุณราวกับว่ากำลังทำงานบนเซิร์ฟเวอร์'

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


4
นักเทียบท่าเรียกใช้ -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

โปรดจำไว้ว่านักเทียบท่าทำงานด้วย sudo (เว้นแต่คุณจะไม่ทำ) หากเป็นกรณีนี้คุณจะใช้คีย์รูท ssh


การใช้วิธีนี้ทำงานร่วมกับนักเทียบท่า 0.11 แต่ถ้าคุณใช้มะเดื่อมันจะทำให้เกิดข้อผิดพลาดที่น่ากลัว ฉันไม่รู้ว่าทำไม
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+(ตรวจสอบเวอร์ชัน API ด้วยdocker version) บิลด์บิลด์อนุญาตให้--sshตัวเลือกที่มีซ็อกเก็ตเอเจนต์หรือคีย์อนุญาตให้ Docker Engine ส่งต่อการเชื่อมต่อเอเจนต์ SSH

สร้างคำสั่ง

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

Dockerfile

# 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 ของคุณมีคำตอบที่ดีมากมายที่นี่ หากคุณทำคำตอบที่ดีที่สุดที่ฉันพบคือจากลิงก์ในความคิดเห็นด้านบนไปยังความคิดเห็น GitHub นี้โดย diegocsandrim เพื่อให้คนอื่น ๆ มีแนวโน้มที่จะเห็นมันและในกรณีที่ repo หายไปนี่เป็นรุ่นแก้ไขของคำตอบนั้น:

โซลูชันส่วนใหญ่ในที่นี้จะทิ้งกุญแจส่วนตัวไว้ในภาพ นี่เป็นสิ่งที่ไม่ดีเนื่องจากทุกคนที่สามารถเข้าถึงรูปภาพได้เข้าถึงคีย์ส่วนตัวของคุณ เนื่องจากเราไม่รู้เกี่ยวกับพฤติกรรมของsquashสิ่งนี้อาจเป็นกรณีที่คุณลบคีย์และบีบเลเยอร์นั้น

เราสร้าง URL ที่ลงชื่อล่วงหน้าเพื่อเข้าถึงกุญแจด้วย aws s3 cli และ จำกัด การเข้าถึงประมาณ 5 นาทีเราบันทึก URL ที่ลงชื่อล่วงหน้านี้ไว้ในไฟล์ในไดเรกทอรี repo จากนั้นใน dockerfile เราเพิ่มลงในรูปภาพ

ใน dockerfile เรามีคำสั่ง RUN ที่ทำตามขั้นตอนเหล่านี้ทั้งหมด: ใช้ URL ล่วงหน้าเพื่อรับคีย์ ssh, รันการติดตั้ง npm และลบคีย์ ssh

ด้วยการทำสิ่งนี้ในคำสั่งเดียวคีย์ ssh จะไม่ถูกจัดเก็บในเลเยอร์ใด ๆ แต่ URL ที่ลงชื่อล่วงหน้าจะถูกเก็บไว้และนี่ไม่ใช่ปัญหาเนื่องจาก URL จะไม่ถูกต้องหลังจาก 5 นาที

สคริปต์การสร้างดูเหมือนว่า:

# 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 จะเปลี่ยนแปลงทุกครั้งการติดตั้ง npm จะไม่สามารถแคชได้แม้ว่าจะไม่มีการเปลี่ยนแปลงกับไฟล์ packages.json ดีกว่าที่จะได้รับคีย์ใน build.sh และตั้งค่าเป็นอาร์กิวเมนต์สำหรับสร้างเพื่อที่จะไม่เปลี่ยนแปลงทุกครั้ง
York Yang

3

ใน Docker รุ่นที่ใหม่กว่า (17.05) คุณสามารถใช้การสร้างแบบหลายขั้นตอนได้ ซึ่งเป็นตัวเลือกที่ปลอดภัยที่สุดเนื่องจากบิลด์ก่อนหน้านี้สามารถใช้งานได้โดยบิลด์ถัดไปเท่านั้นและจะถูกทำลาย

ดูคำตอบสำหรับคำถาม stackoverflow ของฉันสำหรับข้อมูลเพิ่มเติม


3

ภาพรวมสั้นของความท้าทายของ SSH ภายในภาชนะเทียบท่าที่มีรายละเอียดที่นี่ สำหรับการเชื่อมต่อกับรีโมตที่เชื่อถือได้จากภายในคอนเทนเนอร์โดยไม่มีการรั่วไหลของความลับมีสองสามวิธี:

นอกเหนือจากนี้ยังมีความเป็นไปได้ในการใช้ที่เก็บคีย์ในคอนเทนเนอร์นักเทียบท่าแยกต่างหากที่สามารถใช้งานได้เมื่อใช้งาน Compose ข้อเสียเปรียบที่นี่คือความซับซ้อนเพิ่มเติมเนื่องจากเครื่องจักรที่จำเป็นในการสร้างและจัดการที่เก็บคีย์เช่นVault โดย HashiCorpHashiCorp

สำหรับการใช้คีย์ SSH ในคอนเทนเนอร์ Docker แบบสแตนด์อะโลนดูวิธีการที่ลิงก์ด้านบนและพิจารณาข้อเสียของแต่ละข้อตามความต้องการเฉพาะของคุณ อย่างไรก็ตามหากคุณกำลังใช้งานภายใน Compose และต้องการแชร์คีย์กับแอพขณะรันไทม์ (สะท้อนให้เห็นถึงการใช้งานจริงของ OP) ลองทำดังนี้:

  • สร้างdocker-compose.envไฟล์และเพิ่มลงในของคุณ.gitignoreไฟล์
  • อัปเดตdocker-compose.ymlและเพิ่มของคุณenv_fileบริการที่ต้องใช้รหัส
  • เข้าถึงกุญแจสาธารณะจากสภาพแวดล้อมที่แอปพลิเคชันรันไทม์เช่นprocess.node.DEPLOYER_RSA_PUBKEYในกรณีของแอปพลิเคชัน Node.js

วิธีการดังกล่าวเหมาะสำหรับการพัฒนาและทดสอบและในขณะที่สามารถตอบสนองความต้องการการผลิตในการผลิตคุณจะดีขึ้นโดยใช้วิธีการอื่นที่ระบุไว้ข้างต้น

แหล่งข้อมูลเพิ่มเติม:


3

คุณสามารถใช้การสร้างแบบหลายขั้นตอนเพื่อสร้างคอนเทนเนอร์ได้ นี่คือวิธีการที่คุณสามารถทำได้: -

ขั้นตอนที่ 1 การสร้างภาพด้วย ssh

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 จาก build script เช่นนี้:

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 สาธารณะให้กับรูปภาพ แต่ในการทดลองของฉันฉันค้นพบว่า "นักเทียบท่า cp" สำหรับการคัดลอกจากคอนเทนเนอร์ไปยังโฮสต์ รายการ 3 ในคำตอบโดย creak ดูเหมือนว่าคุณสามารถใช้ 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

คุณสามารถส่งคีย์ที่ได้รับอนุญาตไปยังคอนเทนเนอร์ของคุณโดยใช้โฟลเดอร์แชร์และตั้งค่าการอนุญาตโดยใช้ไฟล์นักเทียบท่าเช่นนี้:

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

และการทำงานของนักเทียบท่าของคุณมีสิ่งต่อไปนี้เพื่อแชร์ไดเรกทอรีรับรองความถูกต้องบนโฮสต์ (ถือ authorised_keys) กับคอนเทนเนอร์จากนั้นเปิดพอร์ต ssh ซึ่งจะสามารถเข้าถึงได้ผ่านพอร์ต 7001 บนโฮสต์

-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
  • ข้อมูลสำคัญอื่น ๆ เช่นชื่อของฐานข้อมูลหรือเซิร์ฟเวอร์ภายใน
  • สตริงทั่วไปหรือเนื้อหาไบนารี (ขนาดไม่เกิน 500 kb)

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

ฉันกำลังพยายามหาวิธีเพิ่มคีย์การเซ็นชื่อลงในคอนเทนเนอร์ที่จะใช้ระหว่างรันไทม์ (ไม่ใช่บิลด์) และพบคำถามนี้ ความลับของนักเทียบท่าดูเหมือนจะเป็นคำตอบสำหรับกรณีการใช้งานของฉันและเนื่องจากไม่มีใครพูดถึงมันฉันจะเพิ่มมัน


0

ในกรณีของฉันฉันมีปัญหากับ nodejs และ 'npm i' จากที่เก็บระยะไกล ฉันแก้ไขมันได้เพิ่มผู้ใช้ 'node' ใน nodejs container และ 700 ถึง ~ / .ssh ใน container

Dockerfile:

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

นักเทียบท่า-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

วิธีที่ง่ายที่สุดรับบัญชี launchpad และใช้งาน: ssh-import-id


8
คำถามเกี่ยวกับกุญแจส่วนตัว ssh-import-idดูเหมือนว่าจะนำเข้ากุญแจสาธารณะเท่านั้น
cddr

-1

ในคอนเทนเนอร์นักเทียบท่าที่กำลังทำงานคุณสามารถออก ssh-keygen ด้วยตัวเลือกนักเทียบท่า -i (แบบโต้ตอบ) สิ่งนี้จะส่งต่อคอนเทนเนอร์ที่พร้อมต์เพื่อสร้างคีย์ภายในคอนเทนเนอร์นักเทียบท่า


1
แล้วไงต่อ? คุณไม่สามารถทำอะไรหลังจากนี้เพราะคุณไม่ได้รับอนุญาตให้ทำเช่นนั้น
Jonathon Reinhart

-1

สำหรับ debian / root / 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.