scp файлы через промежуточный хост


85

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

A -> B
B <-> C

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


6
Я знаю, что это не отвечает на вопрос, но для тех, кто не знает о rsync или не знает, как использовать его для переключения между хостами, это может быть полезным советом: используйте опцию '-e' с Rsync, как это:A$ rsync <options> -e 'ssh B ssh' source C:destination
Eddified

Ответы:


108

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 на локальной стороне.

Большое спасибо за эти примеры @grawity. Один вопрос - можно ли инвертировать `tar c thefile другой файл | ssh B "ssh C \" cd destination && tar xv \ "" ´ для копирования загрузки из C в A (находясь на A)
dmeu

@dmeu: Да, это возможно.
Гравитация

Как «убить» ранее запущенный процесс ssh, если, скажем, я использую MacOS?
Aero Windwalker

Примечание: Как обычно, если вы хотите перейти scp от C, хотя B, к A, вы можете сделать A$ scp -oProxyJump=B C:destination thefile.
jvriesem

@Pablo Лучше использовать -S, затем и -O выйти. Или ... хотя бы pkill -f.
grawity

24

Версии 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

В моем случае хост A был доступен только из B (который был VPN). Хост C находился в той же локальной сети, что и B. Я хотел получить файл от A до C, и scp -3 блестяще решил его.
Джо

У меня были проблемы с этим, когда оба хоста запрашивали пароль. Кажется, он запрашивает оба сразу (в одной строке появилось два запроса на ввод пароля), а затем он не смог принять мой пароль. В конце концов я мог заставить его работать, многократно набирая свой пароль (один и тот же пароль на обоих хостах), но это было трудно понять.
Колин Д.

8

Почти все уже сказано, но вот моя последняя копейка: я использую вариант ProxyCommand без ncor 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 тоже хорошо), что не всегда то, что мы имеем. Это стоит попробовать.


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

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

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


@astrofrog - если один из наших ответов удовлетворит ваши потребности, вам, вероятно, следует принять один из них.
Брайан Ванденберг

2

Ответ от Grawity ProxyCommand работал для меня, но, поскольку я менее знаком с SSH, потребовались некоторые эксперименты. Я подумал, что просто изложу ответ Гравити более подробно, чтобы помочь другим новичкам в SSH, таким как я. Вот определения для более явного обозначения:

Машина A: машина, на которой вы находитесь

Сервер B: userB@ip.address.for.B (сервер перехода или промежуточный сервер)

Сервер C: userC@ip.address.for.C (удаленный сервер, на который вы хотите скопировать)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p userB@ip.address.for.B" thefile userC@ip.address.for.C:destination

Конкретный пример

Итак, для конкретного примера, скажем, у вас есть доступ к серверу с IP 0.0.1.2с учетной записью пользователя с именем bar(Сервер C). Но чтобы добраться до него, вам нужно сначала войти на сервер с IP 0.0.1.1с учетной записью пользователя с именем foo(Сервер B). Теперь вы хотите скопировать файл , baz.txtрасположенный на текущей машине (Machine A) для сервера 0.0.1.2«s /home/bar/директории. Чтобы использовать вышеупомянутый ProxyCommand для этого примера, вы должны выполнить следующее:

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" baz.txt bar@0.0.1.2:/home/bar/

Вы также можете с легкостью скопировать файл с сервера C, изменив его порядок и место назначения. Так, например, если вы baz.txtуже находились на сервере, 0.0.1.2расположенном по адресу, /home/bar/вы можете скопировать его на свой компьютер, используя:

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" bar@0.0.1.2:/home/bar/baz.txt /destination/path/on/A

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

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