как передать данные в соединение 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 явно не выполняет команду.

я хочу использовать команду pipe для прямого перенаправления файлового потока в sftp. (потому что недостаточно места для создания файла резервной копии на том же диске перед его загрузкой на сервер sftp.)


1
Я думал об использовании FIFO для этого, но ни SFTP, ни SCP не будут читать из FIFO.
Том Андерсон

1
также хорошая идея, это мое: qxs.ch/2012/07/05/sftp-upload-tool
JMW

Ответы:


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, откройте ssh-туннель к linux-a, я снова использовал порт 2000. Это перенаправит все, что вы выбросите на TCP-порт 2000 на локальном хосте, на TCP-порт 2000 на linux-a, где прослушивает netcat.

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

Теперь создайте архив tar, но отправьте вывод в stdout (используя -) и передайте его в gzip для некоторого сжатия. Теперь передайте это другому netcat, который отправит его на локальный хост по TCP через порт 2000.

[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, это жизнеспособное решение для вашего типа проблемы.

Редактировать: я забыл одну вещь: если вы будете следовать этим инструкциям, у вас все еще будет SSH-туннель, плавающий на linux-a. Узнайте, что такое идентификатор процесса, и убейте его.

[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
Мне это нравится, но есть две проблемы: пользователи sftponly обычно не могут использовать переадресацию портов, а пользователи sftponly не могут получить доступ к nc на сервере sftp (помните, что у них нет доступа ssh)
JMW

1
Это вполне обоснованная критика.
Кенни Рассчарт

Не по теме, но почему в этот пост встроен снимок экрана «Престиж»?
Рилиндо

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

чтобы исправить это, вы можете добавить другие типы ключей в известный файл hosts, используя следующую команду:

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

или вы можете отключить проверку ключа с помощью -kфлага (хотя я бы не рекомендовал это делать)


2

output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command' это вариант, если у вашего удаленного пользователя есть действующая оболочка.


5
Это НЕ sftp!
Джириб

3
@JiriXichtkniha Нет, это не так, однако SFTP почти всегда реализуется как подсистема вашего SSH-сервера, и это наиболее близкий аналог к ​​функциональности, которую я вижу, запрашиваемой из вопроса (данные канала через SFTP обрабатываются программой на другом конце). Иногда ответ таков: «Вы используете не тот инструмент - делайте thisвместо этого». - это поражает меня как один из тех времен.
voretaq7

2
sftp - это protol, и он отличается от простого прохождения через ssh, вот и все! Ваше предложение не будет работать, если удаленной частью будет только SFTP.
Джириб

1
мне не разрешено входить в систему как пользователь ssh
JMW

1
@JMW в этом случае, насколько я знаю, вы здесь неплохо разбираетесь - я никогда не видел версию sftp, которая поддерживает передачу в команду на удаленной системе (возможно, потому что она Sпобеждает бит ecure, позволяя кому-то ваша ситуация, у которой все равно нет программ запуска оболочки). Хотя я могу ошибаться - я в основном знаком с функциональностью SFTP в OpenSSH и проприетарным SSH-сервером, который Sun использовал для доставки ...
voretaq7

1

voretaq7 отметил, что клиент sftp не поддерживает передачу данных по трубопроводам для пользователей, которым разрешено использовать sftp только для подключения к серверу.

К счастью, есть libssh2, которая поддерживает sftp. поэтому нам просто нужно 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: ошибка при добавлении символов: DSO отсутствует в командной строке collect2: ошибка: ld вернул 1 состояние выхода
tobixen

Этот код имеет только статус POC. Не стесняйтесь исправить это самостоятельно. :-)
JMW
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.