ssh
a l'option -i
pour indiquer le fichier de clé privée à utiliser lors de l'authentification:
-i identity_file
Sélectionne un fichier dans lequel l'identité (clé privée) pour l'authentification RSA ou DSA est lue. La valeur par défaut est
~/.ssh/identity
pour la version 1 du protocole, et~/.ssh/id_rsa
et~/.ssh/id_dsa
pour la version 2 du protocole. Les fichiers d'identité peuvent également être spécifiés par hôte dans le fichier de configuration. Il est possible d’avoir plusieurs-i
options (et plusieurs identités spécifiées dans les fichiers de configuration).
Existe-t-il une méthode similaire pour indiquer à git
le fichier de clé privée à utiliser sur un système comportant plusieurs clés privées dans le répertoire ~/.ssh
?
Dans ~/.ssh/config
, ajoutez:
Host github.com
HostName github.com
IdentityFile ~/.ssh/id_rsa_github
User git
Maintenant, vous pouvez faire git clone [email protected]:username/repo.git
.
REMARQUE: Vérifiez que les autorisations sur IdentityFile sont 400.SSH rejettera, de manière non explicite, les clés SSH trop lisibles. Cela ressemblera simplement à un rejet de titres de compétences. La solution, dans ce cas, est la suivante:
chmod 400 ~/.ssh/id_rsa_github
GIT_SSH_COMMAND
:A partir de la version 2.3.0 de Git, vous pouvez utiliser la variable d'environnement GIT_SSH_COMMAND
comme ceci:
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example" git clone example
Notez que -i
peut parfois être remplacé par votre fichier de configuration. Dans ce cas, vous devez donner à SSH un fichier de configuration vide, comme ceci:
GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example -F /dev/null" git clone example
core.sshCommand
:À partir de la version 2.10.0 de Git, vous pouvez le configurer par référentiel ou globalement, de sorte que vous n’ayez plus à définir la variable d’environnement!
git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git Push
Il y a no direct way indiquer à git
quelle clé privée utiliser, car elle repose sur ssh
pour l'authentification du référentiel. Cependant, il existe encore quelques moyens pour atteindre votre objectif:
ssh-agent
Vous pouvez utiliser ssh-agent
pour autoriser temporairement votre clé privée.
Par exemple:
$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@Host'
GIT_SSH_COMMAND
Passez les arguments ssh en utilisant la variable d’environnement GIT_SSH_COMMAND
(Git 2.3.0+).
Par exemple:
$ GIT_SSH_COMMAND='ssh -i ~/.ssh/id_rsa -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no' \
git clone user@Host
Vous pouvez taper tout cela sur une seule ligne - ignorez $
et laissez le \
de côté.
GIT_SSH
Passez les arguments ssh en utilisant la variable d'environnement GIT_SSH
pour spécifier un autre binaire ssh
.
Par exemple:
$ 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
Remarque: Les lignes ci-dessus sont des lignes de commande Shell (terminal) que vous devez coller dans votre terminal. Ils vont créer un fichier nommé ssh
, le rendre exécutable et (indirectement) l'exécuter.
Remarque: GIT_SSH
est disponible depuis la v0.99.4 (2005).
~/.ssh/config
Utilisez le fichier ~/.ssh/config
comme suggéré dans d'autres réponses afin de spécifier l'emplacement de votre clé privée, par exemple.
Host github.com
User git
Hostname github.com
IdentityFile ~/.ssh/id_rsa
Ecrivez un script qui appelle ssh
avec les arguments de votre choix et mettez le nom de fichier du script dans $GIT_SSH
. Ou mettez simplement votre configuration dans ~/.ssh/config
.
Si vous ne souhaitez pas spécifier les variables d'environnement chaque fois que vous exécutez git, ne voulez pas d'autre script d'encapsuleur, n'exécutez/ne pouvez pas exécuter ssh-agent (1), et ne souhaitez pas télécharger un autre package rien que pour cela, utilisez git - transport externe à distance (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)
Je considère cette solution supérieure parce que:
Après ma lutte avec $GIT_SSH
, je voudrais partager ce qui a fonctionné pour moi.
À travers mes exemples, je supposerai que votre clé privée est située à/home/user/.ssh/jenkins
$ export GIT_SSH="ssh -i /home/user/.ssh/jenkins"
ou quelque chose de semblable échouera, car git tentera d'exécuter la valeur sous la forme d'un fichier . Pour cette raison, vous devez créer un script.
/home/user/gssh.sh
Le script sera appelé comme suit:
$ $GIT_SSH [username@]Host [-p <port>] <command>
Exemple de script pouvant ressembler à:
#!/bin/sh
ssh -i /home/user/.ssh/jenkins $*
Notez le $*
à la fin, c’est une partie importante de celui-ci.
Une alternative encore plus sûre, qui éviterait tout conflit éventuel avec quoi que ce soit dans votre fichier de configuration par défaut (en mentionnant explicitement le port à utiliser) serait:
#!/bin/sh
ssh -i /home/user/.ssh/jenkins -F /dev/null -p 22 $*
En supposant que le script soit en /home/user/gssh.sh
, vous devrez alors:
$ export GIT_SSH=/home/user/gssh.sh
et tout fonctionnera.
Utilisez la configuration d’hôte personnalisée dans ~/.ssh/config
, comme ceci:
Host gitlab-as-thuc
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa.thuc
IdentitiesOnly yes
utilisez ensuite votre nom d’hôte personnalisé comme ceci:
git remote add thuc git@gitlab-as-thuc:your-repo.git
Vous pouvez simplement utiliser ssh-ident au lieu de créer votre propre wrapper.
Vous pouvez en savoir plus sur: https://github.com/ccontavalli/ssh-ident
Il charge les clés ssh à la demande lorsque cela est nécessaire pour la première fois, même avec plusieurs sessions de connexion, xterms ou foyers partagés NFS.
Avec un fichier de configuration minuscule, il peut charger automatiquement différentes clés et les garder séparées dans différents agents (pour le transfert d'agent) en fonction de vos tâches.
J'ai eu un client qui avait besoin d'un compte séparé github. Je devais donc utiliser une clé distincte uniquement pour ce projet.
Ma solution a été d'ajouter ceci à mon .zshrc/.bashrc:
alias infogit="GIT_SSH_COMMAND=\"ssh -i ~/.ssh/id_specialkey\" git $@"
Chaque fois que je veux utiliser git pour ce projet, je remplace "infogit" par git:
infogit commit -am "Some message" && infogit Push
Pour moi, c'est plus facile à retenir.
Je règle donc la variable env GIT_SSH sur $HOME/bin/git-ssh
.
Pour que ma configuration de référentiel dicte l'identité ssh à utiliser, mon fichier ~/bin/git-ssh
est le suivant:
#!/bin/sh
ssh -i $(git config --get ssh.identity) -F /dev/null -p 22 $*
Ensuite, j'ai un paramètre global de configuration git:
$ git config --global ssh.identity ~/.ssh/default_id_rsa
Et dans n'importe quel référentiel git, je peux simplement définir une valeur de config ssh.identity
git locale:
$ git config --local ssh.identity ~/.ssh/any_other_id_rsa
Voila!
Si vous pouvez avoir une adresse e-mail différente pour chaque identité, cela devient encore plus simple, car vous pouvez simplement nommer vos clés après vos adresses e-mail, puis laisser le fichier user.email de git config piloter la sélection de clé dans un ~/bin/git-ssh
comme ceci:
#!/bin/sh
ssh -i $HOME/.ssh/$(git config --get user.email) -F /dev/null -p 22 $*
Ma solution était la suivante:
créer un script:
#!/bin/bash
KEY=dafault_key_to_be_used
PORT=10022 #default port...
for i in $@;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
alors quand vous devez changer le var run:
. ./thescript.sh [--port=] [--key=]
N'oubliez pas le point supplémentaire !! cela rend le script définir les environnements vars !! --key et --port sont optionnels.
Je construis sur @shellholic et ce SO thread avec quelques tecks. J'utilise GitHub comme exemple et suppose que vous avez une clé privée dans ~/.ssh/github
(sinon, consultez this SO thread ) et que vous avez ajouté la clé publique à votre profil GitHub (sinon, consultez L'aide de GitHub ).
Si nécessaire, créez un nouveau fichier de configuration SSH à ~/.ssh/config
et modifiez les autorisations à 400
touch ~/.ssh/config
chmod 600 ~/.ssh/config
Ajoutez ceci au fichier ~/.ssh/config
:
Host github.com
IdentityFile ~/.ssh/github
IdentitiesOnly yes
Si vous avez déjà une configuration à distance, vous pouvez vouloir la supprimer, sinon vous pouvez toujours être invité à entrer votre nom d'utilisateur et votre mot de passe:
git remote rm Origin
Ajoutez ensuite une télécommande au référentiel git et notez les deux points avant le nom d'utilisateur:
git remote add Origin [email protected]:user_name/repo_name.git
Et puis les commandes git fonctionnent normalement, par exemple:
git Push Origin master
git pull Origin
@HeyWatchThis on this SO thread a suggéré d'ajouter IdentitiesOnly yes
pour empêcher le comportement par défaut de SSH consistant à envoyer le fichier d'identité correspondant au nom de fichier par défaut pour chaque protocole. Voir ce fil pour plus d'informations et de références.
Utilisez simplement les commandes ssh-agent
et 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>
Après avoir exécuté les commandes ci-dessus, vous pouvez utiliser les deux touches simultanément. Il suffit de taper
git clone [email protected]:<yourname>/<your-repo>.git
pour cloner votre référentiel.
Vous devez exécuter la commande ci-dessus après le redémarrage de votre ordinateur.
Généralement, vous souhaitez utiliser ~/.ssh/config
pour cela. Associez simplement les adresses de serveur aux clés que vous souhaitez utiliser pour elles comme suit:
Host github.com
IdentityFile ~/.ssh/id_rsa.github
Host heroku.com
IdentityFile ~/.ssh/id_rsa.heroku
Host *
IdentityFile ~/.ssh/id_rsa
Host *
désigne n'importe quel serveur, je l'utilise donc pour définir ~/.ssh/id_rsa
comme clé par défaut à utiliser.
J'utilise la version 2.16 de git et je n'ai pas besoin d'un seul script, pas même d'une commande de configuration ou modifiée.
Et git lit à clé automatiquement. Je ne demande rien et ça ne jette pas d'erreur. Ça fonctionne très bien.
Bien que la question ne le demande pas, j'inclus cette réponse pour toute autre personne cherchant à résoudre le même problème spécifiquement pour gitlab .
J'ai essayé d'utiliser les variables-d'environnement , mais même la documentation git recommande d'utiliser ~/.ssh/config
pour autre chose que le cas simple. Dans mon cas, je pousse vers un gitlab serveur - et je voulais le faire en tant qu’utilisateur spécifique - ce qui est bien sûr défini par la clé privée pendant authentification et pas le nom d'utilisateur git
. Une fois implémenté, je réalise simplement ce qui suit:
~/myrepo> git mycommit -m "Important Stuff"
~/myrepo> git mypush
[proceed to enter passphrase for private key...]
Rappelez l’emplacement de votre clé privée/myfolder/.ssh/my_gitlab_id_rsa
dans mon cas.
Ajouter une entrée dans ~/.ssh/config
:
Host gitlab-delegate
HostName gitlab.mydomain.com
User git
IdentityFile /myfolder/.ssh/my_gitlab_id_rsa
IdentitiesOnly yes
Ajoutez le git-alias in ~/.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 git@gitlab-delegate:$path && \
git Push gitlab_as_me $branch && \
git pull Origin $branch; \
git remote remove gitlab_as_me; \
}; f"
En bonus, je effectue mes commits sur ce même hôte en tant qu'utilisateur spécifique avec ceci git-alias :
mycommit = "!f() { \
git -c "user.name=myname" -c "[email protected]" commit \"$@\"; \
}; f"
Tout ce qui précède suppose que la télécommande pertinente est Origin
et que la branche pertinente est actuellement extraite. Pour référence, j'ai rencontré plusieurs points qui devaient être abordés:
gitlab_as_me
distant, et je n'aimais pas voir la télécommande supplémentaire traîner dans mon journal je l'ai donc supprimé une fois l'opération terminée.gitlab_as_me
, vous devez préciser la branche que vous poussez.Origin
local doit être "mis à jour" pour correspondre à gitlab_as_me
(le git pull Origin $branch
le fait).