Как настроить scp со вторым удаленным хостом

83

Интересно, есть ли у меня способ SCP файл с хоста remote2 непосредственно с моего локального компьютера, пройдя через хост remote1.

Сети разрешают подключения к хосту remote2 только с хоста remote1. Кроме того, ни хост remote1, ни хост remote2 не могут подключиться к моему локальному компьютеру по scp.

Есть что-то вроде:

scp user1@remote1:user2@remote2:file .

Первое окно:, ssh remote1затем scp remot2:file ..

Вторая оболочка: scp remote1:file .

Первое окно: rm file; logout

Я мог бы написать сценарий для выполнения всех этих шагов, но если есть прямой способ, я бы предпочел его использовать.

Благодарю.

РЕДАКТИРОВАТЬ: Я думаю о чем-то вроде открытия туннелей SSH, но я не понимаю, какое значение куда поместить.

На данный момент для доступа у remote1меня $HOME/.ssh/configна локальной машине есть следующее .

Host remote1
   User     user1
   Hostname localhost
   Port     45678

После включения remote1для доступа remote2используется стандартный локальный DNS и порт 22. Что мне надеть remote1и / или изменить localhost?

Danosaure
источник

Ответы:

95

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

Как это:

# First, open the tunnel
ssh -L 1234:remote2:22 -p 45678 user1@remote1
# Then, use the tunnel to copy the file directly from remote2
scp -P 1234 user2@localhost:file .

Обратите внимание, что вы подключаетесь, как user2@localhostв реальной scpкоманде, потому что это порт 1234 на локальном хосте, который первый sshэкземпляр прослушивает для пересылки подключений remote2. Также обратите внимание, что вам не нужно запускать первую команду для каждой последующей копии файла; вы можете просто оставить его включенным.

Долда2000
источник
1
Спасибо, похоже, это почти то, что мне нужно. Итак, я создал туннель, отпечаток пальца совпадает с отпечатком сервера, но у меня есть ошибка «Permision denied (publickey)». Я думаю, мне нужно спросить мою сеть / системного администратора, почему он не работает.
Danosaure
3
Благодаря! Мне пришлось изменить его -p 45678на -p 22SSH remote1, который прослушивает порт 22
Montaro
Мне тоже пришлось использовать -p 22вместо -p 45678. У scp -P 1234 ...меня тоже не работает. Я получаю ssh: connect to host localhost port 1234: Connection refused. Когда я попробовал, scp -P 22 ...он работает, но он копирует файл, remote 1а не на мою локальную машину ( remote2).
грешник
Любой инструмент пользовательского интерфейса для того же?
ExploringApple
70

Двойной ssh

Даже в вашем сложном случае вы можете обрабатывать передачу файлов с помощью одной командной строки, просто с помощью ssh;-)
И это полезно, если remote1не удается подключиться к localhost:

ssh user1@remote1 'ssh user2@remote2 "cat file"' > file

tar

Но вы теряете свойства файла (право собственности, разрешения ...).

Тем не менее, tarваш друг, чтобы сохранить эти свойства файла:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar c file"' | tar x

Вы также можете сжать, чтобы уменьшить пропускную способность сети:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj file"' | tar xj

А tarтакже позволяет передавать рекурсивный каталог через базовый ssh:

ssh user1@remote1 'ssh user2@remote2 "cd path2; tar cj ."' | tar xj

ionice

Если файл огромен , и вы не хотите беспокоить другие важные сетевые приложения, вы можете пропустить сеть пропускного ограничения предоставляемого scpи rsyncинструменты (например , scp -l 1024 user@remote:fileне использует более 1 Мбит / секунду).

Но ioniceдля сохранения единой командной строки используется обходной путь :

ionice -c2 -n7 ssh u1@remote1 'ionice -c2 -n7 ssh u2@remote2 "cat file"' > file

Примечание: ioniceможет быть недоступно в старых дистрибутивах.

oHo
источник
Спасибо за все описание, но я думаю, что решение Dolda2000 проще. Это было то, что я пытался, но не мог понять.
Danosaure
5
Это потрясающе хороший ответ и заслуживает большего количества голосов. На мой взгляд, это намного проще, чем принятый ответ.
Рик Смит-Унна
2
Я согласен, что это лучшее решение, чем принятый ответ. Таким образом, соединение автоматически очищается.
Дуг
Спасибо, очень хороший ответ! Как насчет обратного копирования с локального на удаленный?
DomTomCat
31

Это поможет:

scp -o 'Host remote2' -o 'ProxyCommand ssh user@remote1 nc %h %p' \ 
    user@remote2:path/to/file .

Чтобы SCP файл remote2напрямую с хоста , добавьте две опции ( Hostи ProxyCommand) в ваш файл ~ / .ssh / config (см. Также этот ответ о суперпользователе). Тогда вы можете запустить:

scp user@remote2:path/to/file .

с вашего локального компьютера, не думая об этом remote1.

Джон Манак
источник
Хороший подход! Хотя -o 'Host remote2', похоже, это не требуется при запуске из командной строки (т.е. для однократного копирования, не касаясь ~ / .ssh / config)
Майк,
Тоже самое. У меня это работает без -o 'Host remote2'. Благодарю.
грешник
7

С openssh версии 7.3 и выше это легко. Используйте параметр ProxyJump в файле конфигурации.

# Add to ~/.ssh/config 
Host bastion
    Hostname bastion.client.com
    User userForBastion
    IdentityFile ~/.ssh/bastion.pem

Host appMachine
    Hostname appMachine.internal.com
    User bastion
    ProxyJump bastion                   # openssh 7.3 version new feature ProxyJump
    IdentityFile ~/.ssh/appMachine.pem. #no need to copy pem file to bastion host  

Команды для запуска для входа в систему или копирования

ssh appMachine   # no need to specify any tunnel. 
scp helloWorld.txt appMachine:.   # copy without intermediate jumphost/bastion host copy.** 

Конечно, вы можете указать хост бастиона Jump, используя опцию "-J" для команды ssh, если это не указано в файле конфигурации.

Обратите внимание, что на данный момент scp , похоже, не поддерживает флаг «-J». (я не смог найти на страницах руководства. Однако вышеупомянутый scp работает с настройкой файла конфигурации)

user3851404
источник
1
Нет необходимости добавлять сервер-бастион в файл конфигурации, если он используется только для проксирования (т.е. нет другого файла IdentityFile и т. Д.), Просто добавьте ProxyJump bastion.client.com в раздел appMachine.
Томер Коэн
1

В том, scpчто недавно добавили, есть новая опция для точно такой же работы, что очень удобно, это так -3.

TL; DR Для текущего хоста, для которого аутентификация уже настроена в файлах конфигурации ssh, просто выполните:

scp -3 remote1:file remote2:file

Вы scpдолжны быть из последних версий.

Все остальные упомянутые методы требуют, чтобы вы настроили аутентификацию с удаленного1 на удаленный2 или наоборот, что не всегда является хорошей идеей.
Аргумент -3означает, что вы хотите переместить файлы с двух удаленных хостов, используя текущий хост в качестве посредника, и этот хост фактически выполняет аутентификацию для обоих удаленных хостов, поэтому им не нужно иметь доступ друг к другу.
Вам просто нужно настроить аутентификацию в файлах конфигурации ssh, что довольно просто и хорошо документировано, а затем просто запустить команду на TL; DR

Источник этого ответа: https://superuser.com/a/686527/713762

FazeL
источник
0

Эта конфигурация мне нравится:

Host jump
   User username
   Hostname jumphost.yourorg.intranet
Host production
   User username
   Hostname production.yourorg.intranet
   ProxyCommand ssh -q -W %h:%p jump

Тогда команда

scp myfile production:~

Копии Myfile для производства машины.

Anydoby
источник
0

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

Так же, как у вас есть три способа tarкопирования с удаленного хоста на локальный, для копирования с локального хоста на удаленный хост в ситуациях двойного ssh работает следующее: (запустите их в каталоге, из которого должны быть скопированы файлы, в противном случае используйте полный путь /имя файла)

Передача одного файла без сжатия:

tar c filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar x"'

Передача одного файла со сжатием:

tar cj filename |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

Рекурсивный перенос каталога:

tar cj . |  ssh user1@remote1 'ssh -Y user2@remote2 "path2 && tar xj"'

Здесь && предотвращает запуск команды, если первая половина команды не работает - например, если каталог отсутствует или есть ошибка в именах пути источника / назначения.

Апарна
источник