I try to clone a test project from GitLab using a Dockerfile and an SSH key pair: ssh-keygen -t rsa -P ""
. The private key is passwordless, the public key is published at the GitLab account.
This can be quickly tested by anyone else, just open an account on GitLab and publish your SSH public key, and add a new empty project to clone.
Without Docker, using ssh -i C:\path\to\my\private_key\id_rsa [email protected]
, it works. Without Docker, cloning the project also works.
I load the private key in the Dockerfile and delete it in the end. Not important, but for all who see a security risk here: I delete the key pair directly after usage, both on client and server. I only try to get around the password entry for the user account when cloning, since that does not seem to work during the run of a Dockerfile, and would be the real security risk as it could leave the password in the logs.
Start: Go to the Dockerfile directory, paste the private key "id_rsa" in a new ".ssh" subfolder. Then:
docker build -t NEW_IMAGENAME . --build-arg ssh_prv_key="$(cat ./.ssh/id_rsa)"
Working code up to now:
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
Which leads to:
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
The last steps after this working code in the Dockerfile would be as follows, though each of the first three lines stops the script up to now:
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
If
RUN ssh-add /root/.ssh/id_rsa
comes directly after the last working code:=> 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
The error Could not open a connection to your authentication agent.
is famous, see Could not open a connection to your authentication agent. But I could not solve it with that thread.
If
RUN ssh -tti /root/.ssh/id_rsa [email protected]
comes directly after the last working code:#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
If
RUN git clone [email protected]:GITLAB_USERNAME/test.git
comes directly after the last working code:#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
Thus, ssh obviously needs the "ssh-add" that adds the private key to the "ssh-agent" to know the private key on the client at all, and I guess it also needs the ssh -tti /root/.ssh/id_rsa [email protected]
to let ssh know the way to the server.
If
RUN ssh -Tvvv [email protected]
(the -T avoids Pseudo-terminal will not be allocated because stdin is not a terminal) comes directly after the last working code (this is not needed in the final Dockerfile, it is just a check):=> 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
I have tried a lot, but up to now, I could not solve the error read_passphrase: can't open /dev/tty: No such device or address
. The file exists, else I could not change its rights to 666, using chmod 666 /dev/tty
. I guess that a terminal is required just for entering an empty password.
What to change to clone a repo from GitLab with a passwordless SSH key pair, using just one Dockerfile?
If there is no chance to do this in just one Dockerfile, an accepted workaround would be a docker-compose file; this is not the favoured answer, though.
EDITED: The needed path and file can be found when looking into the container.
(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
The last command shows the id_rsa and the known_hosts.
d3cbc35351fd / # cd root/.ssh;ls
id_rsa known_hosts
And if I run d3cbc35351fd .ssh # ssh -Tvvv [email protected]
inside the container, I am asked for the password:
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
This is a try with "", '' and just pressing enter, they all do not work.
If I cannot use SSH in the Dockerfile and neither in the container of that Dockerfile' image, I wonder whether cloning a repo out of a Dockerfile or container is possible at all. I guess that suppressing the password entry will be the next big step to solve this, but even that might not solve it entirely, since I have already tried entering an empty password in the container, to no avail.
read_passphrase: ...
. I suppose the real cause ofread_passphrase
is that the key isn't be accepted. You should try todocker run
into the container and try it there and verify that the private key is stored correct. And add more verbosity byssh -vvv [email protected]
-vvv
parameter, see the edited answer. You are right, the/root
is empty in the container, obviously, there is no/root/.ssh/id_rsa
either, then. There is, though, a green-marked/tmp/ssh-TI6EWavBoyJC
folder with the fileagent.8
in it. (the steps:docker run -it --name test_bash -d MYIMAGE:latest
, thendocker exec -it test_bash /bin/bash
,cd root
,ls
)mkdir -p /root/.ssh && chmod 700 /root/.ssh
git clone
while building the image? Or is it possible to clone while running the container?700
, to no avail. I also triedCOPY id_rsa
(with "id_rsa" in the same folder as the Dockerfile) instead ofecho "$ssh_prv_key"
.git clone
should happen inside the Dockerfile, I just want to have an installation of everything in one go, without adding another step of cloning. If that is not possible, I will go over to a docker-compose approach where the cloning is done only after the main image was built. If that is not possible again, I would do the cloning manually, then I would just use my password and no key pair would be used.