it-swarm-ru.tech

Как сказать git, какой закрытый ключ использовать?

ssh имеет опцию -i, чтобы указать, какой файл закрытого ключа использовать при аутентификации:

-i identity_file

    Выбирает файл, из которого читается идентификатор (закрытый ключ) для аутентификации RSA или DSA. По умолчанию ~/.ssh/identity для протокола версии 1 и ~/.ssh/id_rsaand ~/.ssh/id_dsa для протокола версии 2. Файлы идентификации также могут быть указаны для каждого хоста в файле конфигурации. Можно иметь несколько параметров-i(и несколько идентификаторов, указанных в файлах конфигурации).

Есть ли аналогичный способ сообщить git, какой файл закрытого ключа использовать в системе с несколькими закрытыми ключами в каталоге ~/.ssh?

574
jrdioko

В ~/.ssh/config добавьте:

Host github.com
 HostName github.com
 IdentityFile ~/.ssh/id_rsa_github
 User git

Теперь вы можете сделать git clone [email protected]:username/repo.git.

ПРИМЕЧАНИЕ. Убедитесь, что разрешения для IdentityFile равны 400.SSH неявным образом отклонит слишком читаемые ключи SSH. Это будет выглядеть как отказ от полномочий. Решение в этом случае:

chmod 400 ~/.ssh/id_rsa_github
616
shellholic

Переменная окружения GIT_SSH_COMMAND:

Начиная с версии Git 2.3.0, вы можете использовать переменную окружения GIT_SSH_COMMAND следующим образом:

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example" git clone example

Обратите внимание, что -i может иногда быть переопределен вашим конфигурационным файлом, и в этом случае вы должны дать SSH пустой конфигурационный файл, например так:

GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example -F /dev/null" git clone example

Конфигурация core.sshCommand:

Начиная с Git версии 2.10.0, вы можете настроить это для репо или глобально, так что вам больше не нужно устанавливать переменную окружения!

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git Push
289
Flimm

Существует no direct way , чтобы сообщить git, какой закрытый ключ использовать, поскольку он использует ssh для аутентификации в репозитории. Тем не менее, есть еще несколько способов достижения вашей цели:

Вариант 1: ssh-agent

Вы можете использовать ssh-agent для временной авторизации вашего личного ключа.

Например:

$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch [email protected]'

Вариант 2: GIT_SSH_COMMAND

Передайте аргументы ssh, используя переменную окружения GIT_SSH_COMMAND (Git 2.3.0+).

Например:

$ GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
  git clone [email protected]

Вы можете напечатать все это в одной строке - игнорируйте $ и пропустите \.

Вариант 3: GIT_SSH

Передайте аргументы ssh, используя переменную среды GIT_SSH, чтобы указать альтернативный двоичный файл ssh.

Например:

$ echo 'ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $*' > ssh
$ chmod +x ssh
$ GIT_TRACE=1 GIT_SSH='./ssh' git clone [email protected]

Примечание. Вышеуказанные строки представляют собой командные строки оболочки (терминала), которые вы должны вставить в свой терминал. Они создадут файл с именем ssh, сделают его исполняемым и (косвенно) выполнят его.

Примечание: GIT_SSH доступен с v0.99.4 (2005).

Вариант 4: ~/.ssh/config

Используйте файл ~/.ssh/config, как предложено в других ответах, чтобы указать местоположение вашего личного ключа, например,.

Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa
91
kenorb

Напишите скрипт, который вызывает ssh с нужными аргументами, и укажите имя файла скрипта в $GIT_SSH. Или просто поместите свою конфигурацию в ~/.ssh/config.

32
Ignacio Vazquez-Abrams

Если вы не хотите указывать переменные окружения каждый раз, когда вы запускаете git, не хотите другой скрипт-обертку, не запускаете ssh-agent (1) и не хотите загружать другой пакет только для этого, используйте git -remote-ext (1) внешний транспорт:

$ git clone 'ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git'
Cloning into 'repository'
(...)
$ cd repository
$ git remote -v
Origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (fetch)
Origin  ext::ssh -i $HOME/.ssh/alternate_id git.example.com %S /path/to/repository.git (Push)

Я считаю это решение превосходным, потому что:

  • Это репозиторий/удаленный
  • Избегайте раздувания скриптов
  • Не нужен агент SSH - полезно, если вы хотите, чтобы клоны/Push/Pulls оставались без присмотра (например, в cron)
  • Определенно, внешний инструмент не нужен
16
flaviovs

После моей борьбы с $GIT_SSH я хотел бы поделиться тем, что сработало для меня.

В моих примерах я буду предполагать, что ваш закрытый ключ находится по адресу /home/user/.ssh/jenkins

Ошибка, которую следует избегать: значение GIT_SSH включает опции

$ export GIT_SSH="ssh -i /home/user/.ssh/jenkins"

или что-то подобное не получится, так как git попытается выполнить значение в виде файла . По этой причине вы должны создать скрипт.

Рабочий пример сценария $ GIT_SSH /home/user/gssh.sh

Сценарий будет вызываться следующим образом:

$ $GIT_SSH [[email protected]]Host [-p <port>] <command>

Пример работы скрипта может выглядеть так:

#!/bin/sh
ssh -i /home/user/.ssh/jenkins $*

Обратите внимание на $* в конце, это важная часть.

Еще более безопасная альтернатива, которая предотвратит любой возможный конфликт с чем-либо в вашем конфигурационном файле по умолчанию (плюс явное упоминание используемого порта):

#!/bin/sh
ssh -i /home/user/.ssh/jenkins -F /dev/null -p 22 $*

Предполагая, что скрипт находится в /home/user/gssh.sh, вы должны:

$ export GIT_SSH=/home/user/gssh.sh

и все будет работать.

14
Jan Vlcinsky

Используйте пользовательскую конфигурацию хоста в ~/.ssh/config, например так:

Host gitlab-as-thuc  
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa.thuc
    IdentitiesOnly yes

затем используйте свое собственное имя хоста следующим образом:

git remote add thuc [email protected]:your-repo.git  
13
thucnguyen

Вы можете просто использовать ssh-идент вместо создания своей собственной оболочки.

Вы можете прочитать больше на: https://github.com/ccontavalli/ssh-ident

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

С крошечным файлом конфигурации он может автоматически загружать разные ключи и хранить их разделенными в разных агентах (для переадресации агентов) в зависимости от того, что вам нужно сделать.

5
rabexc

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

Моим решением было добавить это в мой .zshrc/.bashrc:

alias infogit="GIT_SSH_COMMAND=\"ssh -i ~/.ssh/id_specialkey\" git [email protected]"

Всякий раз, когда я хочу использовать git для этого проекта, я заменяю "infogit" на git:

infogit commit -am "Some message" && infogit Push

Для меня это легче запомнить.

4
Michael Cole

Поэтому я установил для переменной GIT_SSH env значение $HOME/bin/git-ssh.

Для того, чтобы моя конфигурация репозитория диктовала, какую идентификацию SSH использовать, мой файл ~/bin/git-ssh таков:

#!/bin/sh
ssh -i $(git config --get ssh.identity) -F /dev/null -p 22 $*

Тогда у меня есть глобальная настройка git config:

$ git config --global ssh.identity ~/.ssh/default_id_rsa

И в любом git-репозитории я могу просто установить локальное значение ssh.identity git config:

$ git config --local ssh.identity ~/.ssh/any_other_id_rsa

Вуаля!

Если вы можете иметь разные адреса электронной почты для каждой личности, это становится еще проще, потому что вы можете просто назвать свои ключи после своих адресов электронной почты, а затем заставить git config user.email управлять выбором ключа в ~/bin/git-ssh, например так:

#!/bin/sh
ssh -i $HOME/.ssh/$(git config --get user.email) -F /dev/null -p 22 $*
3
Brendan Baldwin

Мое решение было таким:

создать скрипт:

#!/bin/bash
KEY=dafault_key_to_be_used
PORT=10022 #default port...
for i in [email protected];do
   case $i in
    --port=*)
        PORT="${i:7}";;
    --key=*)KEY="${i:6}";;
   esac
done
export GIT_SSH_COMMAND="ssh -i $HOME/.ssh/${KEY} -p ${PORT}"
echo Command: $GIT_SSH_COMMAND

затем, когда вам нужно изменить запуск var:

. ./thescript.sh [--port=] [--key=]

Не забывайте лишнюю точку! это заставляет скрипт устанавливать окружение vars !! --key и --port не обязательны.

2
Salsicha

Я использую @shellholic и этот SO поток с несколькими тиками. Я использую GitHub в качестве примера и предполагаю, что у вас есть закрытый ключ в ~/.ssh/github (иначе, смотрите этот SO поток ) и что вы добавили открытый ключ в свой профиль GitHub (иначе смотрите Помощь GitHub ).

При необходимости создайте новый файл конфигурации SSH в ~/.ssh/config и измените разрешения на 400

touch ~/.ssh/config
chmod 600 ~/.ssh/config

Добавьте это в файл ~/.ssh/config:

Host github.com
    IdentityFile ~/.ssh/github
    IdentitiesOnly yes

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

git remote rm Origin

Затем добавьте пульт в репозиторий git и обратите внимание на двоеточие перед именем пользователя:

git remote add Origin [email protected]:user_name/repo_name.git

И тогда команды git работают нормально, например:

git Push Origin master
git pull Origin 

@HeyWatchThis on этот поток SO предложил добавить IdentitiesOnly yes для предотвращения поведения SSH по умолчанию при отправке файла идентификации, соответствующего имени файла по умолчанию для каждого протокола. Смотрите эту ветку для получения дополнительной информации и ссылок.

2
mmorin

Просто используйте команды ssh-agent и ssh-add.

# create an agent
ssh-agent

# add your default key
ssh-add ~/.ssh/id_rsa

# add your second key
ssh-add ~/.ssh/<your key name>

После выполнения вышеуказанных команд вы можете использовать обе клавиши одновременно. Просто введите

git clone [email protected]:<yourname>/<your-repo>.git

клонировать ваш репозиторий.

Вы должны выполнить вышеуказанную команду после перезагрузки компьютера.

1
Jinmiao Luo

Как правило, вы хотите использовать ~/.ssh/config для этого. Просто соедините адреса серверов с ключами, которые вы хотите использовать для них, следующим образом:

Host github.com
  IdentityFile ~/.ssh/id_rsa.github
Host heroku.com
  IdentityFile ~/.ssh/id_rsa.heroku
Host *
  IdentityFile ~/.ssh/id_rsa

Host * обозначает любой сервер, поэтому я использую его для установки ~/.ssh/id_rsa в качестве ключа по умолчанию для использования.

1
Zaz

Я использую git версии 2.16, и мне не нужен ни один фрагмент скрипта, даже конфигурация или измененные команды.

  • Просто скопировал мой закрытый ключ в .ssh/id_rsa
  • установить разрешения на 600

И Git читает ключ автоматически. Я ничего не спрашиваю, и это не выдает ошибку. Просто отлично работает.

0
akprajapati

Хотя вопрос не требует этого, я включаю этот ответ для всех, кто хочет решить эту проблему специально для gitlab .

Гитлаб раствор

Я попытался использовать переменные окружения подход, но даже документация git рекомендует использовать ~/.ssh/config для чего-то большего, чем простой случай. В моем случае я нажимаю на gitlab server - и я хотел сделать это как определенный пользователь - который, конечно, определяется private-key во время аутентификации , а не именем пользователя git. После внедрения я просто выполняю следующее:

~/myrepo> git mycommit -m "Important Stuff"
~/myrepo> git mypush
[proceed to enter passphrase for private key...]

Настроить

Вспомните расположение вашего закрытого ключа/myfolder/.ssh/my_gitlab_id_rsa в моем случае.

Добавить запись в ~/.ssh/config:

Host gitlab-delegate
    HostName gitlab.mydomain.com
    User git
    IdentityFile /myfolder/.ssh/my_gitlab_id_rsa
    IdentitiesOnly yes

Добавьте git-alias в ~/.gitconfig:

mypush = "!f() { \
           path=$(git config --get remote.Origin.url | cut -d':' -f2); \
           branch=$(git rev-parse --abbrev-ref HEAD); \
           git remote add gitlab_as_me [email protected]:$path && \
           git Push gitlab_as_me $branch && \
           git pull Origin $branch; \
           git remote remove gitlab_as_me; \
         }; f"

В качестве бонуса я выполняю свои коммиты на этом же хосте как конкретный пользователь с этим git-alias :

mycommit = "!f() { \
             git -c "user.name=myname" -c "[email protected]" commit \"[email protected]\"; \
           }; f"

Объяснение

Все вышеперечисленное предполагает, что соответствующий удаленный элемент Origin и соответствующая ветвь в настоящее время извлечена. Для справки я столкнулся с несколькими пунктами, которые необходимо было решить:

  • Решение требует создания нового удаленного gitlab_as_me, и мне не нравилось видеть дополнительный удаленный зависающий в моем дереве журнала поэтому я удаляю его, когда закончу
  • Чтобы создать пульт, необходимо генерировать URL-адрес пульта на лету - в случае с gitlab это было достигнуто с помощью простого bash cut
  • При выполнении Push to gitlab_as_me вы должны быть конкретны в отношении того, какую ветку вы нажимаете
  • После выполнения Push ваш локальный указатель Origin должен быть «обновлен», чтобы соответствовать gitlab_as_me (git pull Origin $branch делает это)
0
dtmland