У меня есть приложение, которое выполняет различные забавные вещи с помощью Git (например, запуск git clone & git push), и я пытаюсь сделать это в docker-ize.
Однако я сталкиваюсь с проблемой, когда мне нужно иметь возможность добавить ключ 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
Ответы:
Это более сложная проблема, если вам нужно использовать SSH во время сборки. Например, если вы используете
git clone
, или в моем случаеpip
иnpm
для загрузки из частного хранилища.Решение, которое я нашел, состоит в том, чтобы добавить ваши ключи, используя
--build-arg
флаг. Затем вы можете использовать новую экспериментальную--squash
команду (добавлена 1.13), чтобы объединить слои, чтобы ключи больше не были доступны после удаления. Вот мое решение:Команда построения
Dockerfile
Обновление: если вы используете Docker 1.13 и у вас есть экспериментальные функции, вы можете добавить
--squash
команду build, которая объединит слои, удаляя ключи SSH и скрывая их отdocker history
.источник
id_rsa.pub
файла, так как это не требуется.$(openssl rsa -in ~/.ssh/id_rsa)
вместо этогоОказывается, при использовании Ubuntu ssh_config не верен. Вам нужно добавить
в ваш Dockerfile, чтобы он распознал ваш ключ ssh.
источник
RUN echo " Host example.com" >> /root/.ssh/config RUN echo " User <someusername>" >> /root/.ssh/config
Ключ ssh остается в пределах изображения, даже если вы удалите ключ в команде слоя после его добавления (см. Комментарии в этом посте ).
В моем случае это нормально, вот что я использую:
источник
Если вы используете docker compose , простой способ - перенаправить SSH-агент следующим образом:
источник
SSH_AUTH_SOCK
переменная, которая содержит путь к ssh-агентуSSH_AUTH_SOCK
blog.joncairns.com/2013/12/understanding-ssh-agent-and-ssh-add$SSH_AUTH_SOCK
вы должны монтировать этот путь -/run/host-services/ssh-auth.sock
.Расширяя ответ Питера Грейнджера, я смог использовать многоступенчатую сборку, доступную с Docker 17.05. Официальная страница гласит:
Имея это в виду, вот мой пример
Dockerfile
включения трех этапов сборки. Он предназначен для создания производственного образа клиентского веб-приложения..dockerignore
повторяет содержимое.gitignore
файла (предотвращает копированиеnode_modules
и последующиеdist
каталоги проекта):Пример команды для построения изображения:
Если ваш закрытый ключ SSH не имеет парольной фразы, просто укажите пустой
SSH_KEY_PASSPHRASE
аргумент.Вот как это работает:
1). Только на первом этапе
package.json
,yarn.lock
файлы и секретный ключ SSH копируются первым промежуточным изображением имениsources
. Чтобы избежать дальнейших запросов парольной фразы ключа SSH, она автоматически добавляется вssh-agent
. в заключениеyarn
команда устанавливает все необходимые зависимости от NPM и клонирует частные репозитории git из Bitbucket через SSH.2). Второй этап создает и минимизирует исходный код веб-приложения и помещает его в
dist
каталог следующего промежуточного изображения с именемproduction
. Обратите внимание, что исходный код установленnode_modules
скопирован из образа с именем,sources
созданным на первом этапе этой строкой:Возможно, это также может быть следующая строка:
У нас есть только
node_modules
каталог из первого промежуточного изображения здесь, нетSSH_KEY
иSSH_KEY_PASSPHRASE
аргументов больше. Все остальное, необходимое для сборки, скопировано из каталога нашего проекта.3). На третьем этапе мы уменьшаем размер конечного изображения, которое будет помечено как
ezze/geoport:0.6.0
включающее толькоdist
каталог из второго промежуточного изображения с именемproduction
и устанавливая Node Express для запуска веб-сервера.Список изображений дает вывод, как это:
где немаркированные изображения соответствуют первому и второму промежуточным этапам сборки.
Если вы бежите
Вы не увидите никаких упоминаний
SSH_KEY
иSSH_KEY_PASSPHRASE
в конечном изображении.источник
Identity added: /root/.ssh/id_rsa (/root/.ssh/id_rsa)
но когда я проверяю в другом RUN или даже в том же RUN Команда, выполнив a,ssh-add -l
говорит мне, что «Агент не имеет идентичности». Начинаете стягивать с меня волосы, есть мысли?Чтобы ввести ваш ключ ssh, в контейнере у вас есть несколько решений:
Используя Dockerfile с
ADD
инструкцией, вы можете добавить его во время процесса сборкиПросто делать что-то вроде
cat id_rsa | docker run -i <image> sh -c 'cat > /root/.ssh/id_rsa'
Использование
docker cp
команды, которая позволяет вводить файлы во время работы контейнера.источник
apt-get install openssh-server
и поместил свой ключ в /root/.ssh/id_rsa, и он работал нормально. Какое изображение вы используете?Одним из кроссплатформенных решений является использование привязки для совместного использования
.ssh
папки хоста с контейнером:Подобно переадресации агента, этот подход сделает открытые ключи доступными для контейнера. Дополнительным преимуществом является то, что он работает и с пользователем без полномочий root и подключит вас к GitHub. Однако следует учесть, что все содержимое (включая закрытые ключи) из
.ssh
папки будет общим, поэтому этот подход желателен только для разработки и только для доверенных образов контейнера.источник
docker build
только во времяdocker run
docker-compose up
в моей локальной Windows 10. Как мне использовать ваше решение в этом сценарии?Контейнеры Docker следует рассматривать как собственные «сервисы». Чтобы разделить проблемы, вы должны разделить функции:
1) Данные должны находиться в контейнере данных: используйте связанный том, чтобы клонировать репо. Затем этот контейнер данных может быть связан с сервисом, которому он нужен.
2) Используйте контейнер для запуска задачи клонирования git (т. Е. Это только клонирование задания), связывая контейнер данных с ним при запуске.
3) То же самое для ssh-ключа: поместите это том (как предложено выше) и свяжите его со службой git clone, когда вам это нужно
Таким образом, и задача клонирования, и ключ являются эфемерными и активными только при необходимости.
Теперь, если само ваше приложение представляет собой интерфейс git, вы можете рассмотреть возможность использования API-интерфейсов REST github или bitbucket непосредственно для своей работы: для этого они и были разработаны.
источник
Эта строка является проблемой:
При указании файлов, которые вы хотите скопировать в изображение, вы можете использовать только относительные пути - относительно каталога, в котором находится ваш файл Dockerfile. Так что вместо этого вы должны использовать:
И поместите файл id_rsa в тот же каталог, где находится ваш Dockerfile.
Проверьте это для более подробной информации: http://docs.docker.io/reference/builder/#add
источник
docker cp
просто кладет его в контейнер, а не изображение, верно?У нас была похожая проблема при установке npm во время сборки Docker.
Вдохновленный решением от Daniel van Flymen и объединив его с git url rewrite , мы нашли немного более простой способ аутентификации установки npm из частных репозиториев github - мы использовали токены oauth2 вместо ключей.
В нашем случае зависимости npm были указаны как "git + https://github.com/ ..."
Для аутентификации в контейнере необходимо переписать URL-адреса, чтобы они подходили для аутентификации ssh (ssh: //git@github.com/) или для аутентификации токена (https: // $ {GITHUB_TOKEN} @ github.com /)
Команда построения:
К сожалению, я нахожусь на докере 1.9, поэтому опции --squash еще нет, в конце концов ее нужно добавить
Dockerfile:
источник
Перешлите сокет аутентификации ssh в контейнер:
Ваш сценарий сможет выполнить
git clone
.Дополнительно: если вы хотите, чтобы клонированные файлы принадлежали определенному пользователю, вам нужно использовать,
chown
так как использование другого пользователя, кроме root, внутри контейнера сделаетgit
сбою.Вы можете сделать эту публикацию в среде контейнера некоторых дополнительных переменных:
После клонирования вы должны выполнить
chown $OWNER_USER:$OWNER_GROUP -R <source_folder>
установку правильного владельца, прежде чем покинуть контейнер, чтобы файлы были доступны пользователю без полномочий root вне контейнера.источник
-u root:$(id -u $USER)
по крайней мере, файлы, принадлежащие той же основной группе, что и ваш пользователь, что должно сделать их все по крайней мере читабельными,sudo
если только кто-то не создает их с0600
разрешениями.-u root:$(id -u $USER)
должно быть-g
./tmp/ssh_auth.sock: No such file or directory
сейчас он/tmp/ssh-vid8Zzi8UILE/agent.46016
на моей принимающей машине/tmp
внутри вашего контейнера. Или опечатка в команде запуска Docker. Убедитесь, что оператор связывания правильный-v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock
: порядок важен, точка с запятой также важна. Пожалуйста, проверьте докер документацию для получения дополнительной помощи.Как уже прокомментировал eczajk в ответе Даниеля ван Флаймена, извлекать ключи и использовать
--squash
их небезопасно , так как они все еще будут видны в истории (docker history --no-trunc
).Вместо этого с Docker 18.09 вы можете теперь использовать функцию «строить секреты». В моем случае я клонировал частное git-репо, используя мой SSH-ключ hosts, со следующим в моем Dockerfile:
Чтобы использовать это, вам нужно включить новый бэкэнд BuildKit перед запуском
docker build
:И вам нужно добавить
--ssh default
параметр вdocker build
.Больше информации об этом здесь: https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066
источник
ssh-add ~/.ssh/id_rsa
и 2) добавить хост git в known_hosts, то есть для bitbucket:RUN ssh-keyscan -H bitbucket.org >> ~/.ssh/known_hosts
Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access and the repository exists.
несмотря на передачу--ssh default
флага в моей сборке Docker и использование--mount=type=ssh
команды run, где яgit clone
. Я могу клонировать тот же репо без проблем на сборочной машине. Он просто не работает в контейнере сборки Docker. Я подозреваю, что Mac-версия Docker фактически не передает ssh-клиент.Эта проблема действительно раздражает. Поскольку вы не можете добавить / скопировать какой-либо файл вне контекста dockerfile, это означает, что невозможно просто связать ~ / .ssh / id_rsa в /root/.ssh/id_rsa изображения, и когда вам определенно нужен ключ для выполнения каких-либо sshed как git clone из приватной ссылки репо ... во время создания вашего образа докера.
В любом случае, я нашел решение обходного пути, не настолько убедительное, но сработало для меня.
в вашем докер-файле:
скрипт, который нужно сделать за один раз:
каждый раз, когда вам нужно запустить контейнер из этого образа с некоторыми требованиями ssh, просто добавьте -v для команды run, например:
docker запустите -v ~ / .ssh / id_rsa: /root/.ssh/id_rsa - имя команды контейнера изображения
Это решение не приводит к закрытому ключу ни в исходном проекте, ни во встроенном образе докера, поэтому больше не нужно беспокоиться о безопасности.
источник
docker cp
? Он используется для «Копирования файлов / папок между контейнером и вашим хостом».docker cp
мог бы добиться цели. Однако в этой самой ситуации мне понадобился ключ ssh_key во время создания образа, и в то время контейнера не было ... обновит мое неясное выражение, в любом случае, спасибо.Я столкнулся с той же проблемой сегодня и немного модифицированной версии с предыдущими постами, я нашел этот подход более полезным для меня
(Обратите внимание, что флаг readonly, поэтому контейнер ни в коем случае не испортит мой ключ ssh.)
Внутри контейнера теперь я могу запустить:
Так что я не понимаю ту
Bad owner or permissions on /root/.ssh/..
ошибку, которая была замечена @krossисточник
ssh-agent bash -c "ssh-add..."
. Затем я могу передать это прямо в Docker Run. Все предыдущие примеры, которые я нашел, использовалисьeval ssh-agent
, затем следовал ssh-add, и я не мог найти способ передать этоeval
через команду docker run.«Вы можете выборочно разрешить удаленным серверам обращаться к вашему локальному ssh-агенту, как если бы он работал на сервере»
https://developer.github.com/guides/using-ssh-agent-forwarding/
источник
Вы также можете связать каталог .ssh между хостом и контейнером, я не знаю, имеет ли этот метод какие-либо последствия для безопасности, но это может быть самый простой метод. Примерно так должно работать:
Помните, что docker запускается с помощью sudo (если вы этого не делаете), в этом случае вы будете использовать корневые ssh-ключи.
источник
Bad owner or permissions on /root/.ssh/config
.docker run
, но не во времяdocker build
.Начиная с
docker API 1.39+
(проверьте версию API с помощьюdocker version
) сборки docker, вы можете--ssh
выбрать опцию с сокетом агента или ключами, чтобы Docker Engine мог перенаправлять соединения агента SSH.Команда сборки
Dockerfile
Больше информации:
источник
could not parse ssh: [default=~/.ssh/id_rsa]: stat ~/.ssh/id_rsa: no such file or directory
. Используйте полный путь, если он не работает.Если вы не заботитесь о безопасности своих ключей SSH, здесь есть много хороших ответов. Если да, лучший ответ, который я нашел, был по ссылке в комментарии выше на этот комментарий GitHub от diegocsandrim . Так что другие с большей вероятностью увидят это, и на случай, если репо когда-нибудь исчезнет, вот отредактированная версия этого ответа:
Большинство решений в конечном итоге оставляют закрытый ключ в изображении. Это плохо, так как любой, имеющий доступ к изображению, имеет доступ к вашему личному ключу. Поскольку мы недостаточно знаем о поведении
squash
, это все равно может иметь место, даже если вы удалите ключ и раздавите этот слой.Мы генерируем предварительный URL-адрес для доступа к ключу с помощью aws s3 cli и ограничиваем доступ примерно на 5 минут. Мы сохраняем этот предварительный URL-адрес в файле в каталоге репо, затем в dockerfile добавляем его к изображению.
В dockerfile у нас есть команда RUN, которая выполняет все эти шаги: используйте предварительно введенный URL-адрес, чтобы получить ключ ssh, запустите npm install и удалите ключ ssh.
Делая это в одной команде, ключ ssh не будет сохранен ни на одном слое, но будет сохранен предварительно подписанный URL-адрес, и это не проблема, поскольку URL-адрес не будет действительным через 5 минут.
Сценарий сборки выглядит так:
Dockerfile выглядит так:
источник
В более поздних версиях Docker (17.05) вы можете использовать многоэтапные сборки . Какой самый безопасный вариант, так как предыдущие сборки могут быть использованы только последующими, а затем уничтожены
См. Ответ на мой вопрос stackoverflow для получения дополнительной информации
источник
Краткий обзор проблем SSH внутри контейнеров Docker подробно описан здесь . Для подключения к доверенным удаленным устройствам из контейнера без утечки секретов существует несколько способов:
~/.ssh
в контейнер. (Только разработка, потенциально небезопасно)Помимо этого есть также возможность использовать хранилище ключей, работающее в отдельном контейнере Docker, доступном во время выполнения при использовании Compose. Недостатком здесь является дополнительная сложность из-за механизма, необходимого для создания и управления хранилищем ключей, такого как Vault от HashiCorp .
Для использования ключа SSH в автономном контейнере Docker см. Методы, указанные выше, и рассмотрите недостатки каждого из них в зависимости от ваших конкретных потребностей. Однако, если вы работаете внутри Compose и хотите поделиться ключом к приложению во время выполнения (отражая практические возможности OP), попробуйте это:
docker-compose.env
файл и добавьте его в свой.gitignore
файл.docker-compose.yml
и добавьтеenv_file
для службы, требующей ключ.process.node.DEPLOYER_RSA_PUBKEY
в случае приложения Node.js.Вышеуказанный подход идеален для разработки и тестирования, и, хотя он может удовлетворить производственные требования, на производстве вам лучше использовать один из других методов, указанных выше.
Дополнительные ресурсы:
источник
Вы можете использовать многоэтапную сборку для построения контейнеров. Это подход, который вы можете использовать:
Стадия 1 построение образа с помощью ssh
Этап 2: построить свой контейнер
добавьте атрибут env в ваш файл compose:
затем передайте аргументы из сценария сборки следующим образом:
И удалите промежуточный контейнер для безопасности. Это поможет вам ура.
источник
Простой и безопасный способ добиться этого без сохранения ключа в слое изображения Docker или прохождения гимнастики ssh_agent:
В качестве одного из шагов в вашем
Dockerfile
, создайте.ssh
каталог, добавив:RUN mkdir -p /root/.ssh
Ниже указано, что вы хотите смонтировать каталог ssh как том:
VOLUME [ "/root/.ssh" ]
Убедитесь, что ваш контейнер
ssh_config
знает, где найти открытые ключи, добавив следующую строку:RUN echo " IdentityFile /root/.ssh/id_rsa" >> /etc/ssh/ssh_config
Предоставьте
.ssh
каталог локального пользователя контейнеру во время выполнения:docker run -v ~/.ssh:/root/.ssh -it image_name
Или в вашем
dockerCompose.yml
добавить это под ключ громкости службы:- "~/.ssh:/root/.ssh"
Ваш финал
Dockerfile
должен содержать что-то вроде:источник
Я пытаюсь решить проблему другим способом: добавить открытый ключ ssh к изображению. Но в своих испытаниях я обнаружил, что "docker cp" предназначен для копирования из контейнера на хост. Пункт 3 в ответе скрипит, кажется, говорит, что вы можете использовать docker cp для внедрения файлов в контейнер. См. Https://docs.docker.com/engine/reference/commandline/cp/.
выдержка
источник
Вы можете передать авторизованные ключи в свой контейнер с помощью общей папки и установить разрешения с помощью файла Docker, например:
И ваш докерский прогон содержит что-то вроде следующего для совместного использования каталога auth на хосте (содержащего authorised_keys) с контейнером, после чего откройте порт ssh, который будет доступен через порт 7001 на хосте.
Возможно, вы захотите взглянуть на https://github.com/jpetazzo/nsenter, который является еще одним способом открыть оболочку в контейнере и выполнить команды внутри контейнера.
источник
По общему признанию поздней вечеринки, как об этом, что сделает ключи операционной системы вашего хоста доступными для root внутри контейнера, на лету:
Я не одобряю использование Dockerfile для установки ключей, поскольку итерации вашего контейнера могут оставить закрытые ключи позади.
источник
Я пытался выяснить, как добавить ключи подписи в контейнер для использования во время выполнения (не сборки), и наткнулся на этот вопрос. Секреты докера, похоже, являются решением для моего варианта использования, и, поскольку никто еще не упомянул об этом, я добавлю его.
источник
В моем случае у меня была проблема с nodejs и 'npm i' из удаленного репозитория. Я исправил добавление пользователя 'node' в контейнер nodejs и 700 в ~ / .ssh в контейнер.
Dockerfile:
run.sh:
докер-compose.yml:
после этого начались работы
источник
Проще всего получить учетную запись панели запуска и использовать: ssh-import-id
источник
ssh-import-id
похоже, он импортирует только открытые ключи.В работающем контейнере Docker вы можете запустить ssh-keygen с опцией docker -i (интерактивный). Это переадресует запросы контейнера для создания ключа внутри контейнера докера.
источник
Для debian / root / authorized_keys:
источник