Questão Como dizer ao git qual chave privada usar?


ssh tem o -i opção para informar qual arquivo de chave privada usar ao autenticar:

-i identity_file

    Seleciona um arquivo do qual   a identidade (chave privada) para autenticação RSA ou DSA é lida.   O padrão é ~/.ssh/identity para a versão de protocolo 1,   e ~/.ssh/id_rsa e ~/.ssh/id_dsa para versão de protocolo 2.   Arquivos de identidade também podem ser especificados em uma base por host   no arquivo de configuração. É possível ter múltiplos -i opções    (e múltiplas identidades especificadas nos arquivos de configuração).

Existe uma maneira semelhante de dizer git qual arquivo de chave privada a ser usado em um sistema com várias chaves privadas no ~/.ssh diretório?


463


origem


Vejo esta pergunta no StackOverflow também. - Flimm
Também relacionado serverfault.com/questions/194567/… - Machavity


Respostas:


Dentro ~/.ssh/config, adicionar:

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

Agora você pode fazer git clone git@github.com:username/repo.git.

NOTA: Verifique se as permissões no IdentityFile são 400.SSH rejeitarão, de uma maneira não claramente explícita, as chaves SSH que são legíveis demais. Ele apenas parecerá uma rejeição de credencial. A solução, neste caso, é:

chmod 400 ~/.ssh/id_rsa_github

513



E se você precisar se conectar ao mesmo host com chaves diferentes? - Valentin Klinghammer
@Quelltextfabrik - você pode adicionar outra seção com um host diferente: nerderati.com/2011/03/… - Ben Challenor
@Cliff Nop, na minha manpage: "HostNameEspecifica o nome do host real para efetuar login. Isso pode ser usado para especificar apelidos ou abreviações para hosts. "Minha versão do ssh é openssh-6.7p1. - Grissiom
@Grissiom Isso é exatamente o que diz. Mas você parece entender o significado de trás para frente. Host (ou Match) é necessário. Para criar um apelido do host, coloque o apelido na linha Host e o nome do host real na linha HostName. Exemplos: saltycrane.com/blog/2008/11/… - Cliff
Se o arquivo de configuração é novo, não se esqueça de fazer chmod 600 ~/.ssh/config - elysch


Variável de ambiente GIT_SSH_COMMAND:

Do Git versão 2.3.0, você pode usar a variável de ambiente GIT_SSH_COMMAND como isso:

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

Observe que -i às vezes pode ser substituído pelo seu arquivo de configuração, nesse caso, você deve dar ao SSH um arquivo de configuração vazio, assim:

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

Configuração core.sshCommand:

A partir do Git versão 2.10.0, você pode configurá-lo por repo ou globalmente, assim você não precisa mais configurar a variável de ambiente!

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

214



Eu tive que exportar o Concha variável para uma variável de ambiente para fazer este trabalho, ou seja, export GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example", então git clone example - Abdull
@Abdull No Bash, fazer a atribuição na mesma linha que o comando exporta a variável de ambiente para apenas esse comando. Tente: example=hello /usr/bin/env | grep example. - Flimm
as coisas ficaram ainda melhores: a partir do Git 2.10, você pode armazenar o comando na sua configuração do Git: stackoverflow.com/a/38474220/520162 - eckes
@Noitidart /dev/null é apenas um nome de arquivo válido em sistemas operacionais semelhantes a UNIX, não funciona no Windows. - Flimm
Se você precisar de várias chaves, o parâmetro -i pode ser repetido, e o ssh tentará cada tecla sucessivamente. git config core.sshcommand "ssh -i /path/to/keyA -i /path/to/keyB". Isso permite que o git use chaves diferentes com diferentes hosts remotos. - Mark


Há sim não direto caminho contar git qual chave privada usar, porque depende ssh para autenticação do repositório. No entanto, ainda existem algumas maneiras de alcançar seu objetivo:

Opção 1: ssh-agent

Você pode usar ssh-agent para autorizar temporariamente sua chave privada.

Por exemplo:

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

Opção 2: GIT_SSH_COMMAND

Passe os argumentos ssh usando o GIT_SSH_COMMAND variável de ambiente (Git 2.3.0+).

Por exemplo:

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

Você pode digitar tudo isso em uma linha - ignore $ e deixar de fora o \.

Opção 3: GIT_SSH

Passe os argumentos ssh usando o GIT_SSH variável de ambiente para especificar alternativas ssh binário.

Por exemplo:

$ 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

Nota: As linhas acima são linhas de comando shell (terminal) que você deve colar no seu terminal. Eles vão criar um arquivo chamado ssh, torná-lo executável e (indiretamente) executá-lo.

Nota: GIT_SSH está disponível desde a v0.99.4 (2005).

Opção 4: ~/.ssh/config

Use o ~/.ssh/config arquivo conforme sugerido em outras respostas para especificar a localização da sua chave privada, por exemplo

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

62



//, E se a sua identidade em ssh-agent for encaminhada, como nesta pergunta? superuser.com/questions/971732/… - Nathan Basanese
Eu permiti reformatar este post: IMO, esta é de longe a resposta mais abrangente. Em seu projeto original, uma varredura rápida sugeriu que o post descrevesse uma única solução complicada para o problema, então eu perdi isso. - Alberto
$ ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; git fetch user@host' trabalhou para mim quando nada mais faria. Kudos - Daniel Dewhurst
Eu tive que usar ~/.ssh/config método, env vars não funcionou para mim ... - Greg Dubicki
GIT_SSH está disponível desde v0.99.4 (agosto de 2005)então basicamente desde que o Git existe (abril de 2005). - Dominik


Escreva um script que chama ssh com os argumentos que você quer, e coloque o nome do arquivo do script em $GIT_SSH. Ou apenas coloque sua configuração ~/.ssh/config.


32



Outra explicação de como fazer isso. - Sithsu
~/.ssh/config É a caminho a percorrer - hek2mgl
Eu trabalho em uma máquina (A) a partir da qual eu git empurrar para um servidor (B) que só aceita autenticação de chave ssh. Enquanto minha configuração ~ / .ssh / config em (A) funciona perfeitamente quando eu trabalho diretamente em essa máquina, isso não acontece quando eu faço o login de algum outro local (C). Usando $GIT_SSH e um script resolveu esse problema. Obrigado! - bsumirak


Se você não quer ter que especificar variáveis ​​de ambiente toda vez que você executa git, não quer outro script wrapper, não / não pode rodar ssh-agent (1), nem quer baixar outro pacote apenas para isso, use o git transporte externo -remote-ext (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)

Eu considero esta solução superior porque:

  • É repositório / remoto específico
  • Evite o inchaço do roteiro
  • Não precisa do agente SSH - útil se você quiser clones / push / pull não assistidos (por exemplo, no cron)
  • Definitivamente, nenhuma ferramenta externa necessária

14



//, excelente solução. Pergunto-me, no entanto, se isso permitiria que uma pessoa especificasse uma identidade passada usando o encaminhamento de agentes. A maioria das minhas chaves não é local para os servidores em que estou usando. Eu perguntei sobre isso aqui: superuser.com/questions/971732/… - Nathan Basanese
A resposta lida apenas com uma maneira de especificar linhas de comando arbitrárias a serem usadas como repositórios git. IMHO, você deve tentar resolver o problema usando ssh sozinho primeiro (por exemplo, "ssh hospedeiro"deve se conectar usando a tecla certa). Vou tentar fornecer mais informações sobre sua outra pergunta, no entanto. - flaviovs
Esta resposta foi exatamente o que eu precisava para forçar o Chef git recurso para usar chaves de implementação específicas do repositório para clonar / buscar de repositórios Github particulares. A vantagem adicional deste método sobre o ambiente / baseado em scripts é que, uma vez que o caminho-chave é codificado na configuração do repo-trabalho, ele usará a mesma chave no clone inicial e nas buscas / envios subseqüentes. - Adam Franco
UAU! Isso é ótimo, não sabia disso. Obrigado pela resposta, muito útil também em ambientes de marionetes, para evitar o incômodo extra para gerenciar .ssh/config etc. +1! - gf_
Se você encontrar o seguinte erro fatal: transport 'ext' not allowed, você tem que whitelist o protocolo ext através do export GIT_ALLOW_PROTOCOL=ext. Basicamente, o auxiliar remoto git-remote-ext (que suporta as URLs "ext :: ssh exemplo.com% S foo / repo") permite a execução arbitrária de comandos. Isso normalmente não é uma preocupação, pois o usuário sempre vê e confia na URL que passa para o git. No entanto, os submódulos git, através do arquivo .gitmodules, permitem que um invasor solicite que o cliente busque URLs git arbitrários. hackerone.com/reports/104465 - Gomino


Depois da minha luta com $GIT_SSH Eu gostaria de compartilhar o que funcionou para mim.

Através dos meus exemplos, assumirei que você tem sua chave privada localizada em/home/user/.ssh/jenkins

Erro ao evitar: o valor GIT_SSH inclui opções

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

ou qualquer coisa semelhante falhará, como git tentará executar o valor como um arquivo. Por esse motivo, você precisa criar um script.

Exemplo de trabalho do script $ GIT_SSH /home/user/gssh.sh

O script será chamado da seguinte maneira:

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

O script de exemplo funcionando pode se parecer com:

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

Note o $* no final, é parte importante disso.

Uma alternativa ainda mais segura, que evitaria qualquer conflito possível com qualquer coisa em seu arquivo de configuração padrão (além de mencionar explicitamente a porta a ser usada) seria:

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

Assumindo que o script esteja em /home/user/gssh.shvocê deve então:

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

e todos devem trabalhar.


13



Obrigado. Apenas observe: use "$ @" em vez de $ * para argumentos pass-thru, pois o primeiro se comporta corretamente quando os argumentos contêm espaços em branco. - Piotr Findeisen
@PiotrFindeisen Obrigado pela sua nota. No entanto, eu não entendo isso completamente - em zsh ele me ajuda a manter as cordas com espaço em uma peça, mas na bash não. Você pode me dizer mais ou apontar uma explicação? Eu não quero adicionar algumas modificações às cegas. - Jan Vlcinsky
Você deve remover a primeira metade da sua resposta. Ninguém está interessado em uma solução que não funciona, e é uma leitura desperdiçada que ofusca a resposta correta na parte inferior, que funciona maravilhosamente. - Cerin
@Cerin Se você quer dizer remover o "Erro para evitar" eu vou mantê-lo lá. Compartilha armadilha comum para evitar e é muito curto. Tenho certeza de que alguém tentaria otimizar a solução fornecendo todas as variáveis ​​(isso aconteceu comigo), então tentei encurtar o caminho para o sucesso. - Jan Vlcinsky


Use a configuração do host personalizado em ~/.ssh/config, como isso:

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

então use seu nome de host personalizado como este:

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

6



Essa é a resposta que eu estava procurando, pois tenho contas separadas do GitHub para casa e trabalho. Eu só tive que definir Host work.github.com  HostName github.com  IdentityFile ~/.ssh/worke substitua "github.com" por "work.github.com" sempre que eu clonar um repositório de trabalho. Ele ainda se conecta ao "github.com", mas usando um par de chaves não padrão. - Mikkel
O URL para detalhes ("itblog.study.land / ... ") não funciona mais :( - Carl Smotricz


Você pode simplesmente usar ssh-ident em vez de criar seu próprio wrapper.

Você pode ler mais em:    https://github.com/ccontavalli/ssh-ident

Ele carrega chaves ssh sob demanda quando necessário, uma vez, mesmo com várias sessões de login, xterms ou residências compartilhadas NFS.

Com um pequeno arquivo de configuração, ele pode carregar automaticamente diferentes chaves e mantê-las separadas em agentes diferentes (para o encaminhamento de agentes), dependendo do que você precisa fazer.


5





Eu tinha um cliente que precisava de uma conta separada do github. Então, eu precisava usar uma chave separada apenas para este projeto.

Minha solução foi adicionar isso ao meu .zshrc / .bashrc:

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

Sempre que eu quiser usar o git para esse projeto eu substituo "infogit" pelo git:

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

Para mim, é mais fácil de lembrar.


3





Minha solução foi esta:

crie um 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

então quando você tiver que mudar a execução do var:

. ./thescript.sh [--port=] [--key=]

Não se esqueça do ponto extra !! isso faz com que o script defina os ambientes vars !! --key e --port são opcionais.


2





Geralmente, você quer usar ~/.ssh/config por esta. Basta emparelhar os endereços do servidor com as chaves que você deseja usar para eles da seguinte maneira:

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

Host * denota qualquer servidor, então eu usá-lo para definir ~/.ssh/id_rsa como a chave padrão a ser usada.


1