SSH de A a B a C, usando chave privada em B

59

Estou procurando uma maneira simples de SSH da minha máquina local, A, através de um proxy B, para um host de destino C. A chave privada que acompanha a chave pública em C está em B e não posso coloque essa chave na minha máquina local. Alguma dica?

Além disso, eu gostaria de poder fazer isso usando ~ / .ssh / config.

Obrigado!

wrangler
fonte
1
Você está dizendo que deseja ssh de A para B e depois SSH para C? Ou o proxy é uma verdadeira situação pass-thru?
thinice
Eu quero ssh de A a C, passando por B. Minha resposta abaixo funciona para a parte de passagem, mas ele ainda tenta procurar o IdentityFile no meu computador local em vez de no B, o host de passagem.
Wrangler

Respostas:

74

Esquema:

    ssh       ssh
A ------> B ------> C
    ^          ^
 using A's   using B's
 ssh key     ssh key

Condições prévias:

  • A está executando o ssh-agent;
  • Apode acessar B;
  • Bpode acessar C;
  • AA chave pública ssh está presente em B:~/.ssh/authorized_keys
  • BA chave pública ssh está presente em C:~/.ssh/authorized_keys

Na ~/.ssh/configon A, adicione

Host C
    ProxyCommand ssh -o 'ForwardAgent yes' B 'ssh-add && nc %h %p'

Se sua chave privada ssh em B estiver em um local não padrão, adicione seu caminho depois ssh-add.

Agora você deve ser capaz de acessar Ca partir de A:

A$ ssh C
C$
Bola de neve
fonte
13
Demorou apenas 4 anos, mas parece que temos uma resposta! Impressionante
wrangler
3
Começando com o openssh v.7.3, você pode apenas usar ProxyJump B. fonte: wikibooks
Keith
2
Esta pode ser definida de tal forma que: Anfitrião user1 @ c ProxyCommand ssh -o 'ForwardAgent sim' user2 @ B 'ssh-adicione && nc% h% p'
Ravindranath Akila
2
Como a solução mudaria se a máquina B não tivesse nc?
Mjalajel 18/03
1
@DrewVS Ok, é preciso adicionar ForwardAgent yes antes do ProxyJumpcomando.
Graipher
22

Verifique se o seguinte está funcionando.

ssh -t B ssh C

Use o comando a seguir se desejar usar a chave armazenada em B.

ssh -t B ssh -i /path/to/identity_on_B C

Aqui estamos especificando o comando, ou seja, ssh -i /path/to/identity_on_B Cpara ser executado em B em vez de um shell de login.

Sachin Divekar
fonte
Isso funciona, mas ele não pegar o IdentityFile de B. Ele ainda olha para A.
Wrangler
@DrewVS Atualizei a resposta. Por favor, verifique se está funcionando para você.
Sachin Divekar
Sachin, muito esperto. Isso funcionou perfeitamente. Muito obrigado!
Wrangler
@DrewVS feliz em saber que funcionou para você. então aceite a resposta.
Sachin Divekar
No entanto, parece que isso não funciona com chaves rsa protegidas por senha. A entrada da senha está oculta, forçando o usuário a adicionar a chave à sua chave ssh para que essa abordagem funcione. Alguma ideia?
Wrangler
10

Eu já resolvi isso agora. Aqui está a solução, que é bastante direta. Eu deveria ter visto isso antes:

~ / .ssh / config:

Host B
  HostName 1.2.3.4
  User myuser
  IdentityFile ~/.ssh/rsa_key
  ControlMaster auto
  ControlPath ~/.ssh/socket/master-%l-%r@%h:%p

Host C.*
  User customer_username
  Port customer_port
  IdentityFile remote/path/to/ssh/key
  ForwardAgent yes
  ProxyCommand ssh accessable.server nc %h %p

Host C.server-1
  HostName 2.3.4.5

'B' é o servidor Proxy que você está acessando. Ele deve ser configurado como você normalmente configuraria o acesso a um servidor.

'C' é o host de destino. Ele precisa ser configurado para usar 'B' no processo de conexão. O arquivo de identidade em 'C' é o caminho para a chave ssh em 'B'. O ProxyCommand usa o Netcat para abrir a conexão com 'C' a partir de 'B'. O Netcat, ou nc, precisará ser instalado no 'B'.

Espero que isso ajude os outros.

wrangler
fonte
3
Eu falei cedo demais. Esta solução não parece funcionar. A chave havia sido carregada no agente ssh, então pensei que estava funcionando. No exemplo acima, a chave para C necessita ainda de estar em A, não B
wrangler
2

Escrevi um script simples para listar basicamente minhas chaves ssh na instância remota e depois adicionar a que selecionei ao meu agente ssh local. Isso não é muito limpo, mas me permite manter todas as chaves em um local remoto e não localmente.

Aqui está o script, se alguém estiver interessado:

#!/usr/bin/ruby

require "rubygems"
require "fileutils"

# Get key list
key_list = (`ssh jumpbox "cd ~/.ssh/ ; ls id_rsa*" | sed 's/id_rsa_/  /g' | sed     's/id_rsa//g'`)
puts ' '
puts 'Available customer keys:'
puts key_list

# Get customer name input
puts ' '
puts 'Enter customer name: '
customer_name = gets.chomp

# Add key to ssh-agent
key_name = "~/.ssh/id_rsa_#{customer_name}"
puts ' '
puts "Adding #{key_name} to local ssh-agent"
`ssh jumpbox "ssh-add ~/.ssh/id_rsa_#{customer_name}"`
exit 0
wrangler
fonte
Eu acho que a adição de uma chave pode ser tratada como idempotente, eliminando assim a necessidade de obter a lista de chaves.
dmourati
Você deve aceitar serverfault.com/a/701884/127993, que faz exatamente o que você deseja.
sjas
1
#!/usr/bin/env bash
target_host=10.121.77.16
target_port=22
target_user=vagrant

bastion_user=yourusername
bastion_host=10.23.85.245
bastion_port=32780

scp -P $target_port -o ProxyCommand="ssh -o 'ForwardAgent yes' $bastion_user@$bastion_host -p $bastion_port 'ssh-add ~/.ssh/*.rsa && nc %h %p'" /tmp/x.txt $target_user@$target_host:/tmp/
wcc526
fonte
1

Façam:

ssh someuser@IP_D

de tal modo que

A -> B-> C -> D onde A é o host em que você está,

edite seu ~ / .ssh / config local da seguinte maneira:

Host IP_D
  ProxyCommand ssh -o 'ForwardAgent yes' userX@IP_C 'ssh-add && nc %h %p'
Host IP_C
  ProxyCommand ssh -o 'ForwardAgent yes' userY@IP_B 'ssh-add && nc %h %p'

Esta resposta é baseada na resposta escolhida. Eu tive que descobrir como vários usuários se encaixam em todo o cenário.

Isso funciona para mim. HTH.

Ravindranath Akila
fonte
0

A resposta de Snowball ajudou muito. No entanto, fiz algumas modificações no comando e quis explicar como ele funciona. Dada esta situação:

    ssh        ssh
A -------> B -------> C
     ^          ^
  using A's  using B's
  ssh key    ssh key

Modifique seu ~/.ssh/configarquivo e adicione o host Bpelo qual deseja pular, exatamente como você configuraria normalmente um host:

Host B
 User myusername
 HostName b.mycompany.com

Em seguida, você adiciona o host no Cqual deseja terminar:

Host C
 User myusername
 HostName c.intranet.mycompany.com
 ProxyCommand ssh -T -q -o 'ForwardAgent yes' B 'ssh-add -t 1 && nc %h %p'

Observe o ProxyCommand, onde:

  • ssh -T -qindica que não deve alocar um pseudo-TTY ( -T) e ficar quieto ( -q);
  • uma vez no host de salto B, adicionamos a chave às chaves SSH de Athrough ssh-add;
  • o que só funciona porque encaminhamos o agente SSH usando -o 'ForwardAgent yes'.
  • ssh-add -t 1 indica que eu quero que a chave seja adicionada apenas por 1 segundo necessário para autenticar no host final C;
  • e, finalmente, nc %h %pinicia uma netcatconexão com o host final %hna porta %p(ambos os quais serão preenchidos pelo SSH com base nas informações no ~/.ssh/configarquivo).

Se você precisar especificar uma chave personalizada Bpara usar, poderá fazer isso modificando a ssh-addpeça:

Host C
 User myusername
 HostName c.intranet.mycompany.com
 ProxyCommand ssh -T -q -o 'ForwardAgent yes' B 'ssh-add -t 1 ~/.ssh/mykey && nc %h %p'
Daniel AA Pelsmaeker
fonte