¿Cómo canalizar datos a la conexión sftp?

9

ftp admite el put "|..." "remote-file.name"comando para canalizar datos a una conexión ftp. ¿Hay algo similar disponible para sftp?

En sftp me sale el siguiente error:

sftp 'jmw@backupsrv:/uploads'
sftp> put "| tar -cx /storage" "backup-2012-06-19--17-51.tgz"
stat | tar -cv /storage: No such file or directory

como arriba, el cliente sftp obviamente no ejecuta el comando.

Quiero usar el comando de tubería para redirigir directamente la secuencia del archivo a sftp. (porque no queda suficiente espacio para crear un archivo de copia de seguridad en el mismo disco antes de cargarlo en el servidor sftp).

JMW
fuente
1
Pensé en usar un FIFO para esto, pero ni SFTP ni SCP leerán de un FIFO.
Tom Anderson el
1
También es una buena idea, esto es mío: qxs.ch/2012/07/05/sftp-upload-tool
JMW 05 de

Respuestas:

4

Me divertí mucho encontrando una solución a este problema. Requiere la herramienta nc (netcat) en ambas máquinas y SSH (no se necesita SFTP).

En este ejemplo, llamaré a la máquina que tiene los datos que necesitan respaldar linux-a, y la máquina que necesita recibir la copia de seguridad linux-b.

En linux-a, haga que netcat escuche en un puerto (tomé 2000) y rediríjalo a un archivo. Esto solo se quedará allí y esperará hasta que algo llegue a ese puerto.

[kenny@linux-b /var/backups]$ nc -l 2000 > backup.tgz

En linux-b, abra un túnel ssh en linux-a, utilicé el puerto 2000 nuevamente. Esto redirigirá todo lo que arroje en el puerto TCP 2000 en localhost al puerto TCP 2000 en linux-a, donde netcat está escuchando.

[kenny@linux-a /var/data]$ ssh -L 2000:localhost:2000 -CfN linux-b

Ahora cree el archivo tar, pero envíe la salida a stdout (usando -) y canalícela a gzip para obtener algo de compresión. Ahora canalice eso a otro netcat que lo envíe a localhost en TCP en el puerto 2000.

[kenny@linux-a /var/data]$ tar cf - important-data | gzip -fc | nc localhost 2000

Ya hemos terminado! En linux-b, netcat ya no escucha y se crea un nuevo archivo. La mejor parte es que el archivo tar nunca se colocó en el disco duro de linux-a.

[kenny@linux-b /var/backups]$ file backup.tgz 
backup.tgz: gzip compressed data, from Unix, last modified: Thu Jul  5 13:48:03 2012

Sé que no es exactamente lo que pediste en la pregunta, pero si tienes netcat disponible, es una solución viable para tu tipo de problema.

Editar: Olvidé una cosa: si sigues estas instrucciones, todavía tendrás un túnel SSH flotando en linux-a. Descubra cuál es la ID del proceso y elimínelo.

[kenny@linux-a /var/data]$ ps -ef | grep "ssh -L"
kenny     5741     1  0 13:40 ?        00:00:00 ssh -L 2000:localhost:2000 -CfN linux-b
kenny     5940  3360  0 14:13 pts/1    00:00:00 grep --color=auto ssh -L
[kenny@linux-a /var/data]$ kill 5741
Kenny Rasschaert
fuente
3
me gusta, pero hay 2 problemas: los usuarios de sftponly generalmente no pueden usar el reenvío de puertos y los usuarios de sftponly no pueden acceder a nc en el servidor sftp (recuerden que no tienen acceso ssh)
JMW
1
Esa es una crítica completamente válida.
Kenny Rasschaert el
Fuera de tema, pero ¿por qué hay una captura de pantalla de "The Prestige" incrustada en esta publicación?
Rilindo
4

Como este es el primer resultado que encuentras buscando en Google esta pregunta y no se ha mencionado ya, también agregaré la solución que encontré aquí:

puede usar la implementación de curls sftp para esto. Como curl probablemente ya esté instalado en muchos sistemas, esto podría preferirse a la solución que usa clientes personalizados.

ejemplo de uso:

pg_dump -d database | pigz -1 | curl -u username -T - sftp://sftpserver/folder/dbbackup.sql.gz

curlusa su .ssh/known_hostsarchivo para la verificación de clave. Esto podría fallar en caso de que su cliente ssh use estándares de cifrado más nuevos no admitidos por la biblioteca utilizada en curl

Para solucionar esto, puede agregar los otros tipos de clave al archivo de hosts conocidos con el siguiente comando:

ssh-keyscan sftpserver >> ~/.ssh/known_hosts

o puede deshabilitar la verificación de clave usando la -kbandera (aunque no lo recomendaría)

bsod
fuente
2

output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command' es una opción, si su usuario remoto tiene un shell válido.

voretaq7
fuente
55
¡Esto NO es sftp!
jirib
3
@JiriXichtkniha No, no lo es, sin embargo, SFTP casi siempre se implementa como un subsistema de su servidor SSH, y este es el análogo más cercano a la funcionalidad que veo que se solicita de la pregunta (los datos de canalización a través de SFTP serán manejados por un programa en el otro extremo). A veces la respuesta es "Estás usando la herramienta incorrecta, hazlo en su thislugar". - Esto me parece una de esas veces.
voretaq7
2
sftp es protol, y es diferente de simplemente canalizar a través de ssh, eso es todo. Su sugerencia no funcionaría si la parte remota fuera solo SFTP.
jirib
1
no se me permite iniciar sesión como usuario ssh
JMW
1
@JMW en ese caso, por lo que sé, estás bastante jodido aquí: nunca he visto una versión de sftp que admita la conexión de un comando en el sistema remoto (probablemente porque derrotaría la Secure al dejar entrar a alguien su situación que no tiene un shell ejecutar programas de todos modos). Podría estar equivocado, sin embargo - Lo que más me familiarizado con la funcionalidad de SFTP en OpenSSH y el servidor SSH propietaria Sun utiliza para enviar ...
voretaq7
1

voretaq7 señaló que el cliente sftp no admite la transferencia de datos canalizados para los usuarios, que solo pueden usar sftp para conectarse al servidor.

Afortunadamente, hay libssh2, que admite sftp. así que solo necesitamos otros 2 clientes que usen libssh2, a los que he llamado:

  • sftp_stdin_upload (para cargar en un servidor sftp)
  • sftp_stdout_download (para descargar desde un servidor sftp)

el código fuente se puede encontrar en la siguiente URL: http://www.qxs.ch/2012/07/05/sftp-upload-tool/


Como no tengo tanta experiencia en la programación de libssh2, estoy feliz de recibir cualquier comentario sobre el código fuente.

JMW
fuente
No funciona para mí :-( / usr / bin / ld: libssh2-1.4.2 / src / .libs / libssh2.a (knownhost.o): referencia indefinida al símbolo 'EVP_sha1' / usr / lib / libcrypto. so.0.0.0: error al agregar símbolos: falta DSO en la línea de comando collect2: error: ld devolvió 1 estado de salida
tobixen
Este código tiene solo un estado POC. Siéntase libre de arreglarlo usted mismo. :-)
JMW