2008-09-08 12 views
14

Cuando me conecto a hosts remotos a través de ssh, frecuentemente quiero traer un archivo en ese sistema al sistema local para verlo o procesarlo. ¿Hay alguna forma de copiar el archivo sin (a) abrir un nuevo terminal/pausar la sesión ssh (b) autenticando nuevamente a los hosts locales o remotos que funciona (c) incluso cuando uno o ambos hosts están detrás de un Enrutador NAT?¿Cuál es la mejor manera de llevar un archivo desde un host remoto al host local a través de una sesión SSH?

El objetivo es aprovechar la mayor parte posible del estado actual: existe una conexión entre las dos máquinas, estoy autenticado en ambas, estoy en el directorio de trabajo del archivo- - Así que no tengo que abrir otra terminal y copiar y pegar el host remoto y la ruta de acceso, que es lo que hago ahora. La mejor solución tampoco requeriría ninguna configuración antes de que comenzara la sesión, pero si la configuración era de una sola vez o podía automatizarse, entonces eso es perfectamente aceptable.

+0

Tal vez entendí mal algo, pero ¿por qué no puedes usar scp directamente? Con las claves almacenadas, no es necesario ingresar ninguna contraseña. –

+2

El problema con el uso de scp es que necesita escribir el nombre/ipaddr del host local, autenticar, etc. – Nick

Respuesta

0

Aquí está mi solución preferida para este problema. Configure un túnel ssh inverso al crear la sesión ssh. Esto se facilita con dos funciones bash: grabfrom() debe definirse en el host local, mientras que grab() debe definirse en el host remoto. Puede agregar cualquier otra variable ssh que use (por ejemplo, -X o -Y) como mejor le parezca.

function grabfrom() { ssh -R 2202:127.0.0.1:22 ${@}; }; 
function grab() { scp -P 2202 [email protected] [email protected]:~; }; 

de uso:

localhost% grabfrom [email protected] 
password: <remote password goes here> 
remotehost% grab somefile1 somefile2 *.txt 
password: <local password goes here> 

positivo:

  • Funciona sin software especial en cualquiera de acogida más allá de OpenSSH
  • Funciona cuando anfitrión local está detrás de un router NAT
  • Se puede implementar como un par de dos funciones bash de una línea

Negativos:

  • Se utiliza un número de puerto fijo, por lo:
    • no funcionará con múltiples conexiones a host remoto
    • podría entrar en conflicto con un proceso que utiliza ese puerto en el host remoto
  • Requiere localhost accept ssh connections
  • Se requiere un comando especial en la iniciación de la sesión
  • No maneja implícitamente autenticación al localhost
  • No permite a uno especificar el directorio de destino en el servidor local
  • Si agarras a partir de múltiples localhost a el mismo host remoto, ssh no le gustará las teclas que cambian

Trabajo futuro: Esto todavía es bastante kludgy. Obviamente, sería posible manejar el problema de autenticación configurando las claves ssh de forma apropiada y es aún más fácil permitir la especificación de un directorio remoto agregando un parámetro a grab()

Más difícil es abordar los otros aspectos negativos. Sería bueno elegir un puerto dinámico pero, por lo que puedo ver, no hay una forma elegante de pasar ese puerto al shell en el host remoto; Lo mejor que puedo decir es que OpenSSH no le permite establecer variables de entorno arbitrarias en el host remoto y bash no puede tomar variables de entorno de un argumento de línea de comando. Incluso si pudiera elegir un puerto dinámico, no hay forma de asegurarse de que no se use en el host remoto sin conectarse primero.

-1

Debería poder configurar las claves privadas públicas & para que no se necesite autorización.

La forma de hacerlo depende de los requisitos de seguridad, etc. (tenga en cuenta que hay linux/unix ssh worms que buscarán claves para encontrar otros hosts que puedan atacar).

Hago esto todo el tiempo desde detrás de los enrutadores linksys y dlink. Creo que es posible que deba cambiar algunas configuraciones, pero no es gran cosa.

0

Para hacer esto, configuré el enrutador de mi casa para reenviar el puerto 22 a mi máquina doméstica (que está cortafuegos para aceptar únicamente conexiones ssh desde mi máquina de trabajo) y también tengo una cuenta configurada con DynDNS para proporcionar un DNS dinámico que se resolverá automáticamente en mi IP de origen.

Luego, cuando entro en mi computadora de trabajo, lo primero que hago es ejecutar un script que inicie un ssh-agent (si su servidor no lo hace automáticamente). El guión corro es:

#!/bin/bash 

ssh-agent sh -c 'ssh-add < /dev/null && bash' 

Se pide mi contraseña ssh clave para que yo no tengo que escribirla cada vez. No necesita ese paso si usa una clave ssh sin una frase de contraseña.

Para el resto de la sesión, el envío de archivos de nuevo a la máquina de casa es tan simple como

scp file_to_send.txt your.domain.name:~/ 
+0

Sería bueno si SCP/SFTP se pudiera usar a través de la conexión SSH ya abierta. Lástima que hacerlo implicaría un cambio de protocolo. – Powerlord

+0

Pero con la autenticación de clave pública, no hay ninguna desventaja de abrir una nueva conexión SSH. –

+0

Este comentario realmente no aborda ninguno de los puntos que esta persona está pidiendo, que es reutilizar el estado existente sin ninguna configuración adicional antes de tiempo. Además, SCP/SFTP puede volver a utilizar una conexión SSH ya abierta utilizando ControlMaster (-M) como han señalado otras personas. Y hay un inconveniente al abrir una nueva conexión SSH sin ControlMaster, que lleva tiempo negociar cada nueva conexión; en conexiones de alta latencia que pueden ser bastante notorias. – aculich

0

Aquí es una hack called ssh-xfer que aborda el problema exacto, pero requiere de parches OpenSSH, que es un imposible en la medida de como yo estoy preocupado

4

En una caja Linux utilizo ssh-agent y sshfs. Necesita configurar el sshd para aceptar conexiones con pares de claves. Luego usa ssh-add para agregar su clave al ssh-agent para que no tenga que escribir su contraseña cada vez. Asegúrese de utilizar -t segundos, para que la clave no permanezca cargada para siempre.
ssh-add -t 3600 /home/user/.ssh/ssh_dsa

Después de eso,
sshfs nombre de host:// PathToMountTo/
montará el sistema de archivos del servidor en su máquina para que tenga acceso a eso.

Personalmente, escribí un pequeño script bash que agregaba mi clave y montaba los servidores que más uso, así que cuando empiezo a trabajar solo tengo que iniciar el script y escribir mi frase de contraseña.

8

zssh (a ZMODEM envoltura sobre openssh) hace exactamente lo que quiere.

  • Instalar zssh y usarlo en lugar de OpenSSH (que supongo que se utiliza normalmente)

  • Usted tendrá que tener instalado el paquete lrzsz en ambos sistemas.

Entonces, para transferir un archivo zyxel.png de remoto a host local:

[email protected]:~$ zssh remote 
Press ^@ (C-Space) to enter file transfer mode, then ? for help 
... 
[email protected]:~$ sz zyxel.png 
**B00000000000000 
^@ 
zssh > rz 
Receiving: zyxel.png 
Bytes received: 104036/ 104036 BPS:16059729 

Transfer complete 
[email protected]:~$ 

Carga pasa de manera similar, excepto que acaba de cambiar y rz(1)sz(1).

Los usuarios de masilla pueden probar Le Putty, que tiene una funcionalidad similar.

+0

Esta es una gran solución porque, aunque requiere tener un paquete adicional (zssh) instalado, aborda uno de los puntos que otras respuestas no tienen: esto puede hacer uso del directorio de trabajo actual de una sesión interactiva. Recomendaría esto como una excelente solución simple como alternativa a mi respuesta más complicada. Sin embargo, mi propia respuesta vale la pena, porque te ayuda a aprender las funciones más avanzadas disponibles en openssh que son útiles para otras cosas, y también alienta a aprender a usar netcat, que es otra herramienta valiosa. – aculich

-1

Use the -M switch.

"coloca el cliente ssh en el modo de 'maestro' para la conexión de Shar-ción. Opciones -M varios lugares ssh en el modo` `maestro '' con la confirmación requiere antes de aceptar conexiones de esclavos Consulte la descripción de ControlMaster en ssh_config (5) para más detalles. "

No acabo de ver lo que eso responde a la pregunta de la OP - se puede ampliar esto un poco, David?

+0

Esto probablemente debería eliminarse y reproducirse como un comentario. Sin embargo, estoy contigo: no lo entiendo. – dmckee

1

El uso de ControlMaster (el interruptor -M) es la mejor solución, mucho más simple y fácil que el resto de las respuestas aquí. Le permite compartir una única conexión entre varias sesiones. Parece que hace lo que el afiche quiere. Sin embargo, todavía tiene que escribir la línea de comando scp o sftp. Intentalo. Lo uso para todos mis sshing.

2

Usando algunas características poco conocidas y raramente usadas de la implementación de openssh , ¡puede lograr exactamente lo que quiere!

  • se aprovecha de la situación actual
  • puede utilizar el directorio de trabajo donde se encuentre
  • no requiere ningún tipo de configuración de túnel antes de la sesión comienza
  • no es necesario abrir una terminal separada o conexión
  • se puede usar como una operación única en una sesión interactiva o se puede usar como parte de una sesión automatizada

Solo debe escribir lo que está en cada uno de los local>, remote> y ssh> en los ejemplos a continuación.

local> ssh [email protected] 
remote> ~C 
ssh> -L6666:localhost:6666 
remote> nc -l 6666 < /etc/passwd 
remote> ~^Z 
[suspend ssh] 
[1]+ Stopped     ssh [email protected] 
local> (sleep 1; nc localhost 6666 > /tmp/file) & fg 
[2] 17357 
ssh [email protected] 
remote> exit 
[2]- Done     (sleep 1; nc localhost 6666 > /tmp/file) 
local> cat /tmp/file 
root:x:0:0:root:/root:/bin/bash 
bin:x:1:1:bin:/bin:/sbin/nologin 
daemon:x:2:2:daemon:/sbin:/sbin/nologin 
... 

O, más a menudo que quieren ir la otra dirección, por ejemplo, si quiere hacer algo así como la transferencia de su archivo ~/.ssh/id_rsa.pub de el equipo local para el archivo de la ~/.ssh/authorized_keys máquina remota.

local> ssh [email protected] 
remote> ~C 
ssh> -R5555:localhost:5555 
remote> ~^Z 
[suspend ssh] 
[1]+ Stopped     ssh [email protected] 
local> nc -l 5555 < ~/.ssh/id_rsa.pub & 
[2] 26607 
local> fg 
ssh [email protected] 
remote> nc localhost 5555 >> ~/.ssh/authorized_keys 
remote> cat ~/.ssh/authorized_keys 
ssh-rsa AAAAB3NzaC1yc2ZQQQQBIwAAAQEAsgaVp8mnWVvpGKhfgwHTuOObyfYSe8iFvksH6BGWfMgy8poM2+5sTL6FHI7k0MXmfd7p4rzOL2R4q9yjG+Hl2PShjkjAVb32Ss5ZZ3BxHpk30+0HackAHVqPEJERvZvqC3W2s4aKU7ae4WaG1OqZHI1dGiJPJ1IgFF5bWbQl8CP9kZNAHg0NJZUCnJ73udZRYEWm5MEdTIz0+Q5tClzxvXtV4lZBo36Jo4vijKVEJ06MZu+e2WnCOqsfdayY7laiT0t/UsulLNJ1wT+Euejl+3Vft7N1/nWptJn3c4y83c4oHIrsLDTIiVvPjAj5JTkyH1EA2pIOxsKOjmg2Maz7Pw== [email protected] 

Un poco de explicación está en orden.

El primer paso es abrir un LocalForward; si usted no tiene ya uno estableció entonces se puede utilizar el carácter de escape ~C para abrir una línea de comandos ssh que le dará los siguientes comandos:

remote> ~C 
ssh> help 
Commands: 
     -L[bind_address:]port:host:hostport Request local forward 
     -R[bind_address:]port:host:hostport Request remote forward 
     -D[bind_address:]port     Request dynamic forward 
     -KR[bind_address:]port     Cancel remote forward 

En este ejemplo establezco una LocalForward en el puerto 6666 de localhost tanto para el cliente como para el servidor; el número de puerto puede ser cualquier puerto abierto arbitrario .

El comando nc es del paquete netcat; se describe como "navaja suiza TCP/IP"; es un programa útil simple pero muy flexible y . Conviértalo en una parte estándar de su cinturón de herramientas de Unix.

En este punto nc está escuchando en el puerto 6666 ya la espera de otro programa para conectarse a ese puerto por lo que puede enviar el contenido de /etc/passwd.

siguiente que hacen uso de otro carácter de escape ~^Z que es tilde seguido por control-Z. Esto suspende temporalmente el proceso ssh y nos devuelve a nuestro shell.

Una vuelta en el sistema local puede utilizar nc para conectarse a la remitido puerto 6666. Nota la falta de un -l en este caso porque esa opción dice nc para escuchar en un puerto como si se tratara de un servidor que es no es lo que queremos; en su lugar, queremos simplemente utilizar nc como cliente a conectar a la que ya escucha nc en el lado remoto.

Se requiere que el resto de la magia alrededor del comando nc porque si recuerdan anterior dije que el proceso ssh estaba temporalmente suspendido, por lo que el & pondrá toda la (sleep + nc) expresión en el fondo y la sleep le da tiempo suficiente para ssh a volver al primer plano con fg.

En el segundo ejemplo, la idea es básicamente el mismo, excepto establecimos un túnel que va la otra dirección utilizando -R en lugar de -L modo que establecemos una RemoteForward. Y luego en el lado local es donde desea utilizar el argumento -l al nc.

El carácter de escape por defecto es ~ pero esto se puede cambiar con:

-e escape_char 
     Sets the escape character for sessions with a pty (default: ‘~’). The escape character is only recognized at the beginning of a line. The escape character followed by a dot 
     (‘.’) closes the connection; followed by control-Z suspends the connection; and followed by itself sends the escape character once. Setting the character to “none” disables any 
     escapes and makes the session fully transparent. 

Una explicación completa de los comandos disponibles con los caracteres de escape está disponible en el ssh manpage

ESCAPE CHARACTERS 
    When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape character. 

    A single tilde character can be sent as ~~ or by following the tilde by a character other than those described below. The escape character must always follow a newline to be interpreted 
    as special. The escape character can be changed in configuration files using the EscapeChar configuration directive or on the command line by the -e option. 

    The supported escapes (assuming the default ‘~’) are: 

    ~.  Disconnect. 

    ~^Z  Background ssh. 

    ~#  List forwarded connections. 

    ~&  Background ssh at logout when waiting for forwarded connection/X11 sessions to terminate. 

    ~?  Display a list of escape characters. 

    ~B  Send a BREAK to the remote system (only useful for SSH protocol version 2 and if the peer supports it). 

    ~C  Open command line. Currently this allows the addition of port forwardings using the -L, -R and -D options (see above). It also allows the cancellation of existing remote port- 
      forwardings using -KR[bind_address:]port. !command allows the user to execute a local command if the PermitLocalCommand option is enabled in ssh_config(5). Basic help is avail‐ 
      able, using the -h option. 

    ~R  Request rekeying of the connection (only useful for SSH protocol version 2 and if the peer supports it). 
+0

Para una solución más simple al problema, recomiendo consultar la respuesta de zssh ; sin embargo, mi respuesta vale la pena para aprender las funciones más avanzadas de ssh y hacer uso de netcat, que es una herramienta esencial que la gente debería saber cómo usar. – aculich

Cuestiones relacionadas