2011-01-12 18:20:31 +0000 2011-01-12 18:20:31 +0000
702
702

Como dizer ao git qual a chave privada a utilizar?

ssh tem a opção -i para dizer qual o ficheiro da chave privada a utilizar ao autenticar:

-i identity_file

Selecciona um ficheiro a partir do qual é lida a identidade (chave privada) para autenticação RSA ou DSA.  O ficheiro por defeito é ~/.ssh/identity para a versão de protocolo 1, e ~/.ssh/id_rsa e ~/.ssh/id_dsa para a versão de protocolo 2. Os ficheiros de identidade também podem ser especificados por anfitrião no ficheiro de configuração.  É possível ter múltiplas opções -i (e múltiplas identidades especificadas nos ficheiros de configuração).

Existe uma forma semelhante de indicar ao git qual o ficheiro de chave privada a utilizar num sistema com múltiplas chaves privadas no directório ~/.ssh?

Respostas (19)

720
720
720
2011-01-12 19:36:21 +0000

Em ~/.ssh/config, adicione:

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

Se o arquivo de configuração for novo, não se esqueça de fazer chmod 600 ~/.ssh/config

Agora você pode fazer git clone git@github.com:{ORG_NAME}/{REPO_NAME}.git

  • Onde {ORG_NAME} é o nome GitHub URI da sua conta de usuário (ou conta da organização).
  • Note que existe um : dois pontos depois do github.com em vez da barra / - pois este não é um URI.
  • E {REPO_NAME} é o nome URI do seu repo GitHub
  • Por exemplo, para o kernel Linux isto seria git clone git@github.com:torvalds/linux.git).

NOTA: Em Linux e macOS, verifique que as permissões no seu IdentityFile são 400. O SSH irá rejeitar, de uma forma não claramente explícita, chaves SSH que sejam demasiado legíveis. Irá parecer apenas uma rejeição de credenciais. A solução, neste caso, é:

chmod 400 ~/.ssh/id_rsa_github
387
387
387
2015-05-08 09:43:07 +0000

Variável de ambiente GIT_SSH_COMMAND:

A partir da versão 2.3.0 de Git, pode usar a variável de ambiente GIT_SSH_COMMAND assim:

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

Note que -i pode por vezes ser substituído pelo seu ficheiro de configuração, neste caso, deve dar ao SSH um ficheiro de configuração vazio, como este:

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

Configuração core.sshCommand:

A partir da versão 2 de Git. 10.0, pode configurar isto por repo ou globalmente, para não ter de definir mais a variável de ambiente!

git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"
git pull
git push
122
122
122
2015-01-23 22:08:00 +0000

Existe não há directa forma* para dizer ao git qual a chave privada a utilizar, porque depende do ssh para a autenticação do repositório.

Opção 3:

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

Passar os argumentos ssh usando a variável de ambiente ssh-agent para especificar o binário ssh-agent alternativo.

Por exemplo:

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

Opção 3: GIT_SSH_COMMAND

Passar os argumentos ssh usando a variável de ambiente GIT_SSH_COMMAND para especificar o binário $ alternativo.

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 deve colar no seu terminal. Elas irão criar um ficheiro chamado `Existe **não há _directa forma*** para dizer ao git qual a chave privada a utilizar, porque depende do ssh para a autenticação do repositório.

Opção 3:

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

Passar os argumentos ssh usando a variável de ambiente ssh-agent para especificar o binário ssh-agent alternativo.

Por exemplo:

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

Opção 3: GIT_SSH_COMMAND

Passar os argumentos ssh usando a variável de ambiente GIT_SSH_COMMAND para especificar o binário $ alternativo.

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 deve colar no seu terminal. Elas irão criar um ficheiro chamado __, torná-lo executável e (indirectamente) executá-lo.

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

Opção 4: GIT_SSH

Use o ficheiro ssh como sugerido noutras respostas de modo a especificar a localização da sua chave privada, por exemplo:

Host github.com
  User git
  Hostname github.com
  IdentityFile ~/.ssh/id_rsa
33
33
33
2011-01-12 18:25:51 +0000

Escreva um guião que chame ssh com os argumentos que quiser, e coloque o nome do guião em $GIT_SSH. Ou apenas coloque a sua configuração em ~/.ssh/config.

22
22
22
2016-05-17 15:03:09 +0000

Utilize uma configuração de anfitrião personalizada em ~/.ssh/config, como esta:

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

e depois utilize o seu hostname personalizado como esta:

git remote add thuc git@gitlab-as-thuc:your-repo.git
22
22
22
2015-07-21 19:44:50 +0000

Se você não quer ter que especificar variáveis de ambiente toda vez que executar o git, não quer outro script de embalagem, não quer/cansa executar o ssh-agent(1), nem quer baixar outro pacote apenas para isso, use o git-remote-ext(1) transporte externo:

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

Considero esta solução superior porque:

  • É específico para repositórios/remoto
  • Evita o bloqueio do script de wrapper
  • Não precisa do agente SSH - útil se quiser clones/push/pull sem supervisão (e. g. in cron)
  • Definitivamente, não é necessária nenhuma ferramenta externa
17
17
17
2015-05-28 17:09:40 +0000

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

Através dos meus exemplos vou assumir que tem a sua chave privada localizada em/home/user/.ssh/jenkins

Erro a evitar: GIT_SSH valor inclui opções

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

ou o que quer que seja que falhe, pois git tentará executar o valor como um ficheiro. Por essa razão, terá de criar um script.

Exemplo funcional de $GIT_SSH script /home/user/gssh.sh

O script será invocado da seguinte forma:

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

A amostra de script funcional poderá parecer-se com:

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

Note o $* no final, é uma parte importante do mesmo.

Uma alternativa ainda mais segura, que evitaria qualquer possível conflito com qualquer coisa no seu ficheiro de configuração por defeito (mais mencionar explicitamente a porta a utilizar) seria:

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

Assumindo que o script está em /home/user/gssh.sh, deverá então:

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

e tudo funcionará.

7
7
7
2013-03-23 01:35:15 +0000

Pode simplesmente usar o ssh-ident em vez de criar a sua própria embalagem.

Pode ler mais em: https://github.com/ccontavalli/ssh-ident

Carrega chaves ssh a pedido quando necessário, uma vez, mesmo com várias sessões de login, xterms ou casas partilhadas NFS.

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

6
6
6
2018-03-26 19:26:38 +0000

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

A minha solução foi adicionar isto ao meu .zshrc / .bashrc:

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

Sempre que eu quiser usar git para esse projecto eu substituo “infogit” por git:

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

Para mim, é mais fácil de lembrar.

5
5
5
2018-12-04 22:21:13 +0000

Assim, defino a variável GIT_SSH env para $HOME/bin/git-ssh.

Para suportar que a minha configuração repo dite qual a identidade ssh a usar, o meu ficheiro ~/bin/git-ssh é este:

#!/bin/sh
ssh -i $(git config --get ssh.identity) -F /dev/null -p 22 $*

Depois tenho uma configuração global de configuração de git:

$ git config --global ssh.identity ~/.ssh/default_id_rsa

E dentro de qualquer repositório de git posso apenas definir um valor local de configuração de git ssh.identity:

$ git config --local ssh.identity ~/.ssh/any_other_id_rsa

Voila!

Se você pode ter um endereço de email diferente para cada identidade, fica ainda mais simples, porque você pode simplesmente nomear as suas chaves com o seu endereço de email e depois ter a drive user.email do git config a selecção de chaves num ~/bin/git-ssh como este:

#!/bin/sh
ssh -i $HOME/.ssh/$(git config --get user.email) -F /dev/null -p 22 $*
3
3
3
2018-05-03 10:17:14 +0000

Eu construo em @shellholic e este fio de SO com algumas teias. Eu uso GitHub como exemplo e assumo que você tem uma chave privada em ~/.ssh/github (caso contrário, veja esta linha SO ) e que você adicionou a chave pública ao seu perfil GitHub (caso contrário, veja ajuda de GitHub ).

Se necessário, crie um novo ficheiro de configuração SSH em ~/.ssh/config e altere as permissões para 400

touch ~/.ssh/config
chmod 600 ~/.ssh/config

Adicione isto ao ficheiro ~/.ssh/config:

Host github.com
    IdentityFile ~/.ssh/github
    IdentitiesOnly yes

Se já tem uma configuração remota, pode querer apagá-la, caso contrário pode ainda ser-lhe pedido o nome de utilizador e a palavra-passe:

git remote rm origin

Depois adicione um comando remoto ao repositório git, e repare nos dois pontos antes do nome de utilizador:

git remote add origin git@github.com:user_name/repo_name.git

E depois os comandos git funcionam normalmente, e. g.:

git push origin master
git pull origin

@HeyWatchThis on this SO thread suggested adding IdentitiesOnly yes to prevent the SSH default behavior of sending the identity file matching the default filename for each protocol. Veja essa thread para mais informações e referências.

3
3
3
2015-12-05 12:22:32 +0000

A minha solução foi esta:

criar 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 tiver de mudar a execução da var:

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

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

3
3
3
2016-02-11 22:44:57 +0000

Geralmente, você quer usar ~/.ssh/config para isso. Basta associar os endereços dos servidores com as chaves que pretende utilizar para eles da seguinte forma:

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, por isso utilizo-o para definir o ~/.ssh/id_rsa como a chave por defeito a utilizar.

2
2
2
2018-07-05 09:53:09 +0000

Basta usar os comandos ssh-agent e 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>

Depois de executar os comandos acima, pode usar ambas as teclas ao mesmo tempo. Basta digitar

git clone git@github.com:<yourname>/<your-repo>.git

para clonar o seu repositório.

Você precisa executar o comando acima depois de reiniciar a sua máquina.

1
1
1
2019-08-31 05:43:47 +0000
# start :: how-to use different ssh identity files

    # create the company identity file
    ssh-keygen -t rsa -b 4096 -C "first.last@corp.com"
    # save private key to ~/.ssh/id_rsa.corp, 
    cat ~/.ssh/id_rsa.corp.pub # copy paste this string into your corp web ui security ssh keys

    # create your private identify file
    ssh-keygen -t rsa -b 4096 -C "me@gmail.com"
    # save private key to ~/.ssh/id_rsa.me, note the public key ~/.ssh/id_rsa.me.pub
    cat ~/.ssh/id_rsa.me.pub # copy paste this one into your githubs, private keys

    # clone company internal repo as follows
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git clone git@git.in.corp.com:corp/project.git

    export git_msg="my commit msg with my corporate identity, explicitly provide author"
    git add --all ; git commit -m "$git_msg" --author "MeFirst MeLast <first.last@corp.com>"
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git push 
    # and verify 
    clear ; git log --pretty --format='%h %ae %<(15)%an ::: %s

    # clone public repo as follows
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.corp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git clone git@github.com:acoolprojectowner/coolproject.git

    export git_msg="my commit msg with my personal identity, again author "
    git add --all ; git commit -m "$git_msg" --author "MeFirst MeLast <first.last@gmail.com>"
    GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa.me -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" \
    git push ; 
    # and verify 
    clear ; git log --pretty --format='%h %ae %<(15)%an ::: %s

    # stop :: how-to use different ssh identity files
1
1
1
2019-01-07 18:26:23 +0000

Embora a pergunta não o solicite, incluí esta resposta para qualquer outra pessoa que procure resolver o mesmo problema apenas especificamente para gitlab .

A solução gitlab

Tentei utilizar a abordagem environment-variables , mas mesmo a documentação gitlab recomenda utilizar ~/.ssh/config para algo mais do que o simples caso. No meu caso estou a empurrar para um servidor gitlab - e queria fazê-lo como um utilizador específico - que é naturalmente definido pelo private-key durante a autenticação e não pelo nome de utilizador git. Uma vez implementado, simplesmente faço o seguinte:

~/myrepo> git mycommit -m "Important Stuff"
~/myrepo> git mypush
[proceed to enter passphrase for private key...]

Setup

Recall the location of your private-key /myfolder/.ssh/my_gitlab_id_rsa in my case.

Adicionar uma entrada em ~/.ssh/config:

Host gitlab-delegate
    HostName gitlab.mydomain.com
    User git
    IdentityFile /myfolder/.ssh/my_gitlab_id_rsa
    IdentitiesOnly yes

Adicionar as git-alias em ~/.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"

Como bónus, eu realizo os meus compromissos neste mesmo host como um utilizador específico com esta git-alias :

mycommit = "!f() { \
             git -c "user.name=myname" -c "user.email=myname@mysite.com" commit \"$@\"; \
           }; f"

Explicação

Todos os acima referidos assumem que o comando remoto relevante é o origin e que a filial relevante está actualmente a ser verificada. Para referência, encontrei vários itens que precisavam de ser abordados:

  • A solução requer a criação de um novo controlo remoto gitlab_as_me, e eu não gostei de ver o controlo remoto extra pendurado na minha árvore de toros por isso retiro-o quando terminado
  • Para criar o controlo remoto, existe a necessidade de gerar a url do comando na mosca - no caso do gitlab isto foi conseguido com uma simples bash cut
  • Ao executar um push to gitlab_as_me você precisa ser específico sobre que ramo você está empurrando
  • Após executar o push o seu ponteiro local origin precisa ser “atualizado” a fim de combinar gitlab_as_me (o git pull origin $branch faz isto)
1
1
1
2019-04-06 20:42:39 +0000

Quando tiver várias contas git e quiser chaves ssh diferentes

Tem de seguir o mesmo passo para gerar a chave ssh, mas certifique-se de que

ssh-keygen -t ed25519 -C "your-email-id@gmail.com"

Introduza o caminho que pretende guardar(Ex: my-pc/Desktop/. ssh/ed25519)

Adicione a chave pública ao seu gitlab Como adicionar a chave ssh ao gitlab )

Tem de criar uma nova identidade ssh usando o comando abaixo

ssh-add ~/my-pc/Desktop/.ssh/ed25519
0
0
0
2018-06-06 04:37:12 +0000

Estou a usar a versão 2.16 do git e não preciso de uma única peça de script nem mesmo de um comando de configuração ou modificação.

  • Apenas copiei a minha chave privada para .ssh/id_rsa
  • configure as permissões para 600

e o git lê para a chave automaticamente. Eu não pergunto nada e não atiro um erro. Apenas funciona bem.

0
0
0
2020-01-24 00:58:26 +0000

Se precisar de se ligar ao mesmo host com chaves diferentes, então pode consegui-lo por:

  1. Configure o ~/.ssh/config com diferentes hosts mas com o mesmo nome de host.
  2. Clonar o seu repos usando o host apropriado.

Exemplo:

~/.ssh/config

Host work
 HostName bitbucket.org
 IdentityFile ~/.ssh/id_rsa_work
 User git

Host personal
 HostName bitbucket.org
 IdentityFile ~/.ssh/id_rsa_personal
 User git

Então em vez disso clonar os seus repos como:

git clone git@bitbucket.org:username/my-work-project.git
git clone git@bitbucket.org:username/my-personal-project.git

deve fazer

git clone git@work:username/my-work-project.git
git clone git@personal:username/my-personal-project.git