Как указать закрытый SSH-ключ для использования при выполнении команды оболочки на Git?

795

Возможно, довольно необычная ситуация, но я хочу указать частный SSH-ключ для использования при выполнении команды оболочки (git) с локального компьютера.

В основном так:

git clone [email protected]:TheUser/TheProject.git -key "/home/christoffer/ssh_keys/theuser"

Или даже лучше (в Ruby):

with_key("/home/christoffer/ssh_keys/theuser") do
  sh("git clone [email protected]:TheUser/TheProject.git")
end

Я видел примеры подключения к удаленному серверу с Net:: SSH, который использует указанный закрытый ключ, но это локальная команда. Возможно ли это?

  • 4
    Смотрите этот вопрос в SuperUser .
  • 15
    Мне интересно, почему это так необычно, что у Git нет опции -i как у ssh .
Показать ещё 2 комментария
Теги:
ssh

22 ответа

554
Лучший ответ

Что-то вроде этого должно работать (предлагается orip):

ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone [email protected]:user/project.git'

Если вы предпочитаете подоболочки, вы можете попробовать следующее (хотя оно более хрупкое):

ssh-agent $(ssh-add /somewhere/yourkey; git clone [email protected]:user/project.git)

Git будет вызывать SSH, который найдет свой агент по переменной окружения; это, в свою очередь, приведет к загрузке ключа.

В качестве альтернативы, установка HOME также может сделать трюк, если вы хотите настроить каталог, содержащий только каталог .ssh как HOME; это может либо содержать файл identity.pub, либо файл конфигурации, определяющий IdentityFile.

  • 4
    Но это добавит ключ навсегда как принятый SSH-ключ, верно? Я хочу избежать этого, чтобы theuser2 не мог связываться с проектами пользователя. Это для веб-приложения, поэтому нецелесообразно использовать разных пользователей ОС, что было бы лучшим вариантом.
  • 22
    Нет, когда git завершает работу, ssh-agent завершается, а ключ забывается.
Показать ещё 16 комментариев
961

Ни одно из этих решений не работало для меня.

Вместо этого я подробно останавливаюсь на упоминании @Martin v. Löwis о настройке файла config для SSH.

SSH будет искать файл пользователя ~/.ssh/config. У меня есть моя установка как:

Host gitserv
    Hostname remote.server.com
    IdentityFile ~/.ssh/id_rsa.github
    IdentitiesOnly yes # see NOTES below

И я добавляю удаленный репозиторий git:

git remote add origin git@gitserv:myrepo.git

И тогда команды git работают нормально для меня.

git push -v origin master

ЗАМЕТКИ

  • IdentitiesOnly yes требуется для предотвращения поведения по умолчанию SSH по отправке файла идентификатора, соответствующего имени файла по умолчанию для каждого протокола. Если у вас есть файл с именем ~/.ssh/id_rsa который будет проверен перед вашим ~/.ssh/id_rsa.github без этой опции.

Рекомендации

  • 12
    Я обнаружил, что когда вы указываете несколько ключей с помощью .ssh / config, вам необходимо использовать имя друга хоста в строке «Host» как часть команды «git remote add». Если строка "Host stg", вам нужно использовать git remote, добавить <someName> user @ stg: /path_to_git_repo.git ". Если вы используете точное имя сервера, например [email protected]: /path_to_git_repo.git, файл конфигурации git не выбирает. Следовательно, он не выбирает файл закрытого ключа правильно. Я пробовал это, передавая одинаковое содержимое в github и heroku, и работает, только когда вы даете понятное имя в "git remote add"
  • 2
    Я не был уверен насчет Host для github. Я нашел эту ссылку: gist.github.com/jexchan/2351996 .
Показать ещё 16 комментариев
363

Другие предложения людей о ~/.ssh/config сложны. Это может быть просто:

Host github.com
  IdentityFile ~/.ssh/github_rsa
  • 27
    Это работает, только если у вас есть только одна учетная запись пользователя для GitHub
  • 19
    Вам также нужна опция IdentitiesOnly .
Показать ещё 2 комментария
267

Начиная с Git 2.3.0, у нас также есть простая команда (нет файла конфигурации):

GIT_SSH_COMMAND='ssh -i private_key_file' git clone user@host:repo.git

Возможно, потребуется перезагрузка службы ssh на вашем компьютере.

  • 2
    У меня не получается cannot run ssh -i /home/vagrant/.ssh/git: No such file or directory хотя он существует 444 Nov 16 18:12 /home/vagrant/.ssh/git из ls -l /home/vagrant/.ssh/git
  • 2
    @ted: chmod 400 /home/vagrant/.ssh/git
Показать ещё 8 комментариев
119

Содержимое my_git_ssh_wrapper:

#!/bin/bash

ssh -i /path/to/ssh/secret/key $1 $2

Затем вы можете использовать ключ, выполнив следующие действия:

GIT_SSH=my_git_ssh_wrapper git clone [email protected]:TheUser/TheProject.git
  • 4
    Очень хорошее решение, если у вас есть несколько учетных записей в одном домене, с которыми другие решения не справляются хорошо
  • 1
    Хорошее решение. Вы также можете упростить это с помощью> GIT_SSH = my_git_ssh_wrapper; git clone [email protected]: TheUser / TheProject.git
Показать ещё 3 комментария
79

Подводя ответы и комментарии, лучший способ настроить git для использования разных файлов ключей, а затем забыть об этом, что также поддерживает разных пользователей для один и тот же хост (например, личная учетная запись GitHub и один рабочий), который также работает в Windows, заключается в редактировании ~/.ssh/config (или c:\Users\<your user>\.ssh\config) и определении нескольких идентификаторов:

Host github.com
HostName github.com
IdentityFile /path/to/your/personal/github/private/key
User dandv

Host github-work
HostName github.com
IdentityFile /path/to/your/work/github/private/key
User workuser

Затем, чтобы клонировать проект как ваш личный пользователь, просто запустите обычную команду git clone.

Чтобы клонировать репо как workuser, запустите git clone git@github-work:company/project.git.

  • 2
    Я вас опроверг, потому что все, что вы говорите, уже отражено в ответах выше, и, на мой взгляд, еще яснее. Например, почему именно вы определяете пользователя для e dandv и workuser, соответственно?
  • 2
    Вы ответили на 4-летний вопрос без новой информации, и вы утверждаете, что ваш ответ "лучший способ". Более того, вы понизили голосование и заставили других пользователей убрать свой ответ ... просто чтобы подтолкнуть вашего.
Показать ещё 4 комментария
55

С git 2.10+ (Q3 2016: выпущено 2 сентября 2016 года) у вас есть возможность установить конфигурацию для GIT_SSH_COMMAND (а не только для переменной среды, как описано в Робер Джек Уилл ответ)

См. commit 3c8ede3 (26 июня 2016 г.) Nguyễn Thái Ngọc Duy (pclouds).
(слияние Юнио С Хамано - gitster - в commit dc21164, 19 июля 2016 г.)

Добавлена ​​новая переменная конфигурации core.sshCommandукажите, какое значение для GIT_SSH_COMMAND использовать для каждого репозитория.

core.sshCommand:

Если эта переменная установлена, git fetch и git push будут использовать указанную команду вместо ssh, когда им необходимо подключиться к удаленной системе.
Команда находится в той же форме, что и переменная среды GIT_SSH_COMMAND, и переопределяется при установке переменной среды.

Это означает, что git clone может быть:

cd /path/to/my/repo
git config core.sshCommand 'ssh -i private_key_file' 
# later on
git clone host:repo.git
  • 0
    @Flimm даты выпуска: calendar.google.com/calendar/…
  • 0
    Это было выпущено.
Показать ещё 4 комментария
51

Как указано здесь: https://superuser.com/a/912281/607049

Вы можете настроить его для каждого репо:

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git push
  • 1
    Что делает -F /dev/null ? Насколько я вижу, это изменит configFile по умолчанию из ~/.ssh/config но зачем это нужно? Чтобы обеспечить песочницу команды?
  • 3
    linuxcommand.org/man_pages/ssh1.html , не указывает файл конфигурации, поэтому, когда git запустит ssh, файл конфигурации не будет передан (на самом деле это своего рода режим песочницы, просто игнорируйте параметры конфигурации пользователя по умолчанию) Исходный поток в суперпользователе имеет больше информации о -F
Показать ещё 4 комментария
30

Я пошел с переменной среды GIT_SSH. Здесь моя обложка, аналогичная тому, что из Joe Block сверху, но обрабатывает любое количество аргументов.

Файл ~/gitwrap.sh

#!/bin/bash
ssh -i ~/.ssh/gitkey_rsa "$@"

Затем в моем .bashrc добавьте следующее:

export GIT_SSH=~/gitwrap.sh
  • 0
    Я установил это на .bashrc. Но когда я вхожу в экземпляр openshift, он, кажется, не вызывает его. Я что-то пропустил ?
  • 0
    Он завершается с ошибкой для меня .. он не может найти событие сценария, хотя он там .. не уверен, что происходит ... ошибка: не может запустить /tmp/gitwrap.sh: нет такого файла или каталога
Показать ещё 2 комментария
28

Лучше всего добавить этот хост или ip в файл .ssh/config следующим образом:

Host (a space separated list of made up aliases you want to use for the host)
    User git
    Hostname (ip or hostname of git server)
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_(the key you want for this repo)
  • 1
    Это полезно, но заставляет вас использовать ключ репо для всего взаимодействия с этим именем хоста. Если на том же сервере есть другие репозитории, которым требуются разные ключи, лучше использовать оболочку и указать git использовать ее с GIT_SSH.
  • 9
    Это не обязательно правда. Я использую несколько ключей для Github - один для работы и один для моей личной учетной записи. Вам не нужно указывать доменное имя для «Host». Вы можете указать любой псевдоним. Например, я использую gh-home и gh-work в качестве имен хостов, а когда я клонирую, я использую, например, git clone git@gh-work:repo/project.git В моем ~ / .ssh / config у меня есть два раздела что оба используют github.com для HostName. Просто у них разные IdentityFile и Host
Показать ещё 8 комментариев
7

Многие из этих решений выглядели заманчивыми. Однако я нашел общий подход git -wrapping- script по следующей ссылке наиболее полезным:

Как указать файл ключа ssh с помощью команды git

Дело в том, что нет команды git, например:

git -i ~/.ssh/thatuserkey.pem clone [email protected]:/git/repo.git

Решение Alvin должно использовать четко определенный bash -wrapper script, который заполняет этот пробел:

git.sh -i ~/.ssh/thatuserkey.pem clone [email protected]:/git/repo.git

Где git.sh:

#!/bin/bash

# The MIT License (MIT)
# Copyright (c) 2013 Alvin Abad
# https://alvinabad.wordpress.com/2013/03/23/how-to-specify-an-ssh-key-file-with-the-git-command

if [ $# -eq 0 ]; then
    echo "Git wrapper script that can specify an ssh-key file
Usage:
    git.sh -i ssh-key-file git-command
    "
    exit 1
fi

# remove temporary file on exit
trap 'rm -f /tmp/.git_ssh.$$' 0

if [ "$1" = "-i" ]; then
    SSH_KEY=$2; shift; shift
    echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$
    chmod +x /tmp/.git_ssh.$$
    export GIT_SSH=/tmp/.git_ssh.$$
fi

# in case the git command is repeated
[ "$1" = "git" ] && shift

# Run the git command
git "$@"

Я могу проверить, что это решило проблему, с которой я столкнулся с распознаванием пользователя/ключа для удаленного ретрансляции битбакет с git remote update, git pull и git clone; все из которых теперь отлично работают в задаче cron script, который в противном случае имел проблемы с перемещением ограниченной оболочки. Я также смог назвать этот script из R и решить ту же самую проблему cron execute (например, system("bash git.sh -i ~/.ssh/thatuserkey.pem pull")).

Не то, что R совпадает с Ruby, но если R может это сделать... O: -)

  • 1
    Выглядит здорово! Я проверю это и отвечу обратно.
  • 2
    Помимо синтаксиса, как это лучше, чем GIT_SSH_COMMAND="ssh -i ~/.ssh/thatuserkey.pem" git clone clone [email protected]:/git/repo.git согласно GIT_SSH_COMMAND="ssh -i ~/.ssh/thatuserkey.pem" git clone clone [email protected]:/git/repo.git Роберта Джека Уилла ?
7

Когда вам нужно подключиться к github с обычным запросом (git pull origin master), настройка для меня как * in ~/.ssh/config работала для меня, любой другой хост (скажем, "github" или "gb" ) не был Работает.

Host *
    User git
    Hostname github.com
    PreferredAuthentications publickey
    IdentityFile ~/.ssh/id_rsa_xxx
  • 0
    Также можно оставить всю строку «Host *».
  • 1
    Вероятно, он не работал, потому что он не соответствовал вашему удаленному URL. Если вы хотите использовать Host my-host-alias , вы должны установить remote.origin.url=git@my-host-alias:[username]/[repo].git .
3

Хитрость для меня заключалась в использовании git @hostname вместо http://hostname

3

Вы можете использовать переменную среды GIT_SSH. Но вам нужно будет обернуть ssh и опции в оболочку script.

См. руководство git: man git в командной оболочке.

2

В Windows с Git Bash вы можете использовать следующее, чтобы добавить репозиторий ssh-agent bash -c 'ssh-add "key-address"; git remote add origin "rep-address"' например: ssh-agent bash -c 'ssh-add /d/test/PrivateKey.ppk; git remote add origin [email protected]:test/test.git' Какой закрытый ключ находится в диске D, проверка папки на компьютере. Кроме того, если вы хотите клонировать репозиторий, вы можете изменить git remote add origin на git clone.

После ввода этого значения в Git Bash он попросит вас ввести парольную фразу!

Будьте осведомлены о том, что opensh закрывает закрытый ключ и закрывающий ключ putty!

Если вы создали свои ключи с помощью puttygen, вы должны преобразовать свой закрытый ключ в openssh!

1

Если ни одно из других решений здесь не работает, и вы создали несколько ssh-ключей, но все же не можете делать простые вещи, например

git pull

то предположим, что у вас есть два файла ssh key, например

id_rsa
id_rsa_other_key

то внутри git repo вы боретесь с (cd туда), попробуйте:

ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa_other_key

а также убедитесь, что ваше имя пользователя и идентификатор пользователя github верны:

git config user.name "Mona Lisa"
git config user.email "[email protected]"

Дополнительную информацию см. В https://gist.github.com/jexchan/2351996.

  • 0
    Обратите внимание, если вы получили Could not open a connection to your authentication agent. попробуйте $ eval `ssh-agent -s` и попробуйте снова.
  • 1
    Для тех, кто потерян, уловка команды ssh-add работала для меня. Добавьте ключ идентификации в список тех, которые проверяются при аутентификации ssh. Это сработало для меня хорошо!
0

GIT_SSH_COMMAND = "ssh -i/path/to/git-private-access-key" git clone $ git_repo

0

Если вы похожи на меня, вы можете:

  • Держите ваши ключи SSH организованными

  • Сделайте ваши команды git clone простыми

  • Обрабатывать любое количество ключей для любого количества хранилищ.

  • Сократите ваше обслуживание ключа SSH.

Я храню свои ключи в моей директории ~/.ssh/keys.

Я предпочитаю соглашение по конфигурации.

Я думаю, что кодекс - это закон; чем проще, тем лучше.

ШАГ 1 - Создание псевдонима

Добавьте этот псевдоним в вашу оболочку: alias git-clone='GIT_SSH=ssh_wrapper git clone'

ШАГ 2 - Создание сценария

Добавьте этот скрипт ssh_wrapper в вашу переменную PATH:

#!/bin/bash
# Filename: ssh_wrapper

if [ -z ${SSH_KEY} ]; then
    SSH_KEY='github.com/l3x'  # <= Default key
fi
SSH_KEY="~/.ssh/keys/${SSH_KEY}/id_rsa"
ssh -i "${SSH_KEY}" "$@"

ПРИМЕРЫ

Используйте ключ github.com/l3x:

KEY=github.com/l3x git-clone https://github.com/l3x/learn-fp-go

В следующем примере также используется ключ github.com/l3x (по умолчанию):

git-clone https://github.com/l3x/learn-fp-go

Используйте ключ bitbucket.org/lsheehan:

KEY=bitbucket.org/lsheehan git-clone [email protected]:dave_andersen/exchange.git

ЗАМЕТКИ

Измените значение по умолчанию SSH_KEY в скрипте ssh_wrapper на то, что вы используете большую часть времени. Таким образом, вам не нужно использовать переменную KEY большую часть времени.

Вы можете подумать: "Привет! Это часто происходит с псевдонимом, скриптом и некоторым каталогом ключей", но для меня это соглашение. Почти все мои рабочие станции (и серверы в этом отношении) настроены одинаково.

Моя цель здесь - упростить команды, которые я выполняю регулярно.

Мои соглашения, например скрипты Bash, псевдонимы и т.д., Создают согласованную среду и помогают мне быть проще.

Поцелуй и имена имеют значение.

Дополнительные советы по дизайну можно найти в главе 4 "SOLID Design in Go" из моей книги: https://www.amazon.com/Learning-Functional-Programming-Lex-Sheehan-ebook/dp/B0725B8MYW

Надеюсь, это поможет. - Лекс

0

Вам нужно создать файл ~/.ssh/config, как показано ниже.

Host <Your bitbucket server>
User <userid>
Hostname <Your bitbucket server as above>
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa<file> This is your private key file

разрешение ниже

-rw------- $HOME/.ssh/config

Добавьте свой открытый ключ в свой git (cat ~/.ssh/id_rsa_pub [или имя simillar])

и затем git clone, как показано ниже

git clone ssh://[email protected]/userid/test.git
0

Если номер порта SSH не равен 22 (по умолчанию), добавьте Port xx в ~/.ssh/config

В моем случае (синология),

Host my_synology
    Hostname xxxx.synology.me
    IdentityFile ~/.ssh/id_rsa_xxxx
    User myname
    Port xx

Затем клонировать с использованием заголовка хоста в config. ( "my_synology"., чтобы избежать @chopstik "*" )

git clone my_synology:path/to/repo.git
0

для gitlab RSAAuthentication yes

Host gitlab.com
  RSAAuthentication yes
  IdentityFile ~/.ssh/your_private_key_name
  IdentitiesOnly yes

doc здесь

0

Я использую zsh, и разные ключи загружаются в мою zsh-оболочку ssh-agent автоматически для других целей (например, для доступа к удаленным серверам) на моем ноутбуке. Я изменил ответ @Nick, и я использую его для одного из моих репозиций, которые нужно часто обновлять. (В этом случае это мой dotfiles, который я хочу иметь самую последнюю версию на всех моих машинах, где бы я ни работал.

bash -c 'eval `ssh-agent`; ssh-add /home/myname/.dotfiles/gitread; ssh-add -L; cd /home/myname/.dotfiles && git pull; kill $SSH_AGENT_PID'
  • Создайте ssh-agent
  • Добавить ключ только для чтения в агент
  • Измените каталог на мой git repo
  • Если cd для репозитория успешно завершено, вытащите из удаленного репо
  • Убить порожденный ssh-агент. (Я бы не хотел, чтобы многие агенты задерживались.)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню