Вкажіть SSH ключ для git push для даного домену


342

У мене є такий випадок використання: я б хотів перейти до git@git.company.com:gitolite-adminвикористання приватного ключа користувача gitolite-admin, хоча хочу перейти до git@git.company.com:some_repoвикористання приватного ключа "власний". AFAIK, я не можу вирішити це за допомогою ~/.ssh/config, оскільки ім'я користувача та ім’я сервера в обох випадках однакові. Як я в основному використовую свій власний закритий ключ, у мене є певний в ~/.ssh/configпротягом git@git.company.com. Хтось знає про спосіб перекриття ключа, який використовується для одного gitвиклику?

(Убік: gitolite розрізняє, хто робить натискання на основі ключа, тому з точки зору доступу, власності та аудиту, це не проблема, що рядок user @ server однаковий для різних користувачів.)


Відповіді:


597

Навіть якщо користувач і хост однакові, їх все одно можна розрізнити ~/.ssh/config. Наприклад, якщо ваша конфігурація виглядає так:

Host gitolite-as-alice
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_rsa.alice
  IdentitiesOnly yes

Host gitolite-as-bob
  HostName git.company.com
  User git
  IdentityFile /home/whoever/.ssh/id_dsa.bob
  IdentitiesOnly yes

Тоді ви просто використовуєте gitolite-as-aliceі gitolite-as-bobзамість імені хоста у своїй URL-адресі:

git remote add alice git@gitolite-as-alice:whatever.git
git remote add bob git@gitolite-as-bob:whatever.git

Примітка

Ви хочете включити опцію, IdentitiesOnly yesщоб запобігти використанню ідентифікаторів за замовчуванням. В іншому випадку, якщо у вас також є ідентифікаційні файли, що відповідають іменам за замовчуванням, вони спершу будуть випробувані, оскільки на відміну від інших параметрів конфігурації (які дотримуються "першого в виграші"), IdentityFileпараметр додається до списку ідентифікацій, які слід спробувати. Дивіться: /server/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807


9
Дивовижне, спасибі Я не розумів, що ви можете вільно вибрати "псевдонім" для специфікації Host в ~ / .ssh / config
Confusion

4
Дякую також за цю відповідь! Одне з моїх причин було те, що IdentityFile повинен пройти повний шлях (я ставлю id_rsa.rick лише як мій аргумент до IdentityFile, і це не вдалося). Дивіться сторінку ssh_config (5) для інших синтаксисів для IdentityFile.
rickumali

1
Дякую вам за чітку і дуже корисну відповідь. Я деякий час намагався змусити це працювати, і раніше відмовився, припускаючи, що той же користувач повинен використовувати той самий файл приватного ключа id_rsa.
DrCord

7
git@Частина в пульті дистанційного керування не є необхідною , як воно дано в Userрядку конфігурації.
долмен

2
Я боровся з цим рішенням, поки не додав ще один рядок, що містить IdentitiesOnly yesвідразу після рядка з IdentityFileдля хоста. Здається, він проходив по декількох особах, і одному з них було заборонено доступ до хоста.
Fitter Man

57

Альтернативний підхід до запропонованого вище Марком Лонгейром полягає у використанні псевдоніму, який буде виконувати будь-яку команду git на будь-якому віддаленому пристрої з альтернативним ключем SSH. В основному ідея полягає в переключенні вашої SSH ідентичності під час виконання команд git.

Переваги щодо підходу з псевдонімом хоста в іншій відповіді:

  • Працює з будь-якими командами git або псевдонімами, навіть якщо ви не можете remoteчітко вказати це .
  • Простіше працювати з багатьма сховищами, тому що вам потрібно встановити його лише один раз на клієнтській машині, а не один раз у сховищі на кожній клієнтській машині.

Я використовую кілька невеликих сценаріїв і псевдонім git admin. Так я можу зробити, наприклад:

git admin push 

Щоб натиснути на пульт за замовчуванням, використовуючи альтернативну клавішу SSH ("адмін"). Знову ж таки, ви можете використовувати будь-яку команду (не тільки push) з цим псевдонімом. Ви навіть git admin clone ...можете клонувати сховище, до якого ви матимете доступ лише до свого ключа "адмін".

Крок 1: Створіть альтернативні ключі SSH, необов'язково встановіть парольну фразу на випадок, якщо ви робите це на чужому комп'ютері.

Крок 2: Створіть сценарій під назвою "ssh-as.sh", який виконує матеріали, які використовують SSH, але використовує заданий ключ SSH, а не за замовчуванням:

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"

Крок 3: Створіть сценарій під назвою "git-as.sh", який виконує команди git за допомогою даного ключа SSH.

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"

Крок 4: Додайте псевдонім (використовуючи щось відповідне для "PATH_TO_SCRIPTS_DIR" нижче):

# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"

Більше інформації на сайті: http://noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-running-git-commands-as-a-privileged-ssh-identity/


4
Дуже приємна відповідь. Не забудьте додати подвійні лапки $@-> "$@"щоб бути безпечним.
кевінарпе

@sinelaw Це все ще працює? Мені постійно дозволено відмовити в помилках
Алок Кумар

56

Ви можете використовувати змінну середовища git GIT_SSH_COMMAND. Запустіть це у своєму терміналі під сховищем git:

GIT_SSH_COMMAND='ssh -i ~/.ssh/your_private_key' git submodule update --init

Замініть ~/.ssh/your_private_keyшлях приватного ключа ssh, який ви хочете використовувати. І ви можете змінити подальшу команду GIT (в прикладі git submodule update --init) , щоб інші , як git pull, git fetchі т.д.


1
Повний документ знаходиться за адресою git-scm.com/docs/git#git-codeGITSSHcode ; йому потрібен останній Git (> = 2.3. *).
Крістіан Ульбріх,

2
Дякуємо за просте рішення, яке не вимагає нічого, крім встановлення однієї змінної середовища.
Ной Суссман

4
Зверніть увагу, що ваш ~ / .ssh / id_rsa (або будь-який ваш ключ за замовчуванням) матиме перевагу над тим, який ви передаєте через -i. Отже, ви дійсно хочете використовувати GIT_SSH_COMMAND = 'ssh -i ~ / .ssh / your_private_key -o IdentitiesOnly = так', щоб ігнорувати інші ключі
staktrace

як можна оновити git push? Я не зміг його знайти в документації
lebed2045

Було б добре створити псевдоніми bash чи git - подібні до відповіді sinelaw, але за допомогою цього методу замість того, щоб десь створювати сценарії.
Ініго

14

В одних системах на базі Unix (Linux, BSD, Mac OS X) ідентифікація за замовчуванням зберігається в каталозі $ HOME / .ssh , у двох файлах: private key: $HOME/.ssh/id_rsa public key: $HOME/.ssh/id_rsa.pub Якщо ви користуєтесь sshбез опції -i, він використовує приватний ключ за замовчуванням для автентифікації з віддаленою системою.

Якщо у вас є інший приватний ключ, який ви хочете використовувати, наприклад $ HOME / .ssh / opens_key , ви повинні використовуватиssh -i ~/.ssh/deploy_key ...

Це дратує. Ви можете додати наступні рядки до свого $ HOME / .bash_profile : ssh-add ~/.ssh/deploy_key ssh-add ~/.ssh/id_rsa

Тому кожен раз, коли ви користуєтесь sshабо ( gitабо в scpосновному sshтеж), вам більше не доведеться використовувати варіант -i.

У файл $ HOME / .bash_profile можна додати скільки завгодно ключів .


10

Іншою альтернативою є використання ssh-ident для управління вашими особами ssh .

Він автоматично завантажує та використовує різні ключі на основі вашої поточної робочої директорії, параметрів ssh тощо), а це означає, що ви можете легко мати робочу / директорію та приватні / каталоги, які прозоро закінчують використання різних ключів та посвідчень із ssh.


9

Я використовую Git Bash на Win7. Наступне працювало для мене.

Створіть файл конфігурації за допомогою ~ / .ssh / config або c: / users / [your_user_name] /. Ssh / config. У файл введіть:

Host your_host.com
     IdentityFile [absolute_path_to_your_.ssh]\id_rsa

Я думаю, що хост повинен бути URL-адресою, а не просто "ім'ям" або "ref" для вашого хоста. Наприклад,

Host github.com
     IdentityFile c:/users/[user_name]/.ssh/id_rsa

Шлях також можна записати у форматі / c / users / [user_name] / ....

Рішення, яке надає Джордано Скальцо, теж чудово. https://stackoverflow.com/a/9149518/1738546


9

Від git 2.10 вгору також можна використовувати налаштування gitconfig sshCommand. Документи :

Якщо ця змінна встановлена, git fetch і git push будуть використовувати вказану команду замість ssh, коли їм потрібно підключитися до віддаленої системи. Команда знаходиться в тому ж вигляді, що і змінна середовища GIT_SSH_COMMAND, і вона переосмислюється, коли встановлена ​​змінна середовище.

Прикладом використання може бути: git config core.sshCommand "ssh -i ~/.ssh/[insert_your_keyname]

У деяких випадках це не працює, оскільки ssh_config, що перекриває команду, намагайтеся ssh -i ~/.ssh/[insert_your_keyname] -F /dev/nullне використовувати ssh_config.


8

Я зібрався разом і випробував з Github наступний підхід, заснований на читанні інших відповідей, який поєднує в собі кілька прийомів:

  • правильний конфігурація SSH
  • переписання URL-адрес git

Перевага такого підходу полягає в тому, що після його налаштування він не потребує додаткової роботи, щоб його виправити - наприклад, вам не потрібно змінювати віддалені URL-адреси або пам'ятати, щоб клонувати речі по-іншому - переписування URL-адреси змушує це все працювати .

~/.ssh/config

# Personal GitHub
Host github.com
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/github_id_rsa

# Work GitHub
Host github-work
  HostName github.com
  User git
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/work_github_id_rsa

Host *
  IdentitiesOnly yes

~/.gitconfig

[user]
    name = My Name
    email = personal@personal.email

[includeIf "gitdir:~/dev/work/"]
    path = ~/dev/work/.gitconfig

[url "github-work:work-github-org/"]
    insteadOf = git@github.com:work-github-org/

~/dev/work/.gitconfig

[user]
    email = work@work.email

Поки ви зберігаєте всі свої робочі репозиції під ~ / dev / роботою та особистими речами в іншому місці, git буде використовувати правильний ключ SSH, коли робить тягне / клонує / натискає на сервер, а також додасть правильну адресу електронної пошти до всіх ваші зобов’язання.

Список літератури:


Як це працює з клонуванням? includeIfповинен працювати лише в тому випадку, якщо є .gitкаталог, який я думав?
detly

Зачекайте, я це зрозумію, саме про це потрібно переписати URL. Ця відповідь неймовірно корисна!
detly

4

Якщо ви використовуєте версію ssh для Git у Windows, виглядає рядок файлу посвідчення у ssh-конфігурації

IdentityFile /c/Users/Whoever/.ssh/id_rsa.alice

де /cдляc:

Щоб перевірити, в git's bash зробити

cd ~/.ssh
pwd 

3

Можливо, вам доведеться видалити (або прокоментувати) конфігурацію хоста за замовчуванням .ssh / config


1

ви найбільше вказали у файлі config ключ ssh:

# Default GitHub user
Host one
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-one
 IdentitiesOnly yes

#two user
Host two
 HostName gitlab.com
 User git
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/key-two
 IdentitiesOnly yes

0

Як уже хтось згадував, core.sshCommandконфігурацію можна використовувати для заміни ключа SSH та інших параметрів.

Ось приклад, де ви маєте альтернативний ключ з назвою ~/.ssh/workrsaі хочете використовувати його для всіх сховищ, клонованих під ~/work.

  1. Створіть новий .gitconfigфайл під ~/work:
[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"
  1. ~/.gitconfigДодайте у свій глобальний конфігурацію git :
[includeIf "gitdir:~/work/"]
  path = ~/work/.gitconfig

0

Одна з можливостей використання ~/.ssh/config- використовувати Matchобмеження замість Hostобмеження. Зокрема, Match Execвикликає команду shell, щоб вирішити, застосовувати декларації чи ні. У bash ви можете використовувати таку команду:

[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]

Для цього використовується команда bash [для перевірки рівності двох рядків. У цьому випадку це тестування, чи рядок git@git.company.com:gitolite-adminвідповідає результату, отриманому з $(git config --get remote.origin.url)''команди.

Ви можете використовувати будь-яку іншу команду, яка ідентифікує сховище, на якому знаходиться оболонка. Для цього важливо мати $SHELLзмінну, визначену для вашої оболонки, в моєму випадку /bin/bash. Повний приклад може бути наступним ~/.ssh/config:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

Match Exec "[ git@git.company.com:some_repo = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

У цьому прикладі я припускав, що він ~/.ssh/yourOwnPrivateKeyмістить ваш власний приватний ключ, який ~/.ssh/gitolite-adminмістить приватний ключ користувача gitolite-admin. Я включив IdentitiesOnly yesдекларацію, щоб переконатися, що на сервер git пропонується лише один ключ, згаданий Марком Лонгаіром . Інші декларації - це лише стандартні параметри ssh для git.

Ви можете додати цю конфігурацію, якщо у вас є кілька, some_repoякі ви хочете використовувати з різними клавішами. Якщо у вас є декілька сховищ, git@git.company.comі більшість з них використовує ~/.ssh/yourOwnPrivateKeyйого, має більше сенсу включити цей ключ як основний для хоста. У цьому випадку ~/.ssh/configбуло б:

Match Exec "[ git@git.company.com:gitolite-admin = $(git config --get remote.origin.url)'' ]"
  IdentityFile ~/.ssh/gitolite-admin
  IdentitiesOnly yes

Host git.company.com
  IdentityFile ~/.ssh/yourOwnPrivateKey
  IdentitiesOnly yes
  ForwardAgent no
  ForwardX11 no
  ForwardX11Trusted no

Зауважте, що порядок має значення, а Host git.company.comобмеження має з’явитися після Match Execодного або тих.


0

Налаштуйте сховище за допомогою git config. Наприклад:

git config --add --local core.sshCommand 'ssh -i ~/.ssh/<<<PATH_TO_SSH_KEY>>>'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.