Encaminhar tráfego SSH através de uma máquina do meio

110

O tunelamento SSH é muito confuso para mim. Gostaria de saber se posso fazer isso no Linux.

Eu tenho 3 maquinas ..

A. My local machine at home.
B. Machine at work that I can SSH into (middle man).
C. My desktop at work that I can only SSH into from machine B.

Então eu posso SSH de A -> B e de B -> C, mas não de A -> C.

Existe uma maneira de configurar um túnel SSH de A a B; portanto, quando executo outros comandos SSH, eles simplesmente funcionam na minha máquina local A? Basicamente, estou tentando clonar um repositório git do trabalho para casa (e não consigo instalar o git na máquina B).

Além disso, uma vez configurado. Como eu também o desmarcaria?


fonte
Eu acredito que há uma pergunta duplicada em algum lugar, mas minha busca-fu está fraca hoje.
quack quixote
2
Possível duplicata de um túnel SSH através de múltiplos saltos
Geza Kerecsenyi
Se você estiver executando o Linux na máquina A, use uma ferramenta chamada sshuttle, que permite encaminhar seletivamente todo o tráfego para C através do túnel A-> B (supondo que C seja visível em B).
joat 16/01

Respostas:

128

Coloque isso em seu .ssh/configarquivo no hostA (consulte man 5 ssh_config para obter detalhes):

# .ssh/config on hostA:
Host hostC
    ProxyCommand ssh hostB -W %h:%p

Agora, o comando a seguir fará o túnel automaticamente através do hostB

hostA:~$ ssh hostC

Você pode adicionar opções como -oCiphers=arcfoure -oClearAllForwardings=yesacelerar as coisas, pois o empacotamento sshinterno sshé computacionalmente mais caro e o esforço extra e o invólucro não precisam ser tão seguros quando está encapsulando o tráfego já criptografado.


Se você estiver usando o OpenSSH anterior à 5.3, a -Wopção não estará disponível. Nesse caso, você pode implementar o acima usando netcat ( nc):

ProxyCommand ssh hostB nc %h %p  # or netcat or whatever you have on hostB
efémero
fonte
1
Isto é brilhante! Obrigado. Isso resolve um problema que tem me consumido nos últimos 2 dias: o hostC fica atrás de um firewall e possui dados que eu quero acessar do hostA, um laptop que pode estar em qualquer lugar do mundo. O hostB também está atrás do mesmo firewall do hostC, mas possui uma porta SSH aberta para o mundo. Assim, eu posso ssh de hostC -> hostB. Eu configurei um túnel SSH reverso entre hostC e hostB, para que eu também possa ssh de hostB -> hostC (encaminhado através do host local). Com o seu truque, posso ir de hostA -> hostC! Funciona perfeitamente com SCP & Fugu no OSX! Obrigado!
andyl
A -Wopção deve ser usada em vez da ncopção.
vy32
Qual SSH deve suportar -W, apenas o hostA (a origem) ou também o hostB (a máquina do meio)?
Gioele 5/05
Para informações, se você tiver vários hosts que precisa acessar através do mesmo hostB, é possível declarar várias Host hostClinhas acima ProxyCommand, facilitando o acesso a vários hosts através do servidor intermediário.
Fduff 19/05
7

Edit: Esta é a abordagem errada. Veja a resposta do ephemiente . Essa resposta funcionará, mas é potencialmente menos segura e definitivamente menos impressionante.

Parece que você deseja uma solução como a seguinte:

ssh -L localhost:22:machinec:22 machineb

Isso lhe dará uma concha machineb. Deixe isso em paz; minimizar a janela do terminal.

Agora, sempre que você fizer uma conexão ssh localhost, você estará realmente conectado machinecatravés machineb. Quando terminar o túnel, feche o terminal no qual você executou o comando acima.

Observe que você precisará de privilégios de superusuário para executar o comando.

Wesley
fonte
+1 Obrigado Wesley. Esta é a verdadeira resposta do tunelamento ssh. Aqui está um artigo sobre o assunto: securityfocus.com/infocus/1816
Larry K
3
No geral, isso é muito ruim ... mas eu tive que fazer isso com versões antigas do OpenSSH ou outros clientes ssh. Você pode escolher uma porta alta como 8022: dessa forma, não interfere com nenhum serviço ssh no localhost e não requer a execução como root. Basta adicionar -p 8022aos seus comandos ssh. E é fácil de entender com o git: use o URI ssh://localhost:8022/path/to/repo.git.
ephemient
3

Parece que você quer um apelido de shell em A que faz com que o ssh ocorra em C

  1. Suponho que em A, você pode digitar ssh me @ b "ssh me @ c hostname" e voltar "C"
  2. Faça um pseudônimo sshc que expanda sshc foo em ssh me @ b "ssh me @ c foo"
  3. Para obter a sintaxe exata da criação do alias, consulte superuser.com
Larry K
fonte
1
Pode ser necessário adicionar -tàs opções externas do ssh se você deseja um shell interativo, pois sshassume -Tse ele recebe um comando.
ephemient
1

Para shell interativo, você pode usar este comando simples:

ssh -J <user>@<hostB> <user>@<hostC>

As opções -J são para pular .

ssasa
fonte
0

Se o seu empregador fornece uma VPN, eu recomendo usá-la.

Dessa forma, você não precisará configurar nenhum aplicativo especialmente (mesmo o ssh) e poderá ver qualquer máquina atrás do firewall. Além disso, todo o seu tráfego será criptografado pelo software VPN, que adicionará segurança a qualquer tráfego não criptografado inadvertidamente ou deliberadamente.

Andrew Wagner
fonte
6
Às vezes é o VPN que é a razão pela qual precisamos esses truques ...
Louis
0

YASS Mais uma Solução Simples

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost
  • Primeiro comando, abra uma conexão ssh com o HostB e diga ao HostB para encaminhar as conexões do localhost: 2222 para o HostC: 22 .
  • o -fparâmetro diz ao SSH para entrar em segundo plano depois que a conexão é estabelecida
  • Segundo comando, basta abrir uma conexão do cliente com o host local: 2222
  • A opção HostKeyAlias não é necessária, mas pode ajudar a impedir a conexão com o host errado
  • Nota: o comando sleep 10é necessário para manter a conexão até o segundo comando ssh usar a porta encaminhada. Então o primeiro ssh será fechado quando o segundo ssh deixar a porta encaminhada.

agora você pode executar sessões ssh subseqüentes:

ssh -o HostKeyAlias=HostC -p 2222 userOnC@localhost

Variante:

ssh -f -L 2222:HostC_IP_or_Name:22 userOnB@hostB sleep 10 &&
    ssh -M -S ~/.ssh/ssh_HostC22userOnC.sock -o HostKeyAlias=HostC -p 2222 userOnC@localhost

as sessões ssh subsequentes podem ser abertas executando:

ssh -S ~/.ssh/ssh_HostC22userOnC.sock userOnC@localhost

A principal vantagem do uso de -M e -S param é que apenas uma conexão é aberta do HostA para o HostC, a sessão subsequente não será autenticada novamente e executada muito mais rapidamente.

F. Hauri
fonte
0

Caso especial, plataformas nix mistas:

  hostA (linux) -> HostB (solaris) -> HostC (linux)

Se precisar de um aplicativo X no hostC e o salto intermediário estiver na caixa Solaris ... nesse caso, encontrei o netcat (nc) necessário no ProxyCommand da seguinte forma:

hostA: ~ $ vi .ssh / config:

Host hostC
    ProxyCommand ssh hostB nc% h% p # em que nc é netcat

O tunelamento automático funciona:

hostA: ~ $ ssh hostC

nsysdcw
fonte