arquivos scp via host intermediário

83

Eu tenho acesso a três máquinas, A, B e C. As únicas conexões possíveis (ssh) são:

A -> B
B <-> C

Eu preciso obter arquivos de A a C, para que eu possa scp os arquivos de A para B e depois de B para C. No entanto, B não tem muito espaço em disco, portanto, essa não é uma opção. Existe uma maneira de scp arquivos de A a C via B? Observe que não tenho acesso root em nenhuma das máquinas; portanto, não pense em configurar túneis persistentes, mas corrija-me se estiver errado!

astrofrog
fonte
6
Sei que isso não responde à pergunta, mas para quem não conhece o rsync ou não sabe como usá-lo para percorrer um host, essa pode ser uma dica útil: use a opção '-e' com rsync assim:A$ rsync <options> -e 'ssh B ssh' source C:destination
Eddified

Respostas:

105

ProxyJump

Novo no OpenSSH 7.3:

A$ scp -oProxyJump=B thefile C:destination

(Nos bastidores, isso usa apenas ProxyCommand e ssh -W.)

ProxyCommand

Atualizado para incluir -W de outras respostas:

A$ scp -oProxyCommand="ssh -W %h:%p B" thefile C:destination

Se A tiver um cliente SSH muito antigo instalado (sem -Wsuporte) ou se B estiver configurado para desabilitar o encaminhamento de TCP (mas ainda permitir comandos de shell), use alternativas:

A$ scp -oProxyCommand="ssh B socat stdio tcp:%h:%p" thefile C:destination
A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination

Tubos

A$ tar cf - thefile anotherfile | ssh B "ssh C \"cd destination && tar xvf -\""
A$ (echo thefile; echo anotherfile) | cpio -o | ssh B "ssh C \"cd destination && cpio -i\""

Para apenas um arquivo:

A$ ssh B "ssh C \"cd destination && cat > thefile\"" < thefile

"Túnel" através de B

A$ ssh -f -N -L 4567:C:22 B
(continues running in background)

A$ scp -P 4567 thefile localhost:destinationPath

Quando terminar, não esqueça de eliminar o sshprocesso iniciado anteriormente (que caiu em segundo plano devido a -f -N).

  • -fSolicita que o ssh volte para o plano de fundo imediatamente antes da execução do comando. Isso é útil se o ssh solicitar senhas ou frases secretas, mas o usuário desejar em segundo plano. Isso implica -n.
  • -NNão execute um comando remoto. Isso é útil apenas para encaminhamento de portas.

Inverta o "túnel" através de B para A

Nem sempre funciona:

A$ ssh -f -N -R 4567:localhost:22 B
(now you can reach A from B, by using localhost:4567)

B$ scp -P 4567 localhost:thefile C:destination
  • -R Especifica que as conexões com a porta TCP ou o soquete Unix fornecido no host remoto (servidor) devem ser encaminhadas para o host e a porta fornecidos, ou soquete Unix, no lado local.
gravidade
fonte
Muito obrigado por esses exemplos @grawity. Uma pergunta - é possível inverter `tar c thefile anotherfile | ssh B "ssh C \" destino cd && tar xv \ "" "para copiar o download de C para A (estar em A)
DMEU
@dmeu: Sim, é possível.
grawity
Como "matar" o processo ssh iniciado anteriormente, se diz que estou usando um MacOS?
Aero Windwalker
Nota: Como de costume, se você quiser scp de C, embora B, a A, poderá fazê-lo A$ scp -oProxyJump=B C:destination thefile.
Jvriesem
@ Pablo Melhor usar -S, então, e -O sair. Ou ... pelo menos pkill -f.
grawity
24

As versões do scp do início de 2011 e posteriores podem ter uma opção "-3":

 -3      Copies between two remote hosts are transferred through the local
         host.  Without this option the data is copied directly between
         the two remote hosts.  Note that this option disables the
         progress meter.

Se você tiver isso, basta executar:

B$ scp -3 A:file C:file
Dan Bloch
fonte
No meu caso, o host A só era acessível a partir de B (que estava VPN). O host C estava na mesma LAN que B. Eu queria obter um arquivo de A a C e o scp -3 o resolveu de maneira brilhante.
Joe
Eu tive problemas com isso quando os dois hosts solicitaram uma senha. Parece pedir os dois ao mesmo tempo (duas solicitações de senha apareceram na mesma linha) e, em seguida, não aceitou minha senha. Eventualmente, eu consegui fazê-lo digitar minha senha repetidamente (a mesma senha nos dois hosts), mas era difícil descobrir.
Colin D
8

Quase tudo já foi dito, mas aqui está o meu último centavo: eu uso a variante ProxyCommand sem ncnem soc. Baseado no OpenSSH Proxies e no Jumphost Cookbook, criei uma seguinte configuração:

  1. Portanto, temos os seguintes jogadores:

    • HOME_HOST: é de onde copiamos um arquivo para o host de destino
    • HOP_HOST: copiamos através deste host (registrado como HOP_USER)
    • TARGET_HOST: é o nosso destino (autenticado como TARGET_USER)
  2. Primeiro, adicionei minha chave pública local do meu host doméstico .ssh/id_dsa.pub aos hosts de .ssh/authorized_keyssalto e de destino. Sim, a mesma chave pública do host doméstico para os dois. Normalmente, você espera que seja a chave pública HOP que você deve adicionar à chave TARGET.

  3. Depois, aprimorei .ssh/configum pouco adicionando a seguinte entrada:

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. Depois que a operação de cópia é tão simples como: scp FILE TARGET_HOST:. Ele exibe banners duplos dos nós de salto e de destino, mas funciona.

Claro que você pode usar acima de ssh diretamente para o alvo: ssh TARGET_HOST. Funciona com scp e ssh.

Outra opção mais geral pode ser o utilitário sshuttle , que parece ser um tipo de proxy transparente (vpn sobre ssh). Portanto, no seu caso de A-> B <-> C, ele permite conectar-se a cada nó na rede de C: A-> B- [CDEFG]. Ele não precisa de administrador, mas requer Python 2.7 (3.5 também OK), o que nem sempre é o que temos. Vale a pena tentar.

SQ9MCP
fonte
7
ssh -L 4321:hostC:22 youruser@hostB

em outra concha:

scp -P 4321 localfile [email protected]

Isso está usando o encaminhamento de porta. A única limitação aqui é que o host B precisa ser configurado para permitir o encaminhamento de porta. Caso contrário, isso deve funcionar bem.

Na forma de explicação, -Le -Rpermitem encaminhar portas. Em -L, a primeira porta fornecida é a porta ssh começará a escutar na máquina de origem (host A) e encaminhará tudo o que receber nessa porta pela sua conexão SSH para o host B e, em seguida, encaminhará para o host C na porta 22.

editar

Eu estraguei a sintaxe um pouco. Ele configura um encaminhamento em sua máquina LOCAL.

Brian Vandenberg
fonte
@astrofrog - se uma de nossas respostas atender às suas necessidades, você provavelmente deve aceitar uma delas.
Brian Vandenberg
2

A resposta do ProxyCommand da Grawity funcionou para mim, mas como eu estou menos familiarizado com o SSH, foi preciso experimentar. Eu pensei que apenas explicaria a resposta de Grawity com mais detalhes para ajudar outros novatos no SSH como eu. Aqui estão as definições para uma notação mais explícita:

Máquina A: a máquina em que você está

Servidor B: [email protected] (o host de salto ou o servidor intermediário)

Servidor C: [email protected] (o servidor remoto para o qual você deseja copiar)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" thefile [email protected]:destination

Exemplo concreto

Portanto, para um exemplo concreto, digamos que você tenha acesso a um servidor com IP 0.0.1.2com uma conta de usuário chamada bar(Servidor C). Mas, para isso, você deve primeiro fazer login em um servidor com IP 0.0.1.1com a conta de usuário chamada foo(Servidor B). Agora você deseja copiar o arquivo baz.txtlocalizado na sua máquina atual (Máquina A) para 0.0.1.2o /home/bar/diretório do servidor . Para usar o ProxyCommand acima para este exemplo, você deve executar o seguinte:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" baz.txt [email protected]:/home/bar/

Você também pode copiar com facilidade o arquivo do Servidor C, alternando a ordem e o destino do arquivo. Assim, por exemplo, se baz.txtjá estava no servidor 0.0.1.2localizado na /home/bar/, então você pode copiá-lo para a sua máquina usando:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" [email protected]:/home/bar/baz.txt /destination/path/on/A

Espero que isso ajude as pessoas que precisam de coisas explicadas um pouco mais do que outras.

Joseph Carmack
fonte