Wählen Sie einen privaten Schlüssel für Git aus

81

Ich habe 2 Git-Server, die 2 verschiedene SSH-Schlüssel benötigen.

git clone user1@server1:blahblahblahverwendet ~/.ssh/id_rsa, aber ich muss angeben, welcher Schlüssel verwendet werden soll, abhängig von dem Server, zu dem ich eine Verbindung herstelle.

Welcher Git-Befehlszeilenparameter erledigt diesen Job? (Ich verwende Linux.)

user349302
quelle

Antworten:

59

Wenn Sie eine Verbindung über SSH herstellen, wird der Schlüssel von einem SSH-Parameter und nicht von einem Git-Parameter gesteuert.

SSH sucht in der ~/.ssh/configDatei nach Konfigurationsparametern. Ändern Sie diese Datei und fügen Sie IdentityFile-Einträge für die beiden Git-Server wie folgt hinzu:

Host server1.whatever.com
  IdentityFile /path/to/key_1
Host server2.whatever.com
  IdentityFile /path/to/key_2

Dieser Artikel enthält einige weitere Details.

Cameron Skinner
quelle
12
Das hat die Frage nicht beantwortet. Die Frage ist, wie gebe ich git diesen Parameter, wenn ssh die Autorisierung übernimmt?
Kekse
@Keks: Sie können keine ssh-Argumente über die git-Befehlszeile übergeben. Diese Antwort bietet eine Problemumgehung. Es sind auch andere Problemumgehungen möglich, z. B. git.wiki.kernel.org/index.php/… . Beachten Sie, dass dieser Ansatz auch keine Befehlszeilenargumente verwendet, um das ssh-Verhalten zu ändern.
Cameron Skinner
12
Das ist wahr, aber Ihre ursprüngliche Antwort hat die Frage nicht beantwortet. Sie können auch git verwenden ssh-agentund verwenden ssh-addund dann einfach verwenden. Wenn git über ssh eine Verbindung herstellt, ist der Schlüssel bereits aktiviert. Sie sehen, es gibt verschiedene Möglichkeiten, und Ihre ursprüngliche Antwort hilft einfach nicht wirklich.
Keks
Dies ist so ziemlich eine Nur-Link-Antwort. Könnten Sie die relevanten Teile des Artikels in Ihrer Antwort zusammenfassen?
Flimm
@Flimm: Zusammenfassung hinzugefügt.
Cameron Skinner
92

Es gibt noch eine andere Möglichkeit. Das ist zu setzen core.sshCommand, zB

git config --local core.sshCommand "/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo"

Es gibt ein bestimmtes Szenario, in dem diese Strategie besonders nützlich ist: Wenn Sie mehrere Konten bei Github haben, wie alle Konten sshbei Github as, [email protected]und der sshSchlüssel verwendet, um zu bestimmen, welcher Github-Benutzer Sie sind. In diesem Fall wird .ssh/configund ssh-agentwird weder das getan, was Sie wollen.

Update - Sie können die oben genannten Schritte erst ausführen, wenn Sie über ein lokales Repository verfügen. Wenn Sie also versuchen, ein Remote-Repository zu klonen, müssen Sie den Schlüssel gemäß der Antwort von drawbie18 manuell angeben:

git clone -c core.sshCommand="/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo" [email protected]:me/repo.git

Sobald Sie das Repository geklont haben, können Sie den git configBefehl verwenden, um dies dauerhaft festzulegen.

Richard Smith
quelle
7
Dies sollte die ausgewählte Antwort sein. Die erforderliche Konfiguration ist im Repository gut lokalisiert, das unterschiedliche SSH-Schlüssel verwenden muss, um auf verschiedene Git-Server zuzugreifen. ~ / .Sssh / config muss nicht geändert werden (und sogar / etc / hosts, wenn mehrere Konten auf dem GitHub vorhanden sind).
mr.b
1
Es gibt jedoch ein Problem: Sie können ein Repo nicht klonen, bevor Sie es konfigurieren, und um es zu konfigurieren, müssen Sie es zuerst klonen lassen. ODER Sie können git initein Repo erstellen, es lokal so konfigurieren, dass der richtige ssh-Befehl verwendet wird, und dann eine Fernbedienung hinzufügen (3 Schritte, verglichen mit nur 1 mit "git clone").
mr.b
3
Um das Repo zu klonen, würde ich die folgende Lösung von @ Guss verwenden, indem ich die Umgebungsvariable GIT_SSH_COMMAND setze. Bei normaler Verwendung bevorzuge ich jedoch meine Lösung, da diese Variable nicht jedes Mal neu exportiert werden muss, wenn ich eine neue Shell starte.
Richard Smith
Lebensretter! Es gibt Unmengen von Leuten, die zeigen, wie man ./ssh/config verwendet, um dies einzurichten, und ssh-agent / ssh-add -K für Mac verwenden. Hatte es seit einem Jahr benutzt, aber es funktionierte plötzlich nicht mehr in High Sierra mit den neuesten Patches. core.sshCommand funktionierte, als alles andere fehlschlug. Vielen Dank!
Steve
2
Vielen Dank für diese elegante Lösung. Ich möchte jedoch nur präzisieren, dass core.sshCommand nur für git> = 2.10.0
slonepi
32

Im Allgemeinen möchten Sie ~/.ssh/configdies verwenden. Koppeln Sie einfach die Serveradressen wie folgt mit den Schlüsseln, die Sie für sie verwenden möchten:

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

Host *bezeichnet einen beliebigen Server, daher verwende ich ihn ~/.ssh/id_rsaals Standardschlüssel.

Zaz
quelle
9
Diese Idee funktioniert nicht, wenn Sie mehrere Konten auf einem Server wie GitHub haben und für jeden einen anderen privaten Schlüssel wünschen.
Flimm
Für mehrere Konten auf einem Server siehe diese Antwort stackoverflow.com/questions/3225862/…
lexicalscope
22

In meinem Szenario, ähnlich wie im @ Richard Smith-Szenario (dessen Lösung übrigens für mich nicht funktioniert hat), muss ich verschiedene Schlüssel für denselben Server unter verschiedenen Repositorys verwenden.

Die Problemumgehung für mich bestand darin, die Sitzung mit der Umgebungsvariablen GIT_SSH_COMMANDwie folgt korrekt einzurichten :

export GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/my-secret-identitiy"

Aktualisieren :

Eine andere Sache, die hier zu beachten ist, ist, dass das korrekte Einstellen der Umgebungsvariablen ein Problem sein kann. Daher verwende ich die Änderungsfunktionen der Eingabeaufforderung, die von Dingen wie Liquid Prompt oder Fish Shell bereitgestellt werden, um sich in die Shell einzuhaken und die Umgebungsvariablen entsprechend der zu aktualisieren aktuelles Verzeichnis und einige Regeln. Beispielsweise befinden sich alle meine persönlichen Projekte, die für meinen persönlichen SSH-Schlüssel mit Gitlab erforderlich sind, unter. ~/Documents/Projects/personalWenn der Shell-Hook ausgeführt wird pwdund feststellt, dass sich das aktuelle Verzeichnis unter diesem Pfad befindet, werden die GIT_SSH_COMMANDVariablen automatisch nach Bedarf festgelegt.

Guss
quelle
15

Verwenden Sie ssh-add path-to-private-keyes funktioniert sofort.

khelll
quelle
5
Nicht, wenn Sie zwei Bereitstellungsschlüssel haben und diese nur mit bestimmten Repositorys funktionieren. In diesem Fall wird möglicherweise der falsche Schlüssel verwendet und es wird angegeben, dass Sie keinen Zugriff haben.
CDMckay
Ich habe das Problem cdmckay gesagt
Suge
7

Sie können die Konfiguration --global oder --local festlegen, global aktualisiert die ~/.gitconfigDatei, local aktualisiert die Konfiguration im Repository .git/configund überschreibt die globale Konfiguration (~ / .gitconfig)

git config --local --add core.sshCommand 'ssh -i ~ / .ssh / my_key'

Maoz Zadok
quelle
2
Als Zauber gearbeitet, war dies genau das, was ich brauchte, eine Lösung für ein bestimmtes Repo.
Quästor Lucem
5

Windows-Benutzer hier, ich bin gerade auf dieses Problem gestoßen und habe eine etwas andere Lösung als ich hier bisher gelesen habe. Das Problem, mit dem ich konfrontiert war, war, dass ich einfach ein Repo mit einem bestimmten privaten SSH-Schlüssel klonen wollte und meine Git-Konfiguration nicht global konfigurieren oder bestimmte Git-Bash-Einstellungen hinzufügen musste, während ich meine Arbeit in PowerShell erledige. Im Wesentlichen möchte ich nur einige private Schlüssel in meinem .ssh-Ordner haben und verweise sie nach Bedarf in bestimmten Repos.

Der folgende Befehl funktioniert hierfür:

git clone -c core.sshCommand="ssh -i ~/.ssh/<PRIVATE KEY NAME>" <CLONE URL>

Im Wesentlichen wird dabei bei der Initialisierung des Git-Repos die Option core.sshCommand festgelegt, bevor der Klon ausgeführt wird. Der spezifische SSH-Schlüssel, den Sie für dieses Repo verwenden möchten, wird NUR für dieses Repo festgelegt. Dies ist möglicherweise nicht für alle Fälle eine ideale Lösung, aber für das, was ich will.

drawbie18
quelle
Vielen Dank. Ich war mir der -cOption nicht bewusst git clone. Dies ist besser als das Einstellen der Umgebung, wie ich beim Klonen vorschlage.
Richard Smith
1

Die anderen Antworten haben mich dazu inspiriert, ein kleines Skript zu schreiben, das den ssh-Schlüssel abhängig von den Befehlszeilenoptionen oder (falls vorhanden) den Werten von git remote -v auswählt. Ich hoffe es hilft!

Um die Frage tatsächlich zu beantworten: Verwenden Sie gat.

Siehe auch https://bitbucket.org/eikerobert/gat/src/master/

#!/bin/bash

usegat=false

for VAR in "$@"
do
    if [ "$VAR" != "${VAR/[email protected]:myaccount/}" ]; then
        usegat=true
    fi
done

if [ $usegat=false ]; then
   /usr/bin/git rev-parse --is-inside-work-tree >/dev/null 2>&1
   isinsidegitrepo=$?
    #echo $isinsidegitrepo
   if [ $isinsidegitrepo = 0 ]; then
       remote=`/usr/bin/git remote -v`
       if [ "$remote" != "${remote/[email protected]:myaccount/}" ]; then
           usegat=true
       fi
   fi
fi


if [ $usegat = true ]; then
    # echo "TRUE"
    /usr/bin/git -c core.sshCommand="/usr/bin/ssh -i /home/myaccount/.ssh/mykey" "$@"
else
     #echo "FALSE"
    /usr/bin/git "$@"
fi
Eike
quelle
0

Eine andere Möglichkeit besteht darin, ein kleines Skript zu schreiben core.sshCommand ein bisschen intelligenter Überprüfen Sie, ob im aktuellen Arbeitsverzeichnis ein bestimmter SSH-Schlüssel konfiguriert ist, und verwenden Sie ihn andernfalls. Verwenden Sie die Standardauflösung für den SSH-Schlüssel.

Hier ist meine erste Version:

#!/bin/bash
key="$(git config ssh.key)"
if [ -n "$key" ]; then
        ssh -o IdentitiesOnly=yes -i "$key" "$@"
else
        ssh "$@"
fi

Richten Sie es dann als globalen git SSH-Befehl ein:

chmod 755 ~/.local/bin/git-ssh-command
git config --global core.sshCommand ~/.local/bin/git-ssh-command

( ~/.local/binist der aktuelle Standard für "Benutzerskripte hier platzieren" auf SystemD-Betriebssystemen )

Nachdem Sie dies eingerichtet haben, können Sie jedes Repository für die Verwendung eines bestimmten SSH-Schlüssels konfigurieren, indem Sie die Konfigurationsoption festlegen ssh.key:

git config --local ssh.key ~/.ssh/my-non-default-private-key

Zusätzliche optionale Tricks

  • Stellen Sie die globale ssh.keyEinstellung so ein, dass sie einen "Standard-Fallback auf einen nicht standardmäßigen SSH-Schlüssel" oder ähnliches aufweist.
  • Während git core.sshCommandim Stammverzeichnis des Repositorys ausgeführt wird, kann Ihr Benutzer git-ssh-commanddies überprüfen und einige Heuristiken zu Verzeichnisnamen haben. Dies kann in diesem elseAbschnitt erfolgen, sodass Heuristiken nur dann aktiviert werden, wenn kein spezifischer Schlüssel vorhanden istssh.key .
  • Sie können git remote -vCheck hinzufügen , um Heuristiken basierend auf den Fernbedienungen hinzuzufügen, wie in Eikes Skript
  • Wenn Sie sich die Repository-Fernbedienungen ansehen möchten, aber mehrere Fernbedienungen haben, für die unterschiedliche Schlüssel erforderlich sind, können Sie remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"am Anfang des Skripts hinzufügen , um die Fernbedienung aufzulösen, mit der gearbeitet wird - und dies überprüfen ( $remotewürde wie die mittlere Spalte in der git remote -vAusgabe aussehen ).
Guss
quelle