Geben Sie einen SSH-Schlüssel für Git Push für eine bestimmte Domain an


342

Ich habe den folgenden Anwendungsfall: Ich möchte in der Lage sein, auf die git@git.company.com:gitolite-adminVerwendung des privaten Schlüssels des Benutzers gitolite-adminzu pushen, während ich auf die git@git.company.com:some_repoVerwendung von 'meinem' privaten Schlüssel pushen möchte . AFAIK, ich kann dies nicht mit lösen ~/.ssh/config, da der Benutzername und der Servername in beiden Fällen identisch sind. Als ich vor allem meine eigenen privaten Schlüssel verwenden, habe ich das in definiert ~/.ssh/configfür git@git.company.com. Kennt jemand eine Möglichkeit, den Schlüssel zu überschreiben, der für einen einzelnen gitAufruf verwendet wird?

(Abgesehen davon: gitolite unterscheidet anhand des Schlüssels, wer das Drücken ausführt. Daher ist es in Bezug auf Zugriff, Besitz und Überwachung kein Problem, dass die Zeichenfolge user @ server für verschiedene Benutzer identisch ist.)


Antworten:


597

Auch wenn Benutzer und Host identisch sind, können sie dennoch unterschieden werden ~/.ssh/config. Wenn Ihre Konfiguration beispielsweise so aussieht:

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

Dann verwenden Sie einfach gitolite-as-aliceund gitolite-as-bobanstelle des Hostnamens in Ihrer URL:

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

Hinweis

Sie möchten die Option einschließen IdentitiesOnly yes, um die Verwendung von Standard-IDs zu verhindern. Andernfalls werden ID-Dateien, die mit den Standardnamen übereinstimmen, zuerst ausprobiert, da die IdentityFileOption im Gegensatz zu anderen Konfigurationsoptionen (die sich an "first in wins" halten) an die Liste der zu versuchenden Identitäten angehängt wird . Siehe: /server/450796/how-could-i-stop-ssh-offering-a-wrong-key/450807#450807


9
Super, danke. Ich hatte nicht verstanden, dass Sie einen 'Alias' für die Host-Spezifikation in der ~ / .ssh / config
Confusion

4
Danke auch für diese Antwort! Ein Problem für mich war, dass IdentityFile ein vollständiger Pfad sein muss (ich habe nur id_rsa.rick als Argument für IdentityFile angegeben, und dies ist fehlgeschlagen). Weitere Syntax für IdentityFile finden Sie in der Manpage ssh_config (5).
Rickumali

1
Vielen Dank für die klare und sehr hilfreiche Antwort. Ich hatte eine Weile versucht, dies zum Laufen zu bringen, und zuvor aufgegeben, mit der Annahme, dass derselbe Benutzer dieselbe private Schlüsseldatei id_rsa verwenden musste.
DrCord

7
Der git@Teil in der Fernbedienung ist nicht erforderlich, da er in der UserZeile der Konfiguration angegeben ist.
Dolmen

2
Ich hatte Probleme mit dieser Lösung, bis ich eine weitere Zeile hinzufügte, die IdentitiesOnly yesunmittelbar nach der Zeile mit IdentityFilefür den Host enthielt . Es scheint, dass mehrere Identitäten weitergegeben wurden und eine davon für den Zugriff auf den Host gesperrt war.
Fitter Man

57

Ein alternativer Ansatz zu dem oben von Mark Longair angebotenen besteht darin, einen Alias ​​zu verwenden, der jeden Git-Befehl auf jeder Fernbedienung mit einem alternativen SSH-Schlüssel ausführt. Die Idee ist im Grunde, Ihre SSH-Identität zu ändern, wenn Sie die git-Befehle ausführen.

Vorteile gegenüber dem Host-Alias-Ansatz in der anderen Antwort:

  • Funktioniert mit allen Git-Befehlen oder Aliasen, auch wenn Sie die nicht remoteexplizit angeben können .
  • Die Arbeit mit vielen Repositorys ist einfacher, da Sie sie nur einmal pro Clientcomputer einrichten müssen, nicht einmal pro Repository auf jedem Clientcomputer.

Ich benutze ein paar kleine Skripte und einen Git-Alias admin. So kann ich zum Beispiel:

git admin push 

So drücken Sie mit der alternativen SSH-Taste ("admin") auf die Standardfernbedienung. Auch hier können Sie pushmit diesem Alias einen beliebigen Befehl (nicht nur ) verwenden. Sie können sogar git admin clone ...ein Repository klonen, auf das Sie nur mit Ihrem "Admin" -Schlüssel zugreifen können.

Schritt 1: Erstellen Sie die alternativen SSH-Schlüssel und legen Sie optional eine Passphrase fest, falls Sie dies auf einem anderen Computer tun.

Schritt 2: Erstellen Sie ein Skript mit dem Namen "ssh-as.sh", das Dinge ausführt, die SSH verwenden, aber einen bestimmten SSH-Schlüssel anstelle des Standardschlüssels verwenden:

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

Schritt 3: Erstellen Sie ein Skript mit dem Namen "git-as.sh", das git-Befehle mit dem angegebenen SSH-Schlüssel ausführt.

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

Schritt 4: Fügen Sie einen Alias ​​hinzu (verwenden Sie etwas, das für "PATH_TO_SCRIPTS_DIR" unten geeignet ist):

# 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"

Weitere Details unter: http://noamlewis.wordpress.com/2013/01/24/git-admin-an-alias-for-running-git-commands-as-a-privileged-ssh-identity/


4
Sehr schöne Antwort. Vergessen Sie nicht, doppelte Anführungszeichen hinzuzufügen $@-> "$@"um sicher zu gehen.
Kevinarpe

@sinelaw Funktioniert das noch? Ich erhalte ständig die Berechtigung verweigert Fehler
Alok Kumar

55

Sie können die Umgebungsvariable git verwenden GIT_SSH_COMMAND. Führen Sie dies in Ihrem Terminal unter Ihrem Git-Repository aus:

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

Ersetzen Sie ihn ~/.ssh/your_private_keydurch den Pfad des privaten SSH-Schlüssels, den Sie verwenden möchten. Und Sie können den nachfolgenden Befehl git ändern (im Beispiel istgit submodule update --init ) , um wie andere git pull, git fetchusw.


1
Das vollständige Dokument finden Sie unter git-scm.com/docs/git#git-codeGITSSHcode . es braucht allerdings einen neueren Git (> = 2.3. *).
Christian Ulbrich

2
Vielen Dank für eine einfache Lösung, für die nur eine Umgebungsvariable festgelegt werden muss.
Noah Sussman

4
Beachten Sie, dass Ihr ~ / .ssh / id_rsa (oder was auch immer Ihr Standardschlüssel ist) Vorrang vor dem hat, den Sie über -i übergeben. Sie möchten also wirklich GIT_SSH_COMMAND = 'ssh -i ~ / .ssh / your_private_key -o IdentitiesOnly = yes' verwenden, damit andere Schlüssel ignoriert werden
staktrace

Wie können Sie Git Push aktualisieren? Ich konnte es nicht in der Dokumentation finden
lebed2045

Es wäre schön, entweder Bash- oder Git-Aliase zu erstellen - ähnlich wie bei Sinelaws Antwort, aber mit dieser Methode, anstatt irgendwo Skripte erstellen zu müssen.
Inigo

14

Bei einem Unix-basierten System (Linux, BSD, Mac OS X) wird die Standardidentität im Verzeichnis $ HOME / .ssh in zwei Dateien gespeichert: private key: $HOME/.ssh/id_rsa public key: $HOME/.ssh/id_rsa.pub Bei Verwendung sshohne Option-i , wird der private Standardschlüssel zur Authentifizierung beim Remote-System verwendet.

Wenn Sie einen anderen privaten Schlüssel haben, den Sie verwenden möchten, z. B. $ HOME / .ssh / deploy_key , müssen Sie diesen verwendenssh -i ~/.ssh/deploy_key ...

Es ist nervig. Sie können Ihrem $ HOME / .bash_profile die folgenden Zeilen hinzufügen : ssh-add ~/.ssh/deploy_key ssh-add ~/.ssh/id_rsa

Jedes Mal, wenn Sie sshoder gitoder scp(im Grunde sshauch) verwenden, müssen Sie die Option -inicht mehr verwenden.

Sie können der Datei $ HOME / .bash_profile beliebig viele Schlüssel hinzufügen .


10

Eine andere Alternative ist die Verwendung von ssh-ident, um Ihre ssh-Identitäten zu verwalten .

Es lädt und verwendet automatisch verschiedene Schlüssel basierend auf Ihrem aktuellen Arbeitsverzeichnis, den SSH-Optionen usw. Dies bedeutet, dass Sie problemlos ein Arbeits- / Verzeichnis und ein Privatverzeichnis haben können, die transparent unterschiedliche Schlüssel und Identitäten mit SSH verwenden.


9

Ich benutze Git Bash unter Win7. Folgendes hat bei mir funktioniert.

Erstellen Sie eine Konfigurationsdatei unter ~ / .ssh / config oder c: / users / [Ihr_Benutzername] / .ssh / config. Geben Sie in die Datei Folgendes ein:

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

Ich denke, der Host muss eine URL sein und nicht nur ein "Name" oder eine Referenz für Ihren Host. Zum Beispiel,

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

Der Pfad kann auch im Format / c / users / [Benutzername] / .... geschrieben werden

Die Lösung von Giordano Scalzo ist ebenfalls großartig. https://stackoverflow.com/a/9149518/1738546


9

Ab Git 2.10 ist es auch möglich, die Einstellung gitconfig sshCommand zu verwenden. Dokumentstatus :

Wenn diese Variable festgelegt ist, verwenden git fetch und git push den angegebenen Befehl anstelle von ssh, wenn eine Verbindung zu einem Remote-System hergestellt werden muss. Der Befehl hat dieselbe Form wie die Umgebungsvariable GIT_SSH_COMMAND und wird überschrieben, wenn die Umgebungsvariable festgelegt wird.

Ein Anwendungsbeispiel wäre: git config core.sshCommand "ssh -i ~/.ssh/[insert_your_keyname]

In einigen Fällen funktioniert dies nicht, da ssh_config den Befehl überschreibt. In diesem Fall versuchen Sie ssh -i ~/.ssh/[insert_your_keyname] -F /dev/null, ssh_config nicht zu verwenden.


8

Ich habe den folgenden Ansatz zusammengestellt und mit Github getestet, basierend auf dem Lesen anderer Antworten, der einige Techniken kombiniert:

  • korrekte SSH-Konfiguration
  • Git URL neu schreiben

Der Vorteil dieses Ansatzes besteht darin, dass nach dem Einrichten keine zusätzliche Arbeit erforderlich ist, um ihn richtig zu machen. Sie müssen beispielsweise keine Remote-URLs ändern oder daran denken, die Dinge anders zu klonen. Durch das Umschreiben der URL funktioniert alles .

~/.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

Solange Sie alle Ihre Arbeitsrepos unter ~ / dev / work und persönlichen Dingen an anderer Stelle aufbewahren, verwendet git beim Ziehen / Klonen / Drücken auf den Server den richtigen SSH-Schlüssel und hängt auch die richtige E-Mail-Adresse an alle an Ihre Verpflichtungen.

Verweise:


Wie funktioniert das mit dem Klonen? includeIfsollte nur funktionieren, wenn ein .gitVerzeichnis vorhanden ist, dachte ich?
Detly

Warten Sie, ich verstehe, es ist das Umschreiben der URL, das sich darum kümmert. Diese Antwort ist unglaublich nützlich!
Detly

4

Wenn Sie die Git-Version von ssh unter Windows verwenden, sieht die Zeile der Identitätsdatei in der ssh-Konfiguration so aus

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

wo /cist fürc:

Um das zu überprüfen, tun Sie es in Git's Bash

cd ~/.ssh
pwd 

3

Möglicherweise müssen Sie die Standard-Host-Konfiguration entfernen (oder auskommentieren) .ssh / config


1

Sie haben am meisten in der Datei Konfigurationsschlüssel ssh angegeben:

# 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

Wie bereits erwähnt, core.sshCommandkann config verwendet werden, um den SSH-Schlüssel und andere Parameter zu überschreiben.

Hier ist ein Beispiel, in dem Sie einen alternativen Schlüssel mit dem Namen haben ~/.ssh/workrsaund ihn für alle unter geklonten Repositorys verwenden möchten ~/work.

  1. Erstellen Sie eine neue .gitconfigDatei unter ~/work:
[core]
  sshCommand = "ssh -i ~/.ssh/workrsa"
  1. Fügen Sie in Ihrer globalen Git-Konfiguration Folgendes ~/.gitconfighinzu:
[includeIf "gitdir:~/work/"]
  path = ~/work/.gitconfig

0

Eine Möglichkeit ~/.ssh/configbesteht darin, die MatchEinschränkung anstelle der HostEinschränkung zu verwenden. Ruft insbesondere Match Execeinen Shell-Befehl auf, um zu entscheiden, ob die Deklarationen angewendet werden sollen oder nicht. In bash können Sie den folgenden Befehl verwenden:

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

Dies verwendet den [Befehl bash, um zu überprüfen, ob zwei Zeichenfolgen gleich sind. In diesem Fall wird geprüft, ob die Zeichenfolge git@git.company.com:gitolite-adminmit der vom $(git config --get remote.origin.url)''Befehl erhaltenen Ausgabe übereinstimmt .

Sie können jeden anderen Befehl verwenden, der das Repository identifiziert, in dem sich die Shell befindet. Damit dies funktioniert, ist es in meinem Fall wichtig , dass die $SHELLVariable für Ihre Shell definiert ist /bin/bash. Das vollständige Beispiel wäre dann das folgende ~/.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

In diesem Beispiel habe ich angenommen, dass es ~/.ssh/yourOwnPrivateKeyIhren eigenen privaten Schlüssel ~/.ssh/gitolite-adminenthält und dass es den privaten Schlüssel des Benutzers enthält gitolite-admin. Ich habe die IdentitiesOnly yesErklärung beigefügt , um sicherzustellen, dass dem von Mark Longair erwähnten Git-Server nur ein Schlüssel angeboten wird . Die anderen Deklarationen sind nur Standard-SSH-Optionen für Git.

Sie können diese Konfiguration hinzufügen, wenn Sie mehrere haben some_repo, die Sie mit verschiedenen Schlüsseln verwenden möchten. Wenn Sie mehrere Repositorys haben git@git.company.comund die meisten von ihnen das verwenden ~/.ssh/yourOwnPrivateKey, ist es sinnvoller, diesen Schlüssel als Standard für den Host einzuschließen. In diesem Fall ~/.ssh/configwäre das:

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

Beachten Sie, dass die Reihenfolge wichtig ist und die Host git.company.comEinschränkung nach der Match Execeinen oder den anderen erscheinen sollte.


0

Konfigurieren Sie Ihr Repository mit git config. Zum Beispiel:

git config --add --local core.sshCommand 'ssh -i ~/.ssh/<<<PATH_TO_SSH_KEY>>>'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.