Какой лучший способ доставить файл с удаленного хоста на локальный хост через сеанс SSH? - PullRequest
14 голосов
/ 08 сентября 2008

При подключении к удаленным хостам через ssh я часто хочу перенести файл из этой системы в локальную систему для просмотра или обработки. Есть ли способ скопировать файл без (a) открытия нового терминала / приостановки сеанса ssh (b) повторной аутентификации либо на локальном, либо на удаленном хосте, который работает (c), даже если один или оба хоста находятся за NAT роутер?

Цель состоит в том, чтобы максимально использовать текущее состояние: между двумя компьютерами есть связь, на обоих я аутентифицирована, что я нахожусь в рабочем каталоге файла - -Так что мне не нужно открывать другой терминал, копировать и вставлять удаленный хост и путь, что я и делаю сейчас. Лучшее решение также не потребует какой-либо настройки до начала сеанса, но если установка была одноразовой или могла быть автоматизирована, то это вполне приемлемо.

Ответы [ 10 ]

8 голосов
/ 08 сентября 2008

zssh (оболочка ZMODEM поверх openssh) делает именно то, что вы хотите.

  • Установите zssh и используйте его вместо openssh (который я предполагаю, что вы обычно используете)

  • Вам потребуется установить пакет lrzsz в обеих системах.

Затем для передачи файла zyxel.png с удаленного на локальный хост:

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

Transfer complete
antti@remote:~$ 

Загрузка происходит аналогично, за исключением того, что вы просто переключаете rz (1) и sz (1) .

Пользователи Putty могут попробовать Le Putty , который имеет аналогичную функциональность.

4 голосов
/ 08 сентября 2008

На Linux-коробке я использую ssh-agent и sshfs. Вам необходимо настроить sshd для приема соединений с парами ключей. Затем вы используете ssh-add, чтобы добавить свой ключ в ssh-agent, чтобы вам не приходилось каждый раз вводить пароль. Обязательно используйте -t секунды, чтобы ключ не оставался загруженным вечно.
ssh-add -t 3600 /home/user/.ssh/ssh_dsa

После этого
Имя хоста sshfs: / / PathToMountTo /
смонтирует файловую систему сервера на вашем компьютере, чтобы у вас был к ней доступ.

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

2 голосов
/ 07 декабря 2011

Использование некоторых малоизвестных и редко используемых функций openssh Реализация вы можете выполнить именно то, что вы хотите!

  • использует текущее состояние
  • можете использовать рабочий каталог, где вы находитесь
  • не требует настройки туннелирования до начала сеанса
  • не требует открытия отдельного терминала или соединения
  • может использоваться как разовая сделка в интерактивном сеансе или как часть автоматизированного сеанса

Вы должны печатать только то, что на каждом из local>, remote> и ssh> подсказок в примерах ниже.

local> ssh username@remote
remote> ~C
ssh> -L6666:localhost:6666
remote> nc -l 6666 < /etc/passwd
remote> ~^Z
[suspend ssh]
[1]+  Stopped                 ssh username@remote
local> (sleep 1; nc localhost 6666 > /tmp/file) & fg
[2] 17357
ssh username@remote
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
...

Или, чаще вы хотите пойти в другом направлении, например, если вы хотите сделать что-то вроде передачи файла ~/.ssh/id_rsa.pub из ваш локальный компьютер в файл ~/.ssh/authorized_keys удаленного машина.

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

Немного пояснений.

Первый шаг - открыть LocalForward; если у вас еще нет один установлен, то вы можете использовать escape-символ ~C, чтобы открыть Командная строка ssh, которая выдаст вам следующие команды:

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

В этом примере я устанавливаю LocalForward на порт 6666 локального хоста как для клиента, так и для сервера; номер порта может быть любым произвольный открытый порт.

Команда nc из пакета netcat; это описывается как «TCP / IP швейцарский армейский нож»; это простой, но очень гибкий и полезная программа. Сделайте это стандартной частью вашего unix toolbelt.

В этот момент nc прослушивает порт 6666 и ждет другого Программа для подключения к этому порту, чтобы он мог отправить содержимое /etc/passwd.

Затем мы используем другой escape-символ ~^Z, который tilde затем control-Z. Это временно приостанавливает процесс SSH и бросает нас обратно в нашу раковину.

Один назад в локальной системе вы можете использовать nc для подключения к перенаправленный порт 6666. Обратите внимание на отсутствие -l в этом случае, потому что это опция говорит nc прослушивать порт, как если бы это был сервер, который не то, что мы хотим; вместо этого мы хотим просто использовать nc в качестве клиента для подключитесь к уже прослушиваемой nc на удаленной стороне.

Остальная часть магии вокруг команды nc требуется, потому что если Вы помните выше, я сказал, что процесс ssh был временно приостановлено, поэтому & поместит все выражение (sleep + nc) в фоновом режиме и sleep дает вам достаточно времени для SSH вернитесь на передний план с fg.

Во втором примере идея в основном та же самая, за исключением того, что мы настроили туннель, идущий в другом направлении, используя -R вместо -L, так что мы устанавливаем RemoteForward. И тогда на местной стороне, где вы хотите использовать аргумент -l для nc.

Экранирующим символом по умолчанию является ~, но вы можете изменить это с помощью:

 -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.

Полное объяснение команд, доступных с escape-символами, доступно на справочной странице ssh

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).
1 голос
/ 30 мая 2011

Использование ControlMaster (ключ -M) - лучшее решение, более простое и простое, чем остальные ответы здесь. Это позволяет вам разделить одно соединение между несколькими сессиями. Похоже, это делает то, что хочет плакат. Вы все еще должны набрать командную строку scp или sftp. Попытайся. Я использую это для всего моего sshing.

0 голосов
/ 28 марта 2014

Вы можете использовать протокол SCP для передачи файла. Вы можете обратиться по этой ссылке

http://tekheez.biz/scp-protocol-in-unix/

0 голосов
/ 16 сентября 2008

Вот мое предпочтительное решение этой проблемы. Настройте обратный туннель ssh после создания сеанса ssh. Это легко сделать с помощью двух функций bash: на локальном хосте необходимо определить grabfrom (), а на удаленном хосте - grab (). Вы можете добавить любые другие используемые вами ssh-переменные (например, -X или -Y) по своему усмотрению.

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

Использование:

localhost% grabfrom remoteuser@remotehost
password: <remote password goes here>
remotehost% grab somefile1 somefile2 *.txt
password: <local password goes here>

Положительные:

  • Работает без специального программного обеспечения на любом хосте, кроме OpenSSH
  • Работает, когда локальный хост находится за маршрутизатором NAT
  • Может быть реализована в виде пары двухстрочных функций из одной строки

Отрицательные:

  • Используется фиксированный номер порта, поэтому:
    • не будет работать с несколькими подключениями к удаленному хосту
    • может конфликтовать с процессом, использующим этот порт на удаленном хосте
  • Требуется, чтобы localhost принимал ssh-соединения
  • Требуется специальная команда для начала сеанса
  • Неявно обрабатывает аутентификацию на локальном хосте
  • Он не позволяет указать каталог назначения на локальном хосте
  • Если вы перешли с нескольких локальных хостов на один и тот же удаленный хост, ssh не понравится изменение ключей

Будущая работа: Это все еще довольно глупо. Очевидно, что можно было бы решить проблему аутентификации путем соответствующей настройки ключей ssh, и еще проще разрешить спецификацию удаленного каталога, добавив параметр в grab ()

Более сложным является рассмотрение других негативов. Было бы неплохо выбрать динамический порт, но, насколько я могу судить, не существует элегантного способа передачи этого порта в оболочку на удаленном хосте; Насколько я могу судить, OpenSSH не позволяет вам устанавливать произвольные переменные окружения на удаленном хосте, а bash не может принимать переменные окружения из аргумента командной строки. Даже если вы можете выбрать динамический порт, невозможно гарантировать, что он не будет использоваться на удаленном хосте без предварительного подключения.

0 голосов
/ 08 сентября 2008

Используйте переключатель -M.

"Переводит ssh-клиент в режим 'master' для разделения соединений. Несколько опций -M переводят ssh в режим` `master '' с подтверждением, требуемым до того, как подчиненные соединения будут приняты. См. Описание ControlMaster в ssh_config ( 5) для деталей. "

Я не совсем понимаю, как это отвечает на вопрос ОП - не могли бы вы немного рассказать об этом, Дэвид?

0 голосов
/ 08 сентября 2008

Вот хак , называемый ssh-xfer , который решает точную проблему, но требует исправления OpenSSH, что, на мой взгляд, не является началом.

0 голосов
/ 08 сентября 2008

Для этого у меня настроен домашний маршрутизатор для переадресации порта 22 обратно на мою домашнюю машину (которая защищена брандмауэром для приема только соединений ssh ​​от моей рабочей машины), и у меня также установлена ​​учетная запись с DynDNS для предоставления динамического DNS, который будет автоматически преобразовываться в мой домашний IP.

Затем, когда я захожу в свой рабочий компьютер по ssh, первым делом запускаю скрипт, запускающий ssh-agent (если ваш сервер не делает этого автоматически). Сценарий, который я запускаю:

#!/bin/bash

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

Он запрашивает мою парольную фразу ключа ssh, чтобы мне не приходилось вводить ее каждый раз. Вам не нужен этот шаг, если вы используете ssh-ключ без ключевой фразы.

Для оставшейся части сеанса отправка файлов обратно на домашнюю машину так же проста, как

scp file_to_send.txt your.domain.name:~/
0 голосов
/ 08 сентября 2008

Вы должны иметь возможность настроить открытый и закрытый ключи, чтобы не требовалась авторизация.

То, как вы это сделаете, зависит от требований безопасности и т. Д. (Учтите, что существуют ssh-черви linux / unix, которые будут искать ключи, чтобы найти другие хосты, на которые они могут атаковать).

Я делаю это все время из-за обоих маршрутизаторов linksys и dlink. Я думаю, что вам может понадобиться изменить пару настроек, но это не имеет большого значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...