Как мне сделать Multihop SCP переводы?

85

Я хочу скопировать файл со своего компьютера A на сервер C, но у меня есть доступ только к серверу C через сервер B.

Вместо того, чтобы сначала передавать на сервер B, войти в систему, а затем передать на сервер C, возможна ли передача файла напрямую с помощью SCP или аналогичных программ?

(Emacs tramp-mode имеет эту функцию для удаленного редактирования файлов).

sverrejoh
источник

Ответы:

48

Вы можете добавить -oпараметры scpвместо .ssh/config.

scp -o ProxyCommand="ssh $jump_host nc $host 22" $local_path $host:$destination_path

$jump_host это ваш "сервер B" в этом случае.

Джон Тантало
источник
Это мой любимый способ сделать это. Неразбериха с .ssh / config для многопоточности не является лучшим решением, если вы обращаетесь к одному и тому же хосту либо через шлюз, либо напрямую.
GabrieleV
Как это будет с разными / нестандартными именами пользователей и портами?
Пабло А
Я пытаюсь это и должен ввести пароль. Как я могу это исправить. Благодарю.
HQT
44

Предполагая OpenSSH, добавьте к вашей конфигурации SSH в .ssh / config

Host distant
ProxyCommand ssh near nc distant 22

Это приведет к тому, что SSH сможет подключаться «напрямую» к машине с именем distant через прокси через машину с именем near. Затем он может использовать такие приложения, как scp и sftp для удаленной машины.

Чтобы это работало, вам нужно установить на компьютере с именем «nc» «nc», или «netcat». Но многие современные системы уже будут иметь это.

Решение tar для taro более эффективно для однократных задач, если вы запомнили синтаксис и правила работы tar.

tialaramex
источник
Это тот же метод, который я использую ... В этом примере «удаленный» будет сервер C, а «рядом» будет сервер B для разъяснения ...
Джереми Буз
На многих современных машинах нет nc: обычно он доступен только для машин Linux и только по запросу (не входит в стандартную установку).
Мэй
1
У ssh теперь есть опция -W, которая делает это автоматически без 'nc', но мне интересно, почему нет scp -W
kubanczyk
3
В случае, если я не единственный, кому это было неочевидно: если имя пользователя вкл nearотличается от имени пользователя вкл distant, ближайший пользователь переходит в ProxyCommand ssh nearuser@near..., а удаленный пользователь переходит в отдельную User distantuserстроку.
Mu Mind
Просто наберите ssh multi hope и нажмите Google. Я чувствую себя счастливчиком
чанданк
19

С более свежими версиями ssh на сервере рядом с (B) машиной без netcat будет работать следующее:

Host distant
    ProxyCommand ssh near -W distant:22

Однако для этого потребуется, чтобы значение AllowTcpForwarding было равно yes (по умолчанию) на ближнем (B) компьютере.

редактировать: требуется OpenSSH 5.4+ на B

danblack
источник
работает как очарование :)
gongzhitaao
1
А что касается OpenSSH 7.4p1, по крайней мере, есть команда «ProxyJump», в которой нужно только перечислить каждый порт user @ host:, разделенный запятыми. Приятно!
hmijail
ProxyJump хорош, но он не взял User и IdentityFile из файла конфигурации. ProxyCommand -W делает это, а также работает с scp.
rickfoosusa
18

Вы можете SSH к серверу B, используя что-то вроде

ssh -L 5022:<server C IP>:22 <user_serverB>@<server B IP>

Затем вы можете SSH к серверу C с помощью

ssh -p 5022 <user_serverC>@localhost 

Точно так же scp будет работать с использованием

scp -P 5022 foo.txt <user_serverc>@localhost:

Не забудьте использовать правильный регистр p с scp и ssh

Саураб Баржатия
источник
5

Это возможно и относительно просто, даже если вам нужно использовать сертификаты для аутентификации (типично для сред AWS).

Команда ниже будет копировать файлы из remotePathна server2непосредственно в вашу машину в localPath. Внутренне запрос scp передается через server1.

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Другой способ также работает (загрузить файл):

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" <localpath> user2@server2:/<remotePath>

Если вместо этого вы используете аутентификацию по паролю, попробуйте

scp -o ProxyCommand="ssh -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Если вы используете одинаковые учетные данные пользователя на обоих серверах:

scp -o ProxyCommand="ssh -W %h:%p commonuser@server1" commonuser@server2:/<remotePath> <localpath>
donhector
источник
3

Если вы хотите быть по-настоящему злым, вы можете связать ssh и tar, что-то вроде этого tar c mydir | ssh server "ssh otherserver | tar x", но это может столкнуться со всеми проблемами.

Более простым способом было бы просто установить SSH-туннель с помощью встроенных методов SSH; посмотрите на -Dпереключатель в man-странице и просто перенаправьте какой-нибудь порт на ssh-порт другого сервера.

towo
источник
2

Вы также можете сделать это в обратном порядке, и это может быть проще.

Предположим, у вас открыт сеанс ssh с машиной, на которую вы хотите отправить файл. Этот ПК с самым дальним прыжком, мы назовем это hop2. Ваш "прокси" хост будет hop1. ПК, который является источником файла, мы назовем этот источник.

origin:~/asdf.txt  --> hop1 --> hop2:~/asdf.txt

Вы можете строить туннели, делая локальный порт доступным на удаленном ПК. Таким образом, мы определяем порт, который будет открыт на удаленном ПК, который будет перенаправлять на порт, который вы перенаправили с собой, когда строили туннель.

На хопе 2:

ssh -R 5555:127.0.0.1:22 <hop1_user>@<hop1_IP>
#this has the effect of building a tunnel from hop2 to hop1, making hop2's port 22 available on hop1 as port 5555

Теперь в этом открытом сеансе туннеля вы можете сделать то же самое с hop1 до file_origin.

На прыжке 1:

ssh -R 6666:127.0.0.1:5555 <origin_user>@<origin_IP>
#this has the effect of building a tunnel from hop1 to origin while also pulling the active tunnel with it, making hop1's port 5555 (hop2's port 22) available on origin as port 6666.

Вы теперь туннелированы с hop2 на hop1 к источнику. По совпадению, теперь оба порта 5555 и 6666 открыты на источнике, которые перенаправляют на порт 22 hop2. В этом сеансе оба из следующих допустимых маршрутов scp к hop2:

По происхождению:

scp -P 6666 ~/asdf.txt <hop2_user>@<127.0.0.1>:~/asdf.txt

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

SYANiDE
источник
1

Попробуйте адаптировать следующий пример конфигурации openssh для настройки, которую можно использовать для нескольких хостов:

Host uat-*
     ProxyCommand ssh bastion-uat nc %h %p

Это предполагает набор серверов, начинающихся с «uat-», которые доступны только через сервер Jumpbox / Gateway «bastion-uat». Вы, вероятно, также хотите добавить, ForwardAgent yesесли вы используете ключ для входа в систему.

Бенджамин Гудэйкр
источник
Не используйте ForwardAgent yesдля этого. В этом случае переадресация агента не требуется, поскольку на бастионе не будет запущен ssh-клиент, а переадресация агента, когда он не нужен, просто снизит безопасность. И я думаю, что sshотсутствует в вашей команде. Если используется последняя sshверсия, которая вам не нужна nc, вы можете ввести ssh -W %h:%p bastion-uatвместо нее.
Касперд
@kasperd Отредактировано, чтобы включить ssh. Re ForwardAgent; ssh клиент будет запущен для запуска самой команды nc. Возможно, вы имеете в виду оболочку?
Бенджамин Гудэйк
1

Это не scp (который запрашивал OP), но я обнаружил, что его очень просто использовать rsyncдля копирования с локального на удаленное через один прыжок с помощью:

rsync -v -e 'ssh -A -t user@jumpserver ssh -A -t user@destinationserver' /path/to/sourcefile :/path/to/destination

Источник: http://mjbright.blogspot.com/2012/09/using-rsync-over-multi-hop-ssh.html

Я попробовал предложенное выше -o ProxyPass и не хотел менять конфигурацию для меняющихся потребностей. Как указывает автор в приведенной выше ссылке, целевой файл, предшествующий двоеточию (:), важен для указания того, что указанный путь находится на целевом сервере. Кроме того, используя rsync, у вас есть опции сравнения дат, синхронизации папок и т. Д. Надеюсь, это кому-нибудь поможет!

техасский-Bronius
источник
-2

scp -o 'ProxyJump jumpboxname' somefilename.txt finaldestinationhost: / tmp /.

Я и
источник
3
Не просто сбросьте здесь немного необъяснимого кода. Есть много хороших ответов на этот вопрос, и вам нужно добавить ценность к уже существующим - это не так.
Свен