Seleccione la clave privada para usar con Git


81

Tengo 2 servidores Git que requieren 2 claves SSH diferentes.

git clone user1@server1:blahblahblahusa ~/.ssh/id_rsa, pero necesito especificar qué clave usar dependiendo del servidor al que me estoy conectando.

¿Qué parámetro de línea de comandos de Git hace este trabajo? (Estoy ejecutando Linux).


2
Esta pregunta se responde en superuser.com/questions/232373/… .
Daira Hopwood


Respuestas:


59

Si se conecta a través de SSH, la clave será controlada por un parámetro SSH, no un parámetro git.

SSH busca en el ~/.ssh/configarchivo los parámetros de configuración. Modifique ese archivo y agregue entradas IdentityFile para los dos servidores Git de esta manera:

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

Este artículo tiene más detalles.


12
Eso no respondió a la pregunta. La pregunta es, ¿cómo le doy a git este parámetro, cuando ssh maneja la autorización?
keks

@Keks: no puede pasar argumentos ssh a través de la línea de comando git. Esta respuesta ofrece una solución alternativa. También hay otras soluciones posibles, por ejemplo, git.wiki.kernel.org/index.php/… . Tenga en cuenta que ese enfoque tampoco utiliza argumentos de línea de comandos para modificar el comportamiento de ssh.
Cameron Skinner

12
Eso es cierto, sin embargo, su respuesta original no respondió la pregunta. También puede usar ssh-agenty usar ssh-addy luego simplemente usar git. Cuando git se conecta a través de ssh, la clave ya está habilitada. Verá, hay varias formas, y su respuesta original simplemente no ayuda.
keks

Esta es una respuesta de solo enlace. ¿Podrías resumir los fragmentos relevantes del artículo en tu respuesta?
Flimm

@Flimm: Resumen agregado.
Cameron Skinner

92

Existe otra posibilidad. Eso es para configurar core.sshCommand, por ejemplo

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

Hay un escenario particular en el que esta estrategia es particularmente útil: es cuando tienes varias cuentas en Github, ya que todas las cuentas están sshen Github git@github.comy usa la sshclave para determinar qué usuario de Github eres. En este caso ni .ssh/configni ssh-agentharás lo que quieras.

Actualización : no puede ejecutar lo anterior hasta que tenga un repositorio local, por lo que si está tratando de clonar un repositorio remoto, deberá especificar la clave manualmente según la respuesta de drewbie18:

git clone -c core.sshCommand="/usr/bin/ssh -i /home/me/.ssh/id_rsa_foo" git@github.com:me/repo.git

Una vez que haya clonado el repositorio, puede usar el git configcomando para configurarlo de forma permanente.


7
Esta debería ser la respuesta seleccionada. La configuración requerida está muy bien localizada en el repositorio que necesita usar una clave ssh diferente para acceder a diferentes servidores git. No es necesario modificar ~ / .ssh / config (e incluso / etc / hosts, en caso de múltiples cuentas en GitHub).
Sr.b

1
Sin embargo, hay un problema: no puede clonar un repositorio antes de configurarlo y, para configurarlo, primero debe clonarlo. O, puede git initun repositorio, configurarlo localmente para usar el comando ssh correcto y luego agregar un control remoto (3 pasos, en comparación con solo 1 con "git clone").
Sr.b

3
Para clonar el repositorio, usaría la solución de @ Guss, a continuación, configurando la variable de entorno GIT_SSH_COMMAND. Pero en el uso normal prefiero mi solución, ya que evita tener que volver a exportar esa variable cada vez que inicio un nuevo shell.
Richard Smith

¡salvador de la vida! Hay toneladas de personas que muestran cómo usar ./ssh/config para configurar esto, y cómo usar ssh-agent / ssh-add -K para mac. Lo había estado usando durante un año, pero de repente dejó de funcionar en High Sierra con los últimos parches. core.sshCommand funcionó cuando todo lo demás falló. ¡Gracias!
Steve

2
Gracias por esta elegante solución. Sin embargo, solo quiero precisar que core.sshCommand solo está disponible para git> = 2.10.0
slonepi

32

Generalmente, desea usar ~/.ssh/configpara esto. Simplemente empareje las direcciones del servidor con las claves que desea usar para ellos de la siguiente manera:

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

Host *denota cualquier servidor, así que lo uso para establecer ~/.ssh/id_rsacomo la clave predeterminada para usar.


9
Esta idea no funciona si tiene varias cuentas en un servidor como GitHub, y desea una clave privada diferente para cada una.
Flimm

Para varias cuentas en un servidor, consulte esta respuesta stackoverflow.com/questions/3225862/…
lexicalscope

22

En mi escenario, similar al escenario de @Richard Smith (cuya solución, por cierto, no funcionó para mí), necesito usar diferentes claves para el mismo servidor en diferentes repositorios.

La solución para mí fue configurar la sesión correctamente con la variable de entorno GIT_SSH_COMMAND, así:

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

Actualización :

Otra cosa a tener en cuenta aquí es que configurar la variable de entorno correctamente puede ser complicado, por lo que estoy usando las funciones de modificación del símbolo del sistema proporcionadas por cosas como Liquid Prompt o Fish Shell para conectarme al shell y seguir actualizando las variables de entorno de acuerdo con el directorio actual y algunas reglas. Por ejemplo, todos mis proyectos personales que necesitan mi clave SSH personal con Gitlab están debajo, ~/Documents/Projects/personalpor lo que cuando se ejecuta el enlace de shell pwdy encuentra que el directorio actual está debajo de esa ruta, establece automáticamente las GIT_SSH_COMMANDvariables según sea necesario.


15

Úselo ssh-add path-to-private-keyfunciona fuera de la caja.


5
No si tiene dos claves de implementación y solo funcionan con ciertos repositorios. En ese caso, puede usar la clave incorrecta y decir que no tiene acceso.
cdmckay

Tengo el problema, dijo cdmckay
Suge

7

Puede establecer la configuración --global o --local, global actualizará el ~/.gitconfigarchivo, local actualizará la configuración en el repositorio .git/configy anulará la configuración global (~ / .gitconfig)

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


2
funcionó como un encanto, esto era exactamente lo que necesitaba, una solución para un repositorio específico.
Quaestor Lucem

5

Usuario de Windows aquí, acabo de encontrarme con este problema y tengo una solución ligeramente diferente a la que he leído aquí hasta ahora. El problema que enfrenté es que simplemente quería clonar un repositorio usando una clave ssh privada específica y no tener que configurar globalmente mi configuración de git o agregar configuraciones específicas de git bash, ya que hago mi trabajo en PowerShell. Básicamente, solo quiero tener algunas claves privadas en mi carpeta .ssh y las hago referencia en repositorios específicos según sea necesario.

El siguiente comando funciona para esto:

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

Básicamente, lo que hace esto es que al inicializar el repositorio git establece la opción core.sshCommand antes de ejecutar el clon. Por lo tanto, la clave ssh específica que desea usar para este repositorio está configurada SOLAMENTE para este repositorio. Puede que esta no sea una solución ideal para todos los casos, pero para lo que quiero es.


Gracias. No conocía la -copción de hacerlo git clone. Esto es mejor que configurar el entorno como sugiero al clonar.
Richard Smith

1

Las otras respuestas me inspiraron a escribir un pequeño script que elige la clave ssh dependiendo de las opciones de la línea de comandos o (si están presentes) los valores de git remote -v. ¡Espero eso ayude!

Para responder realmente a la pregunta: use gat.

Véase también https://bitbucket.org/eikerobert/gat/src/master/

#!/bin/bash

usegat=false

for VAR in "$@"
do
    if [ "$VAR" != "${VAR/git@bitbucket.org: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/git@bitbucket.org: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

0

Otra opción es escribir un pequeño script para hacerlo core.sshCommandun poco más inteligente: verifique si el directorio de trabajo actual tiene una clave SSH específica configurada y, si es así, úsela; de lo contrario, confíe en la resolución de clave SSH estándar.

Aquí está mi primera versión:

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

Luego configúrelo como el comando global git SSH:

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

( ~/.local/bines el estándar actual para "colocar scripts de usuario aquí" en los sistemas operativos SystemD )

Después de configurar esto, puede configurar cualquier repositorio para usar una clave SSH específica configurando la opción de configuración ssh.key:

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

Trucos opcionales adicionales

  • Establecer el global ssh.key para tener un "respaldo predeterminado a la clave SSH no predeterminada" o algo así.
  • A medida que git se ejecuta core.sshCommanden el directorio raíz del repositorio, su cliente git-ssh-commandpuede ver eso y tener algunas heurísticas sobre los nombres de directorio. Esto se puede hacer en la elsesección para que la heurística solo se active si no hay una clave específica ssh.key.
  • Puede agregar git remote -vverificación para agregar heurísticas basadas en los controles remotos, como en el script de Eike
  • Si desea ver los controles remotos del repositorio, pero tiene varios controles remotos que necesitan claves diferentes, puede agregar remote="$1:$(sed "s,.* ,,;s,',,g"<<<"$2")"al comienzo del script para resolver el control remoto que se está operando, y verificarlo ( $remotese vería como la columna del medio en la git remote -vsalida).
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.