我嘗試使用 Dockerfile 和 SSH 金鑰對從 GitLab 克隆一個測試專案:ssh-keygen -t rsa -P ""
。私鑰無密碼,公鑰發佈在 GitLab 帳號上。
其他人可以快速測試這一點,只需在 GitLab 上開設帳戶並發布您的 SSH 公鑰,然後添加新的空白專案進行克隆即可。
沒有 Docker,使用,它就可以工作。沒有 Docker,克隆專案也可以工作。ssh -i C:\path\to\my\private_key\id_rsa [email protected]
我將私鑰載入到 Dockerfile 中,最後將其刪除。並不重要,但對於所有在這裡看到安全風險的人來說:我在使用後直接刪除客戶端和伺服器上的金鑰對。我只在克隆時嘗試繞過用戶帳戶的密碼輸入,因為這在 Dockerfile 運行期間似乎不起作用,並且將是真正的安全風險,因為它可能會將密碼留在日誌中。
開始:前往 Dockerfile 目錄,將私鑰「id_rsa」貼到新的「.ssh」子資料夾中。然後:
docker build -t NEW_IMAGENAME . --build-arg ssh_prv_key="$(cat ./.ssh/id_rsa)"
到目前為止的工作代碼:
FROM vcatechnology/linux-mint:18.2
ARG ssh_prv_key
RUN apt-get update && \
apt upgrade -y && \
apt-get install -y git
RUN apt-get install -y openssh-client # openssh-server
RUN mkdir /root/.ssh/
RUN echo "Host *\n User git\n HostName gitlab.com\n AddKeysToAgent yes\n IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa
RUN ssh-keyscan -t rsa -H gitlab.com >> /root/.ssh/known_hosts
RUN ssh -o StrictHostKeyChecking=no [email protected] || true
RUN eval "$(ssh-agent -s)"
RUN chmod 666 /dev/tty
這導致:
docker build -t CONTAINERNAME . --build-arg ssh_prv_key="$(cat /.ssh/id_rsa)"
[+] Building 254.9s (14/17)
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 6.84kB 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/vcatechnology/linux-mint:18.2 0.8s
=> CACHED [ 1/14] FROM docker.io/vcatechnology/linux-mint:18.2@sha256:0557a4999d43c0c622f3a57c3db5b13536024fb5999ecf4f03c6ffec0e4fdb47 0.0s
=> [ 2/14] RUN apt-get update && apt upgrade -y && apt-get install -y git 244.3s
=> [ 3/14] RUN apt-get install -y openssh-client # openssh-server 3.1s
=> [ 4/14] RUN mkdir /root/.ssh/ 0.6s
=> [ 5/14] RUN echo "Host *\n User git\n HostName gitlab.com\n AddKeysToAgent yes\n IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config 0.6s
=> [ 6/14] RUN echo "$(cat /.ssh/id_rsa)" > /root/.ssh/id_rsa && chmod 600 /root/.ssh/id_rsa 0.6s
=> [ 7/14] RUN ssh-keyscan -t rsa -H gitlab.com >> /root/.ssh/known_hosts 1.3s
=> [ 8/14] RUN ssh -o StrictHostKeyChecking=no [email protected] || true 1.6s
=> [ 9/14] RUN eval "$(ssh-agent -s)" 0.6s
=> [10/14] RUN chmod 666 /dev/tty 0.6s
Dockerfile 中此工作程式碼之後的最後步驟如下,但到目前為止,前三行中的每一行都停止了腳本:
RUN ssh-add /root/.ssh/id_rsa
RUN ssh -tti /root/.ssh/id_rsa [email protected]
RUN git clone [email protected]:GITLAB_USERNAME/test.git
RUN rm -r /root/.ssh
如果
RUN ssh-add /root/.ssh/id_rsa
直接出現在最後一個工作代碼之後:=> ERROR [11/14] RUN ssh-add /root/.ssh/id_rsa 0.6s ------ > [11/14] RUN ssh-add /root/.ssh/id_rsa: #14 0.579 Could not open a connection to your authentication agent. ------ executor failed running [/bin/sh -c ssh-add /root/.ssh/id_rsa]: exit code: 2
該錯誤Could not open a connection to your authentication agent.
很有名,請參閱無法開啟與您的身份驗證代理程式的連接。但我無法用該線程解決它。
如果直接出現在最後一個工作代碼之後:
RUN ssh -tti /root/.ssh/id_rsa [email protected]
#14 1.545 Permission denied (publickey,keyboard-interactive). ------ executor failed running [/bin/sh -c ssh -tti /root/.ssh/id_rsa [email protected]]: exit code: 255
如果直接出現在最後一個工作代碼之後:
RUN git clone [email protected]:GITLAB_USERNAME/test.git
#16 0.450 Cloning into 'test'... #16 1.466 Permission denied (publickey,keyboard-interactive). #16 1.467 fatal: Could not read from remote repository. #16 1.467 #16 1.467 Please make sure you have the correct access rights #16 1.467 and the repository exists. ------ executor failed running [/bin/sh -c git clone [email protected]:GITLAB_USERNAME/test.git]: exit code: 128
因此,ssh顯然需要「ssh-add」將私鑰添加到「ssh-agent」才能知道客戶端上的私鑰,而且我猜它還需要讓ssh知道通往伺服器的方式。ssh -tti /root/.ssh/id_rsa [email protected]
如果(-T 避免
RUN ssh -Tvvv [email protected]
偽終端不會被分配,因為 stdin 不是終端) 直接出現在最後一個工作代碼之後(這在最終的 Dockerfile 中不需要,它只是一個檢查):=> ERROR [12/12] RUN ssh -Tvvv [email protected] 1.2s ------ > [12/12] RUN ssh -Tvvv [email protected]: #16 0.376 OpenSSH_7.2p2 Ubuntu-4ubuntu2.10, OpenSSL 1.0.2g 1 Mar 2016 #16 0.376 debug1: Reading configuration data /etc/ssh/ssh_config #16 0.376 debug1: /etc/ssh/ssh_config line 19: Applying options for * #16 0.376 debug1: /etc/ssh/ssh_config line 57: Applying options for * #16 0.376 debug2: resolving "gitlab.com" port 22 #16 0.397 debug2: ssh_connect_direct: needpriv 0 #16 0.397 debug1: Connecting to gitlab.com [172.65.251.78] port 22. #16 0.450 debug1: Connection established. #16 0.450 debug1: permanently_set_uid: 0/0 #16 0.450 debug1: key_load_public: No such file or directory #16 0.450 debug1: identity file /root/.ssh/id_rsa type -1 #16 0.450 debug1: key_load_public: No such file or directory #16 0.450 debug1: identity file /root/.ssh/id_rsa-cert type -1 #16 0.451 debug1: Enabling compatibility mode for protocol 2.0 #16 0.451 debug1: Local version string SSH-2.0-OpenSSH_7.2p2 Ubuntu-4ubuntu2.10 #16 0.977 debug1: Remote protocol version 2.0, remote software version OpenSSH_7.9p1 Debian-10+deb10u2 #16 0.977 debug1: match: OpenSSH_7.9p1 Debian-10+deb10u2 pat OpenSSH* compat 0x04000000 #16 0.977 debug2: fd 3 setting O_NONBLOCK #16 0.977 debug1: Authenticating to gitlab.com:22 as 'git' #16 0.977 debug3: hostkeys_foreach: reading file "/root/.ssh/known_hosts" #16 0.977 debug3: send packet: type 20 #16 0.977 debug1: SSH2_MSG_KEXINIT sent #16 0.994 debug3: receive packet: type 20 #16 0.994 debug1: SSH2_MSG_KEXINIT received #16 0.994 debug2: local client KEXINIT proposal #16 0.994 debug2: KEX algorithms: [email protected],ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,ext-info-c #16 0.994 debug2: host key algorithms: [email protected],[email protected],[email protected],[email protected],[email protected],ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa #16 0.994 debug2: ciphers ctos: [email protected],aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected],aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc #16 0.994 debug2: ciphers stoc: [email protected],aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected],aes128-cbc,aes192-cbc,aes256-cbc,3des-cbc #16 0.994 debug2: MACs ctos: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1 #16 0.994 debug2: MACs stoc: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1 #16 0.994 debug2: compression ctos: none,[email protected],zlib #16 0.994 debug2: compression stoc: none,[email protected],zlib #16 0.994 debug2: languages ctos: #16 0.994 debug2: languages stoc: #16 0.994 debug2: first_kex_follows 0 #16 0.994 debug2: reserved 0 #16 0.994 debug2: peer server KEXINIT proposal #16 0.994 debug2: KEX algorithms: curve25519-sha256,[email protected],ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1 #16 0.994 debug2: host key algorithms: rsa-sha2-512,rsa-sha2-256,ssh-rsa,ecdsa-sha2-nistp256,ssh-ed25519 #16 0.994 debug2: ciphers ctos: [email protected],aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected] #16 0.994 debug2: ciphers stoc: [email protected],aes128-ctr,aes192-ctr,aes256-ctr,[email protected],[email protected] #16 0.994 debug2: MACs ctos: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1 #16 0.994 debug2: MACs stoc: [email protected],[email protected],[email protected],[email protected],[email protected],[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1 #16 0.994 debug2: compression ctos: none,[email protected] #16 0.994 debug2: compression stoc: none,[email protected] #16 0.994 debug2: languages ctos: #16 0.994 debug2: languages stoc: #16 0.994 debug2: first_kex_follows 0 #16 0.994 debug2: reserved 0 #16 0.994 debug1: kex: algorithm: [email protected] #16 0.994 debug1: kex: host key algorithm: ecdsa-sha2-nistp256 #16 0.994 debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none #16 0.994 debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none #16 1.014 debug3: send packet: type 30 #16 1.014 debug1: expecting SSH2_MSG_KEX_ECDH_REPLY #16 1.182 debug3: receive packet: type 31 #16 1.185 debug1: Server host key: ecdsa-sha2-nistp256 SHA256:HbW3g8zUjNSksFbqTiUWPWg2Bq1x8xdGUrliXFzSnUw #16 1.186 debug3: hostkeys_foreach: reading file "/root/.ssh/known_hosts" #16 1.187 debug3: hostkeys_foreach: reading file "/root/.ssh/known_hosts" #16 1.187 debug1: read_passphrase: can't open /dev/tty: No such device or address #16 1.188 Host key verification failed. ------ executor failed running [/bin/sh -c ssh -Tvvv [email protected]]: exit code: 255
我已經嘗試了很多,但到目前為止,我無法解決該錯誤read_passphrase: can't open /dev/tty: No such device or address
。該文件存在,否則我無法使用chmod 666 /dev/tty
.我猜想輸入空密碼就需要終端。
若要使用無密碼 SSH 金鑰對、僅使用一個 Dockerfile 從 GitLab 複製儲存庫,需要進行哪些變更?
如果沒有機會在一個 Dockerfile 中做到這一點,一個可接受的解決方法是 docker-compose 檔案;但這不是受歡迎的答案。
編輯:查看容器時可以找到所需的路徑和檔案。
(The start was: docker build -t . --build-arg ssh_prv_key="$(cat ./.ssh/id_rsa)", until the end of the working code only!)
docker run -d -it --name test_bash -d NEW_IMAGENAME:latest
docker exec -it test_bash bash
cd root/.ssh;ls
最後一個指令顯示 id_rsa 和known_hosts。
d3cbc35351fd / # cd root/.ssh;ls
id_rsa known_hosts
如果我在容器內運行,系統會要求我輸入密碼:d3cbc35351fd .ssh # ssh -Tvvv [email protected]
Enter passphrase for key '/root/.ssh/id_rsa':
debug2: bad passphrase given, try again...
Enter passphrase for key '/root/.ssh/id_rsa':
debug2: bad passphrase given, try again...
Enter passphrase for key '/root/.ssh/id_rsa':
debug2: no passphrase given, try next key
這是用“”,''嘗試的,只是按回車鍵,它們都不起作用。
如果我無法在 Dockerfile 中使用 SSH,也無法在該 Dockerfile 映像的容器中使用 SSH,我想知道是否可以從 Dockerfile 或容器中克隆儲存庫。我想抑制密碼輸入將是解決此問題的下一個重要步驟,但即使這樣也可能無法完全解決問題,因為我已經嘗試在容器中輸入空密碼,但無濟於事。
答案1
如果您出於安全原因想要刪除圖像中的私鑰,或者需要更多信息,請參閱在 docker 容器內使用 SSH 金鑰並提供更徹底的答案。
主要錯誤是由
echo "$ssh_prv_key" > /root/.ssh/id_rsa
儘管私鑰需要很多行,但它僅將格式錯誤的 ssh_prv_key 作為一行傳遞。這個想法來自將私鑰加入docker檔案中的ssh-agent這暗示著Gitlab CI/Docker:ssh-add 不斷要求輸入密碼。
--> 因此,不要使用RUN echo ...
私鑰,而是使用COPY ...
!
另一個小錯誤是,它不起作用,但是RUN ssh -o StrictHostKeyChecking=no [email protected] || true
兩個都
RUN echo "Host *\n\t StrictHostKeyChecking no" >> /etc/ssh/ssh_config
和
RUN ssh-keyscan -t rsa -H gitlab.com >> /root/.ssh/known_hosts
工作並達到相同的目標,僅選擇兩者之一。
另一個步驟是刪除ssh-agent
和ssh-add
。只有當您需要時,才需要兩者有密碼,參見將私鑰加入docker檔案中的ssh-agent。
這現在正在發揮作用。
Dockerfile 如下所示:
FROM ubuntu:latest
RUN apt-get update && apt-get install -y git
RUN mkdir -p /root/.ssh && chmod 700 /root/.ssh
COPY /.ssh/id_rsa /root/.ssh/id_rsa
RUN chmod 600 /root/.ssh/id_rsa
RUN ssh-keyscan -t rsa -H gitlab.com >> /root/.ssh/known_hosts
RUN git clone [email protected]:GITLAB_USERNAME/test.git
RUN rm -r /root/.ssh
若要從 Dockerfile 建立映像:
進入Dockerfile所在目錄。
將您的私鑰“id_rsa”(或您擁有的任何名稱,當然,然後更改程式碼)貼到新的子資料夾“/.ssh/”中(或將其貼到 Dockerfile 目錄中並將程式碼更改為
COPY id_rsa /root/.ssh/id_rsa
)。開始 (不要忘記“。”最後,這是建構上下文):
docker build -t test .
答案2
ssh-agent 在建置過程中無法按預期工作,但您根本不需要它。
我建立了一個可行的最小樣本
FROM ubuntu:latest
ARG ssh_prv_key
RUN apt-get update \
&& apt-get install -y git
RUN mkdir -p /root/.ssh && chmod 700 /root/.ssh
RUN echo "$ssh_prv_key" > /root/.ssh/id_rsa && \
chmod 600 /root/.ssh/id_rsa
# Check if the key was successfully copied
# RUN cat -n /root/.ssh/id_rsa
# Dummy ssh to store the host into known_hosts
# The expected output is something like:
# Hi <user>! You've successfully authenticated, but GitHub does not provide shell access.
RUN ssh -T -o StrictHostKeyChecking=no [email protected] || true
RUN git clone ssh://[email protected]/<myrepo>
答案3
就我而言,錯誤read_passphrase: can't open /dev/tty: No such device or address
是由 ssh 提示新增主機的權限所引起的。按照這個答案新增到您的 ssh 配置
StrictHostKeyChecking no
如果您的 ssh 用戶端支援它,請使用它accept-new
而不是no
出於安全考慮。