Каков наилучший способ принести файл с удаленного хоста на локальный хост через сеанс SSH?

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

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

Ответы

Ответ 1

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

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

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

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

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

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

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

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

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

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

Ответ 2

zssh (a ZMODEM wrapper over openssh) делает именно то, что вы хотите.

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

  • У вас должен быть установлен пакет lrzsz на обеих системах.

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

[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]:~$ 

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

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

Ответ 3

В ящике linux я использую ssh-agent и sshfs. Вам нужно настроить sshd для приема соединений с парами ключей. Затем вы используете ssh-add, чтобы добавить ключ к ssh-агенту, чтобы вы не вводили свой пароль каждый раз. Обязательно используйте -t секунд, чтобы ключ не оставался навсегда.

ssh-add -t 3600/home/user/.ssh/ssh_dsa

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

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

Ответ 4

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

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

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

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

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

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]

Немного объяснения в порядке.

Первый шаг - открыть 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 localhost как для клиента, так и для сервера; номер порта может быть любым произвольный открытый порт.

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

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

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

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

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

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

Символ escape по умолчанию - ~, но вы можете изменить его с помощью:

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

Ответ 5

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

Ответ 6

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

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

#!/bin/bash

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

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

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

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

Ответ 7

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

Ответ 8

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

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

Ответ 9

Вы должны иметь возможность создавать общедоступные и закрытые ключи, чтобы не требовалось auth.

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

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

Ответ 10

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

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

Я не совсем понимаю, как это отвечает на вопрос OP - можете ли вы немного расширить его, Дэвид?