如何将数据管道传输到sftp连接?


9

ftp支持将put "|..." "remote-file.name"数据管道传输到ftp连接的命令。sftp是否有类似的功能?

在sftp中,出现以下错误:

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

如上sftp客户端显然不执行命令。

我想使用管道命令直接将文件流重定向到sftp。(因为在将其上载到sftp服务器之前,没有足够的空间在同一磁盘上创建备份文件。)


1
我考虑过为此使用FIFO,但是SFTP和SCP都不会从FIFO中读取。
汤姆·安德森

1
也是个好主意,这是我的:qxs.ch/2012/07/05/sftp-upload-tool
JMW

Answers:


4

找出解决这个问题的方法,我感到很开心。在两台计算机上都需要工具nc(netcat),并且需要SSH(不需要SFTP)。

在此示例中,我将调用具有需要备份linux-a的数据的计算机,以及需要接收备份linux-b的计算机。

在linux-a上,让netcat监听端口(我花了2000)并将其重定向到文件。它只会坐在那里,等到该端口上有东西通过。

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

在linux-b上,打开到linux-a的ssh隧道,我再次使用端口2000。这会将您在localhost的TCP端口2000上抛出的所有内容重定向到netcat正在侦听的linux-a上的TCP端口2000。

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

现在创建tar归档文件,但是将输出发送到stdout(使用-)并将其通过管道传输到gzip进行压缩。现在,将其通过管道传送到另一个netcat,并将其发送到端口2000上TCP的localhost。

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

大功告成!在linux-b上,netcat不再侦听,并且创建了一个新文件。最好的部分是tar存档从未放在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

我知道这不是您在问题中所要的,但是如果您有可用的netcat,则它是解决问题类型的可行解决方案。

编辑:我忘记了一件事:如果遵循这些说明,您仍将在linux-a上浮动SSH隧道。找出进程ID是什么并将其杀死。

[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

3
我喜欢它,但是有2个问题:sftponly用户通常不能使用端口转发,并且sftponly用户不能访问sftp服务器上的nc(请记住他们没有ssh访问权限)
JMW 2012年

1
这完全是正确的批评。
肯尼·拉沙特

话题不对,但是为什么本文中嵌入了“ The Prestige”的屏幕截图?
Rilindo

4

由于这是您通过谷歌搜索此问题而发现的第一个结果,并且尚未提及,因此我还将添加在这里找到的解决方案:

您可以为此使用curls sftp实现。由于curl可能已经安装在许多系统上,因此它比使用自定义客户端的解决方案更可取。

用法示例:

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

curl使用您的.ssh/known_hosts文件进行密钥验证。如果您的ssh客户端确实使用了curl中使用的库不支持的较新的加密标准,则这可能会失败

要解决此问题,您可以使用以下命令将其他密钥类型添加到已知主机文件中:

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

或者您可以使用该-k标志禁用密钥验证(不过我不建议这样做)


2

output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command' 如果远程用户具有有效的外壳程序,则是一个选项。


5
不是 sftp!
jirib 2012年

3
@JiriXichtkniha不,不是,但是SFTP几乎总是作为SSH服务器的子系统实现的,这与我看到的问题(通过SFTP的管道数据由程序处理)最相似。在另一端)。有时答案是“您使用的是错误的工具- this相反。” -这一次让我印象深刻。
voretaq7 2012年

2
sftp是协议,与通过ssh进行管道传输不同,就是这样!如果远程部分仅是SFTP,则您的建议将不起作用。
jirib 2012年

1
我不能登录的SSH用户
JMW

1
就我所知,在这种情况下,@ JMW已经在这里搞砸了-我从未见过支持远程系统上的命令管道化的sftp版本(可能是因为它S会让某人进入您仍然没有shell运行程序的情况)。不过我可能错了-我最熟悉OpenSSH中的SFTP功能以及Sun以前曾发行的专有SSH服务器...
voretaq7 2012年

1

voretaq7指出,sftp客户端不支持用户的管道数据传输,只能使用sftp来连接服务器。

幸运的是,有支持sftp的libssh2。所以我们只需要2个其他使用libssh2的客户端,我称之为:

  • sftp_stdin_upload(上传到sftp服务器)
  • sftp_stdout_download(从sftp服务器下载)

可以在以下URL下找到源代码:http : //www.qxs.ch/2012/07/05/sftp-upload-tool/


由于我没有libssh2编程经验,因此很高兴收到对源代码的任何反馈。


对我不起作用:-( / usr / bin / ld:libssh2-1.4.2 / src / .libs / libssh2.a(knownhost.o):对符号'EVP_sha1'/ usr / lib / libcrypto的未定义引用。 so.1.0.0:添加符号时出错:命令行collect2中缺少DSO:错误:ld返回1退出状态
tobixen

此代码仅具有POC状态。随时自行修复。:-)
JMW
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.