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


84

У мене є доступ до 3 машин, A, B і C. Єдиним можливим (ssh) з'єднанням є:

A -> B
B <-> C

Мені потрібно отримати файли від А до С, щоб я міг скопіювати файли від А до В, а потім прокрутити їх від B до C. Однак у B мало місця на диску, тому це не варіант. Чи є спосіб сканувати файли з А на С через В? Зауважте, я не маю кореневого доступу на жодній із машин, тому не думайте, що я можу налаштувати будь-які стійкі тунелі, але виправте мене, якщо я помиляюся!


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

Відповіді:


107

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Не виконуйте віддалену команду. Це корисно лише для переадресації портів.

Зворотний "тунель" через В до А

Не завжди це працює:

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 anotherfile | ssh B "ssh C \" cd призначення && tar xv \ "" ´ для того, щоб скопіювати завантаження з C на A (знаходяться на A)
dmeu

@dmeu: Так, це можливо.
grawity

Як "вбити" раніше розпочатий процес 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 (який був VPNed). Ведучий C був у тій самій локальній мережі, що і B. Я хотів отримати файл від A до C і scp -3 вирішив це блискуче.
Джо

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

8

Майже все вже було сказано, але ось моя остання копійка: я використовую варіант ProxyCommand без ncnor soc. На основі OpenSSH проксі та кулінарної книги Jumphost я створив таку конфігурацію:

  1. Отже, у нас є такі гравці:

    • HOME_HOST: саме звідси ми копіюємо файл на цільовий хост
    • HOP_HOST: ми копіюємо через цей хост (увійшли як HOP_USER)
    • TARGET_HOST: це наше призначення (засвідчено як TARGET_USER)
  2. По- перше , я додав свій місцевий відкритий ключ від мого будинку господаря , .ssh/id_dsa.pub щоб .ssh/authorized_keysна обох хмелю і цільових хостів. Так, той самий відкритий ключ від домашнього господаря для обох. Зазвичай ви можете очікувати, що це відкритий ключ HOP, який ви повинні додати до цільового.

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

Відповідь ProxyCommand Grawity працювала на мене, але, оскільки я менш знайомий з SSH, знадобилося деяке експериментування. Я думав, що я просто викладу відповідь Grawity більш детально, щоб допомогти будь-яким іншим новачкам в 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(Server C). Але щоб дістатися до нього, потрібно спочатку увійти на сервер з IP-адресою 0.0.1.1з обліковим записом користувача foo(Server 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.