Frage Wie kann ich git mitteilen, welchen privaten Schlüssel er verwenden soll?


ssh hat die -i Option, um anzugeben, welche private Schlüsseldatei beim Authentifizieren verwendet werden soll:

-i identity_file

    Wählt eine Datei aus, von der   Die Identität (privater Schlüssel) für die RSA- oder DSA-Authentifizierung wird gelesen.   Der Standardwert ist ~/.ssh/identity für Protokollversion 1,   und ~/.ssh/id_rsa und ~/.ssh/id_dsa für Protokollversion 2.   Identitätsdateien können auch pro Host-Basis angegeben werden   in der Konfigurationsdatei. Es ist möglich, mehrere zu haben -i Optionen    (und mehrere Identitäten, die in Konfigurationsdateien angegeben sind).

Gibt es eine ähnliche Art zu erzählen? git welche private Schlüsseldatei auf einem System mit mehreren privaten Schlüsseln in der ~/.ssh Verzeichnis?


463
2018-01-12 18:20


Ursprung


Sehen diese Frage in StackOverflow auch. - Flimm
Auch verwandt serverfault.com/questions/194567/... - Machavity


Antworten:


Im ~/.ssh/config, hinzufügen:

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

Jetzt können Sie tun git clone git@github.com:username/repo.git.

HINWEIS: Stellen Sie sicher, dass die Berechtigungen für IdentityFile 400 sind. NSH weist auf nicht eindeutig explizite Weise SSH-Schlüssel zurück, die zu lesbar sind. Es wird nur wie eine Ablehnung der Anmeldeinformationen aussehen. Die Lösung ist in diesem Fall:

chmod 400 ~/.ssh/id_rsa_github

513
2018-01-12 19:36



Was ist, wenn Sie eine Verbindung mit demselben Host mit verschiedenen Schlüsseln herstellen müssen? - Valentin Klinghammer
@Quelltextfabrik - Sie können einen anderen Bereich mit einem anderen Host hinzufügen: nerderati.com/2011/03/ ... - Ben Challenor
@Cliff Nop, in meiner Manpage: "HostName: Gibt den echten Hostnamen für die Anmeldung an. Dies kann verwendet werden, um Kurznamen oder Abkürzungen für Hosts anzugeben. "Meine ssh-Version ist openssh-6.7p1. - Grissiom
@Grissiom Das ist genau das, was es sagt. Aber du scheinst die Bedeutung rückwärts zu verstehen. Host (oder Match) ist erforderlich. Um einen Host-Kurznamen zu erstellen, platzieren Sie den Kurznamen in der Host-Zeile und den echten Hostnamen in der HostName-Zeile. Beispiele: salzycrane.com/blog/2008/11/... - Cliff
Wenn die Konfigurationsdatei neu ist, vergessen Sie nicht zu tun chmod 600 ~/.ssh/config - elysch


Umgebungsvariable GIT_SSH_COMMAND:

Ab Git Version 2.3.0 können Sie die Umgebungsvariable verwenden GIT_SSH_COMMAND so was:

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

Beachten Sie, dass -i kann manchmal durch Ihre Konfigurationsdatei überschrieben werden, in diesem Fall sollten Sie SSH eine leere Konfigurationsdatei geben, wie folgt:

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

Aufbau core.sshCommand:

Ab Git Version 2.10.0 können Sie dies per Repo oder global konfigurieren, so dass Sie die Umgebungsvariable nicht mehr setzen müssen!

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

215
2018-05-08 09:43



Ich musste das exportieren Schale Variable zu einer Umgebungsvariablen, um dies zu ermöglichen, d.h. export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example", dann git clone example - Abdull
@Abdull In Bash exportiert die Zuweisung in derselben Zeile wie der Befehl die Umgebungsvariable für genau diesen Befehl. Versuch es: example=hello /usr/bin/env | grep example. - Flimm
Die Dinge sind noch besser geworden: Ab Git 2.10 kannst du den Befehl in deiner Git-Konfiguration speichern: stackoverflow.com/a/38474220/520162 - eckes
@Noitidart /dev/null ist nur ein gültiger Dateiname in UNIX-ähnlichen Betriebssystemen, es funktioniert nicht unter Windows. - Flimm
Wenn Sie mehrere Schlüssel benötigen, kann der Parameter -i wiederholt werden, und ssh wird jeden Schlüssel der Reihe nach versuchen. git config core.sshcommand "ssh -i /path/to/keyA -i /path/to/keyB". Dadurch können verschiedene Schlüssel mit verschiedenen Remote-Hosts verwendet werden. - Mark


Es gibt Nein Direkte Weg erzählen git welcher private Schlüssel zu verwenden ist, weil er darauf beruht ssh für die Repository-Authentifizierung. Es gibt jedoch noch einige Möglichkeiten, Ihr Ziel zu erreichen:

Option 1: ssh-agent

Sie können verwenden ssh-agent um Ihren privaten Schlüssel vorübergehend zu autorisieren.

Beispielsweise:

$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host'

Option 2: GIT_SSH_COMMAND

Übergeben Sie die SSH-Argumente mithilfe von GIT_SSH_COMMAND Umgebungsvariable (Git 2.3.0+).

Beispielsweise:

$ GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
  git clone user@host

Sie können dies alles in einer Zeile eingeben - ignorieren $ und lass die \.

Option 3: GIT_SSH

Übergeben Sie die SSH-Argumente mithilfe von GIT_SSH Umgebungsvariable zur Angabe von Alternate ssh binär.

Beispielsweise:

$ 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 user@host

Hinweis: Die obigen Zeilen sind Shell (Terminal) -Befehlszeilen, die Sie in Ihr Terminal einfügen sollten. Sie werden eine Datei namens erstellen sshmach es ausführbar und führe es (indirekt) aus.

Hinweis: GIT_SSH ist seit v0.99.4 verfügbar (2005).

Option 4: ~/.ssh/config

Benutze die ~/.ssh/config Datei, wie in anderen Antworten vorgeschlagen, um den Ort Ihres privaten Schlüssels anzugeben, z.

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

62
2018-01-23 22:08



//, Was ist, wenn Ihre Identität in ssh-agent weitergeleitet wird, wie in dieser Frage? superuser.com/questions/971732/ ... - Nathan Basanese
Ich habe mir erlaubt, diesen Beitrag neu zu formatieren: IMO, das ist bei weitem die umfassendste Antwort. In seinem ursprünglichen Design, ein schneller Scan vorgeschlagen, die Post, wo eine einzelne komplizierte Lösung für das Problem zu beschreiben, so habe ich es verpasst. - Alberto
$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host' arbeitete für mich, wenn nichts anderes würde. Kudos. - Daniel Dewhurst
Ich musste es benutzen ~/.ssh/config Methode, env vars hat nicht für mich funktioniert ... - Greg Dubicki
GIT_SSH ist seit verfügbar v0.99.4 (August 2005), also im Grunde seit Git existiert (April 2005). - Dominik


Schreiben Sie ein Skript, das aufruft ssh mit den Argumenten, die Sie wollen, und setzen Sie den Dateinamen des Skripts in $GIT_SSH. Oder stell einfach deine Konfiguration ein ~/.ssh/config.


32
2018-01-12 18:25



Eine andere Erklärung wie man das macht. - Sithsu
~/.ssh/config Ist das Weg zu gehen. - hek2mgl
Ich arbeite an einer Maschine (A), von der ich Push zu einem Server (B), der nur SSH-Schlüssel Authentifizierung akzeptiert. Während meine ~ / .ssh / config Einstellung auf (A) funktioniert perfekt, wenn ich direkt arbeite auf Diese Maschine funktioniert nicht, wenn ich mich von einem anderen Ort aus anmelde (C). Verwenden $GIT_SSH und ein Skript löste dieses Problem. Vielen Dank! - bsumirak


Wenn Sie nicht jedes Mal Umgebungsvariablen angeben müssen, wenn Sie git ausführen, kein anderes Wrapper-Skript, ssh-agent (1) nicht ausführen und / oder nur ein anderes Paket herunterladen möchten, verwenden Sie den git -remote-ext (1) externer Transport:

$ 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)

Ich halte diese Lösung für überlegen, weil:

  • Es ist Repository / Remote-spezifisch
  • Vermeiden Sie Wrapper Script Bloat
  • Benötigen Sie keinen SSH-Agenten - nützlich, wenn Sie unbeaufsichtigte Klone / Push / Pulls (z. B. in Cron) möchten
  • Definitiv, kein externes Tool benötigt

14
2017-07-21 19:44



//, Ausgezeichnete Lösung. Ich frage mich jedoch, ob es so möglich wäre, eine Identität anzugeben, die mit Agent-Weiterleitung durchgereicht wird. Die meisten meiner Schlüssel sind nicht lokal auf den Servern, auf denen ich sie verwende. Ich habe das hier gefragt: superuser.com/questions/971732/ ... - Nathan Basanese
Die Antwort befasst sich nur mit einer Möglichkeit, willkürliche Befehlszeilen anzugeben, die als Git-Repositories verwendet werden sollen. IMHO, sollten Sie versuchen, Ihr Problem mit ssh allein zu lösen (z. B. "ssh Gastgeber"sollte mit dem richtigen Schlüssel verbinden). Ich werde versuchen, weitere Informationen zu Ihrer anderen Frage zu liefern. - flaviovs
Diese Antwort war genau das, was ich brauchte, um Chef's zu zwingen git Ressource, um Repository-spezifische Implementierungsschlüssel zum Klonen / Abrufen von privaten Github-Repositories zu verwenden. Der zusätzliche Vorteil dieser Methode gegenüber den auf der Umgebung / Skript basierenden besteht darin, dass, da der Schlüsselpfad in der Konfiguration des Arbeits-Repos codiert ist, er den gleichen Schlüssel sowohl beim anfänglichen Klon als auch bei nachfolgenden Abrufen / Drücken verwendet. - Adam Franco
BEEINDRUCKEND! Das ist einfach toll, wusste nicht darüber. Danke für die Antwort, sehr hilfreich in Marionettenumgebungen, um den zusätzlichen Aufwand zu vermeiden .ssh/config usw. +1! - gf_
Wenn der folgende Fehler auftritt fatal: transport 'ext' not allowedSie müssen das ext - Protokoll über die Whitelist aufheben export GIT_ALLOW_PROTOCOL=ext. Im Grunde erlaubt der Remote-Helfer git-remote-ext (der die URLs "ext :: ssh example.com% S foo / repo" unterstützt) die Ausführung beliebiger Befehle. Dies ist normalerweise nicht von Bedeutung, da der Benutzer die URL, die an git übergeben wird, immer sieht und ihr vertraut. Git-Submodule ermöglichen es einem Angreifer jedoch über die Datei .gitmodules, vom Client das Abrufen beliebiger Git-URLs zu verlangen. hackerone.com/reports/104465 - Gomino


Nach meinem Kampf mit $GIT_SSH Ich möchte gerne erzählen, was für mich funktioniert hat.

Bei meinen Beispielen gehe ich davon aus, dass Sie Ihren privaten Schlüssel bei sich haben/home/user/.ssh/jenkins

Zu vermeidender Fehler: Der GIT_SSH-Wert enthält Optionen

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

oder was auch immer ähnlicher Wille versagt, wie git wird versuchen, den Wert als Datei auszuführen. Aus diesem Grund müssen Sie ein Skript erstellen.

Arbeitsbeispiel von $ GIT_SSH-Skript /home/user/gssh.sh

Das Skript wird wie folgt aufgerufen:

$ $GIT_SSH [username@]host [-p <port>] <command>

Das Arbeiten mit Beispielskripten könnte folgendermaßen aussehen:

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

Beachten Sie das $* Am Ende ist es ein wichtiger Teil davon.

Noch sicherere Alternative, die jeden möglichen Konflikt mit etwas in Ihrer Standardkonfigurationsdatei verhindern würde (plus ausdrücklich den zu verwendenden Hafen zu erwähnen), würde sein:

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

Vorausgesetzt, das Skript ist in /home/user/gssh.shDann sollst du:

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

und alles soll funktionieren.


13
2018-05-28 17:09



Vielen Dank. Nur zu beachten: Verwenden Sie "$ @" anstelle von $ * für Pass-Thru-Argumente, da die erstere sich korrekt verhält, wenn Argumente Whitespace enthalten. - Piotr Findeisen
@PiotrFindeisen Danke für deine Nachricht. Allerdings verstehe ich es nicht vollständig - in zsh hilft es mir, Strings mit Leerzeichen in einem Stück zu halten, aber in bash nicht. Kannst du mir mehr erzählen oder auf eine Erklärung hinweisen? Ich möchte keine Modifikation blind hinzufügen. - Jan Vlcinsky
Sie sollten die erste Hälfte Ihrer Antwort entfernen. Niemand interessiert sich für eine Lösung, die nicht funktioniert, und es ist verschwendete Lese, dass die richtige Antwort auf der Unterseite verschleiert, was wunderbar funktioniert. - Cerin
@Cerin Wenn du meinst den "Fehler zu vermeiden" entferne ich werde es dort behalten. Es teilt gemeinsame Fallstricke zu vermeiden und es ist sehr kurz. Ich bin mir sicher, dass jemand versuchen würde, die Lösung zu optimieren, indem er alle Dinge variabel bereitstellt (das ist mir passiert), also habe ich versucht, den Weg zum Erfolg zu verkürzen. - Jan Vlcinsky


Verwenden Sie benutzerdefinierte Host-Konfiguration in ~/.ssh/config, so was:

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

Verwenden Sie dann Ihren benutzerdefinierten Hostnamen wie folgt:

git remote add thuc git@gitlab-as-thuc:your-repo.git  

6
2018-05-17 15:03



Dies ist die Antwort, nach der ich gesucht habe, da ich GitHub-Accounts für Heim und Arbeit getrennt habe. Ich musste mich nur festlegen Host work.github.com  HostName github.com  IdentityFile ~/.ssh/workund ersetzen Sie dann "github.com" durch "work.github.com", wenn ich ein Arbeitsrepository kloniere. Es verbindet sich immer noch mit "github.com", aber mit einem nicht standardmäßigen Schlüsselpaar. - Mikkel
Die URL für Details ("itblog.studium.land / ... ") funktioniert nicht mehr :( - Carl Smotricz


Sie können einfach ssh-ident verwenden, anstatt einen eigenen Wrapper zu erstellen.

Sie können mehr lesen unter:    https://github.com/ccontavalli/ssh-ident

Es lädt SSH-Schlüssel bei Bedarf, wenn es einmal benötigt wird, sogar mit mehreren Login-Sitzungen, xterms oder NFS shared homes.

Mit einer winzigen Konfigurationsdatei können automatisch verschiedene Schlüssel geladen und in verschiedenen Agenten getrennt gespeichert werden (für die Agentenweiterleitung), je nachdem, was Sie tun müssen.


5
2018-03-23 01:35





Ich hatte einen Kunden, der ein separates GitHub-Konto benötigte. Also musste ich einen separaten Schlüssel nur für dieses eine Projekt verwenden.

Meine Lösung bestand darin, dies meiner .zshrc / .bashrc hinzuzufügen:

alias infogit="GIT_SSH_COMMAND=\"ssh -i ~/.ssh/id_specialkey\" git $@"

Wann immer ich git für dieses Projekt verwenden möchte, ersetze ich "infogit" durch git:

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

Für mich ist es leichter, sich daran zu erinnern.


3
2018-03-26 19:26