Especifique a chave SSH privada para usar ao executar o comando shell?

Uma situação bastante incomum, talvez, mas eu quero especificar uma chave SSH privada para usar ao executar um comando shell (git) a partir do computador local.

Basicamente assim:

git clone git@github.com:TheUser/TheProject.git -key "/home/christoffer/ssh_keys/theuser" 

Ou melhor ainda (em Ruby):

 with_key("/home/christoffer/ssh_keys/theuser") do sh("git clone git@github.com:TheUser/TheProject.git") end 

Eu vi exemplos de conexão a um servidor remoto com Net :: SSH que usa uma chave privada especificada, mas este é um comando local. É possível?

Algo como isso deve funcionar (sugerido por orip):

 ssh-agent bash -c 'ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git' 

Se você preferir subshells, você pode tentar o seguinte (embora seja mais frágil):

 ssh-agent $(ssh-add /somewhere/yourkey; git clone git@github.com:user/project.git) 

O Git invocará o SSH que encontrará seu agente pela variável de ambiente; isso, por sua vez, terá a chave carregada.

Como alternativa, a configuração HOME também pode funcionar, desde que você esteja disposto a configurar um diretório que contenha apenas um diretório .ssh como HOME ; isso pode conter um identity.pub ou um arquivo de configuração definindo IdentityFile.

Nenhuma dessas soluções funcionou para mim.

Em vez disso, eu elaborei sobre a menção do @Martin v. Löwis de configurar um arquivo de config para o SSH.

O SSH procurará pelo arquivo ~/.ssh/config do usuário. Eu tenho minha configuração como:

 Host gitserv Hostname remote.server.com IdentityFile ~/.ssh/id_rsa.github IdentitiesOnly yes # see NOTES below 

E eu adiciono um repository git remoto:

 git remote add origin git@gitserv:myrepo.git 

E então os comandos do git funcionam normalmente para mim.

 git push -v origin master 

NOTAS

  • O IdentitiesOnly yes é necessário para impedir o comportamento padrão do SSH de enviar o arquivo de identidade correspondente ao nome de arquivo padrão para cada protocolo. Se você tem um arquivo chamado ~/.ssh/id_rsa que será tentado ANTES de seu ~/.ssh/id_rsa.github sem esta opção.

Referências

  • Melhor maneira de usar várias chaves privadas SSH em um cliente
  • Como eu poderia parar o ssh oferecendo uma chave errada?

As sugestões de outras pessoas sobre o ~/.ssh/config são extremamente complicadas. Pode ser tão simples como:

 Host github.com IdentityFile ~/.ssh/github_rsa 

A partir do Git 2.3.0 também temos o comando simples (não é necessário nenhum arquivo de configuração):

 GIT_SSH_COMMAND='ssh -i private_key_file' git clone user@host:repo.git 

Conteúdo de my_git_ssh_wrapper:

 #!/bin/bash ssh -i /path/to/ssh/secret/key $1 $2 

Então você pode usar a chave fazendo:

 GIT_SSH=my_git_ssh_wrapper git clone git@github.com:TheUser/TheProject.git 

Para resumir as respostas e comentários , a melhor maneira de configurar o git para usar diferentes arquivos de chave e depois esquecê-lo, que também suporta diferentes usuários para o mesmo host (por exemplo, uma conta pessoal do GitHub e uma de trabalho), que funciona no Windows também, é editar ~/.ssh/config (ou c:\Users\\.ssh\config ) e especificar múltiplas identidades:

 Host github.com HostName github.com IdentityFile /path/to/your/personal/github/private/key User dandv Host github-work HostName github.com IdentityFile /path/to/your/work/github/private/key User workuser 

Então, para clonar um projeto como seu usuário pessoal, basta executar o comando regular git clone .

Para clonar o workuser como o workuser , execute git clone git@github-work:company/project.git .

Com git 2.10+ (T3 2016: lançado em 2 de setembro de 2016), você tem a possibilidade de definir uma configuração para GIT_SSH_COMMAND (e não apenas uma variável de ambiente como descrito na resposta de Rober Jack Will )

Veja commit 3c8ede3 (26 Jun 2016) de Nguyễn Thái Ngọc Duy ( pclouds ) .
(Mesclado por Junio ​​C Hamano – gitster – em commit dc21164 , 19 de julho de 2016)

Uma nova variável de configuração core.sshCommand foi incluída para especificar qual valor para GIT_SSH_COMMAND usar por repository.

 core.sshCommand: 

Se esta variável for configurada, git fetch e git push usarão o comando especificado em vez de ssh quando precisarem se conectar a um sistema remoto.
O comando está na mesma forma que a variável de ambiente GIT_SSH_COMMAND e é sobrescrito quando a variável de ambiente é configurada.

Isso significa que o git clone pode ser:

 cd /path/to/my/repo git config core.sshCommand 'ssh -i private_key_file' # later on git clone host:repo.git 

Como afirmado aqui: https://superuser.com/a/912281/607049

Você pode configurá-lo por repo:

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

Melhor maneira de adicionar esse host ou ip ao .ssh/config forma:

 Host (a space separated list of made up aliases you want to use for the host) User git Hostname (ip or hostname of git server) PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa_(the key you want for this repo) 

Eu fui com a variável de ambiente GIT_SSH. Aqui está o meu wrapper, semelhante ao de Joe Block acima, mas lida com qualquer quantidade de argumentos.

Arquivo ~ / gitwrap.sh

 #!/bin/bash ssh -i ~/.ssh/gitkey_rsa "$@" 

Então, no meu .bashrc, adicione o seguinte:

 export GIT_SSH=~/gitwrap.sh 

Quando você precisa se conectar ao github com um pedido normal ( git pull origin master ), definindo o Host como * em ~/.ssh/config funcionou para mim, qualquer outro Host (digamos, “github” ou “gb”) não foi t trabalhando.

 Host * User git Hostname github.com PreferredAuthentications publickey IdentityFile ~/.ssh/id_rsa_xxx 

Muitas dessas soluções pareciam atraentes. No entanto, achei a abordagem genérica de quebra de script de rastreamento no link a seguir como a mais útil:

Como especificar um arquivo de chave ssh com o comando git

O ponto é que não existe um comando git como o seguinte:

 git -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git 

A solução de Alvin é usar um script de wrapper bem definido que preenche essa lacuna:

 git.sh -i ~/.ssh/thatuserkey.pem clone thatuser@myserver.com:/git/repo.git 

Onde git.sh é:

 #!/bin/bash # The MIT License (MIT) # Copyright (c) 2013 Alvin Abad # https://alvinabad.wordpress.com/2013/03/23/how-to-specify-an-ssh-key-file-with-the-git-command if [ $# -eq 0 ]; then echo "Git wrapper script that can specify an ssh-key file Usage: git.sh -i ssh-key-file git-command " exit 1 fi # remove temporary file on exit trap 'rm -f /tmp/.git_ssh.$$' 0 if [ "$1" = "-i" ]; then SSH_KEY=$2; shift; shift echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$ chmod +x /tmp/.git_ssh.$$ export GIT_SSH=/tmp/.git_ssh.$$ fi # in case the git command is repeated [ "$1" = "git" ] && shift # Run the git command git "$@" 

Posso verificar que isso resolveu um problema que eu estava tendo com o reconhecimento de chave / usuário para um repository bitbucket remoto com git remote update , git pull e git clone ; todos os quais agora funcionam bem em um script de tarefa cron que estava, de outra forma, tendo problemas para navegar pelo shell limitado. Eu também era capaz de chamar esse script de dentro de R e ainda resolver exatamente o mesmo problema de execução do cron (por exemplo, system("bash git.sh -i ~/.ssh/thatuserkey.pem pull") ).

Não que R seja o mesmo que Ruby, mas se R puder fazer isso … O 🙂

Você poderia usar a variável de ambiente GIT_SSH. Mas você precisará colocar o ssh e as opções em um script de shell.

Veja git manual: man git no seu shell de comando.

O truque para mim foi usar git @ hostname em vez de http: // hostname

No Windows com o Git Bash, você pode usar o seguinte para adicionar um repository ssh-agent bash -c 'ssh-add "key-address"; git remote add origin "rep-address"' ssh-agent bash -c 'ssh-add "key-address"; git remote add origin "rep-address"' por exemplo: ssh-agent bash -c 'ssh-add /d/test/PrivateKey.ppk; git remote add origin git@git.test.com:test/test.git' ssh-agent bash -c 'ssh-add /d/test/PrivateKey.ppk; git remote add origin git@git.test.com:test/test.git' Qual chave privada está na unidade D, teste de pasta do computador. Além disso, se você quiser clonar um repository, você pode alterar git remote add origin git clone com o git clone .

Depois de entrar no Git Bash, ele pedirá a senha!

Esteja ciente de que a chave privada openssh e chave privada putty são diferentes!

Se você criou suas chaves com puttygen, você deve converter sua chave privada para openssh!

Eu uso o zsh e chaves diferentes são carregadas para o ssh-agent do meu shell zsh automaticamente para outros propósitos (por exemplo, access a servidores remotos) no meu laptop. Eu modifiquei a resposta do @ Nick e estou usando para um dos meus repositorys que precisam ser atualizados com frequência. (Neste caso são meus dotfiles que eu quero a versão igual e mais recente em todas as minhas máquinas, onde quer que eu esteja trabalhando.)

 bash -c 'eval `ssh-agent`; ssh-add /home/myname/.dotfiles/gitread; ssh-add -L; cd /home/myname/.dotfiles && git pull; kill $SSH_AGENT_PID' 
  • Gerar um agente ssh
  • Adicionar chave somente leitura ao agente
  • Alterar o diretório para o meu repository git
  • Se cd para repo dir for bem sucedido, puxe de repo remoto
  • Matar spawned ssh-agent. (Eu não gostaria que muitos agentes permanecessem por perto.)

para o RSAAuthentication do RSAAuthentication yes

 Host gitlab.com RSAAuthentication yes IdentityFile ~/.ssh/your_private_key_name IdentitiesOnly yes 

doc está aqui

Se o número da porta SSH não for 22 (padrão), adicione a Port xx em ~/.ssh/config

No meu caso (synology),

 Host my_synology Hostname xxxx.synology.me IdentityFile ~/.ssh/id_rsa_xxxx User myname Port xx 

Em seguida, clone usando o título do host na configuração. (“my_synology”. para evitar o “*” de @chopstik)

 git clone my_synology:path/to/repo.git