68

У меня есть доступ к 3 машинам, A, B и C. Единственные возможные (ssh) соединения:

A -> B
B <-> C

Мне нужно получить файлы от A до C, чтобы я мог просмотреть файлы от A до B, а затем скопировать их из B в C. Однако B не имеет много места на диске, так что это не вариант. Есть ли способ scp файлы из A в C через B? Обратите внимание, что у меня нет прав доступа root ни на одной из машин, поэтому не думайте, что я могу настроить какие-либо постоянные туннели, но исправьте меня, если я ошибаюсь!

4 ответа4

87

ProxyJump

Новое в OpenSSH 7.3:

A$ scp -oProxyJump=B thefile C:destination

(За кулисами это просто использует ProxyCommand и ssh -W .)

ProxyCommand

Обновлено, чтобы включить -W из других ответов:

A$ scp -oProxyCommand="ssh -W %h:%p B" thefile C:destination

Если у A установлен очень старый SSH-клиент (без поддержки -W ) или если B настроен на запрет перенаправления TCP (но все еще допускает команды оболочки), используйте альтернативы:

A$ scp -oProxyCommand="ssh B socat stdio tcp:%h:%p" thefile C:destination
A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination

трубы

A$ tar cf - thefile anotherfile | ssh B "ssh C \"cd destination && tar xvf -\""
A$ (echo thefile; echo anotherfile) | cpio -o | ssh B "ssh C \"cd destination && cpio -i\""

Только для одного файла:

A$ ssh B "ssh C \"cd destination && cat > thefile\"" < thefile

"Туннель" через Б

A$ ssh -f -N -L 4567:C:22 B
(continues running in background)

A$ scp -P 4567 thefile localhost:destinationPath

Когда вы закончите, не забудьте завершить ранее запущенный процесс ssh (который перешел в фоновый режим из-за -f -N).

  • -f Запрашивает ssh перейти в фон непосредственно перед выполнением команды. Это полезно, если ssh собирается запрашивать пароли или парольные фразы, но пользователь хочет сделать это в фоновом режиме. Это подразумевает -n.
  • -N Не выполнять удаленную команду. Это полезно только для переадресации портов.

Обратный "туннель" через B к A

Не всегда работает, хотя:

A$ ssh -f -N -R 4567:localhost:22 B
(now you can reach A from B, by using localhost:4567)

B$ scp -P 4567 localhost:thefile C:destination
  • -R Указывает, что соединения с данным портом TCP или сокетом Unix на удаленном (серверном) хосте должны перенаправляться на данный хост и порт или сокет Unix на локальной стороне.
22

Версии scp с начала 2011 года и позже могут иметь опцию «-3»:

 -3      Copies between two remote hosts are transferred through the local
         host.  Without this option the data is copied directly between
         the two remote hosts.  Note that this option disables the
         progress meter.

Если у вас есть это, вы можете просто запустить:

B$ scp -3 A:file C:file
7

Почти все уже сказано, но вот моя последняя копейка: я использую вариант ProxyCommand без nc и soc . На основе прокси-серверов OpenSSH и Jumphost Cookbook я создал следующую конфигурацию:

  1. Итак, у нас есть следующие игроки:

    • HOME_HOST: это откуда мы копируем файл на целевой хост
    • HOP_HOST: мы копируем через этот хост (зарегистрирован как HOP_USER)
    • TARGET_HOST: это наш пункт назначения (аутентифицированный как TARGET_USER)
  2. Сначала я добавил свой локальный открытый ключ с моего домашнего хоста .ssh/id_dsa.pub в .ssh/authorized_keys как на хосте, так и на целевом хосте. Да, один и тот же открытый ключ от домашнего хоста для них обоих. Обычно вы ожидаете, что это открытый ключ HOP, который вы должны добавить к TARGET.

  3. Затем я немного подправил .ssh/config , добавив следующую запись:

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. После этого операция копирования выполняется так: scp FILE TARGET_HOST: Он отображает двойные баннеры как с узла, так и с узла, но работает.

Конечно, вы можете использовать выше для ssh непосредственно к цели: ssh TARGET_HOST . Работает с scp и ssh.

Другим более общим вариантом может быть утилита sshuttle, которая выглядит как своего рода прозрачный прокси (vpn поверх ssh). Так что в вашем случае A-> B <-> C это позволяет подключиться к каждому узлу в сети C: A-> B- [CDEFG]. Ему не нужен админ, но он требует Python 2.7 (3.5 тоже хорошо), что не всегда то, что мы имеем. Это стоит попробовать.

6
ssh -L 4321:hostC:22 youruser@hostB

в другой оболочке:

scp -P 4321 localfile youruser@127.0.0.1

Это использует переадресацию портов. Единственным ограничением здесь является то, что хост B должен быть настроен для разрешения переадресации портов. В противном случае это должно работать нормально.

В качестве объяснения -L и -R позволяют вам перенаправлять порты. В -L первый указанный порт - это порт, который ssh начнет прослушивать на исходной машине (хост A), и он перенаправит все, что получит на этом порту через ваше SSH-соединение, на хост B, а затем направит его на хост C на порт. 22.

редактировать

Я немного испортил синтаксис. Он настраивает форварда на вашей локальной машине.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .