Я пытаюсь клонировать тестовый проект из GitLab, используя Dockerfile и пару ключей SSH: 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
. Файл существует, иначе я не смог бы изменить его права на 666, используя chmod 666 /dev/tty
. Я предполагаю, что терминал требуется только для ввода пустого пароля.
Что нужно изменить, чтобы клонировать репозиторий из GitLab с помощью пары ключей SSH без пароля, используя всего один Dockerfile?
Если нет возможности сделать это всего в одном 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
Это попытка с "", '' и простым нажатием Enter, они все не работают.
Если я не могу использовать SSH в Dockerfile и ни в контейнере образа этого Dockerfile, интересно, возможно ли вообще клонирование репозитория из Dockerfile или контейнера. Я предполагаю, что подавление ввода пароля будет следующим большим шагом к решению этой проблемы, но даже это может не решить ее полностью, так как я уже пытался ввести пустой пароль в контейнер, но безрезультатно.
решение1
Если вы хотите избавиться от закрытого ключа на изображении по соображениям безопасности или вам нужна дополнительная информация, см.Использование ключей SSH внутри контейнера Dockerс более подробным ответом.
Основная ошибка возникает из-за
echo "$ssh_prv_key" > /root/.ssh/id_rsa
который передает неправильно отформатированный ssh_prv_key, как всего одну строку, хотя для закрытого ключа нужно много строк. Идея изДобавьте закрытый ключ к ssh-agent в файле dockerчто намекает на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
. Оба нужны только если выиметьпароль, см.Добавьте закрытый ключ к ssh-agent в файле docker.
Теперь это работает.
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
в целях безопасности.