Я хочу скопировать файл со своей машины A на сервер C, но имею доступ только к серверу C через сервер B.
Вместо того, чтобы сначала передавать на сервер B, войдите в систему и затем перенесите на сервер C. Можно ли передать файл напрямую с помощью SCP или аналогичных программ?
(В Emacs tramp-mode есть эта функция для удаленного редактирования файлов).
Можете добавить -o
варианты для scp
вместо того .ssh/config
.
scp -o ProxyCommand="ssh $jump_host nc $host 22" $local_path $host:$destination_path
$jump_host
в данном случае ваш "сервер Б".
Предполагая OpenSSH, добавьте в конфигурацию SSH в .ssh / config
Host distant
ProxyCommand ssh near nc distant 22
Это приведет к тому, что SSH сможет подключиться «напрямую» к машине с именем distant путем проксирования через машину с именем near. Затем он может использовать такие приложения, как scp и sftp, для удаленного компьютера.
Чтобы это работало, вам нужно, чтобы на машине с именем near был установлен «nc» или netcat. Но он уже есть во многих современных системах.
Решение с tar более эффективно для одноразовых задач, если вы запомнили синтаксис tar и правила работы.
С более свежими версиями ssh на сервере рядом с машиной (B) без netcat будет работать следующее:
Host distant
ProxyCommand ssh near -W distant:22
Однако для этого потребуется, чтобы AllowTcpForwarding было да (по умолчанию) на ближайшем (B) компьютере.
изменить: требуется OpenSSH 5.4+ на B
Вы можете 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
Это возможно и относительно просто, даже если вам нужно использовать сертификаты для аутентификации (обычно в средах 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>
Если вы хотите быть действительно злым, вы можете связать ssh и tar, что-то вроде tar c mydir | ssh server "ssh otherserver | tar x"
, но это может вызвать проблемы.
Более простым способом было бы просто настроить SSH-туннель с помощью встроенных методов SSH; посмотри на -D
переключитесь на странице руководства и просто перенаправьте какой-то порт на ssh-порт другого сервера.
Вы также можете сделать это в обратном порядке, что может быть проще.
Предположим, у вас открыт сеанс ssh с машиной, на которую вы хотите отправить файл. Этот ПК с самым дальним переходом мы назовем его hop2. Ваш "прокси" хост будет hop1. ПК, который является источником файла, мы назовем его источником.
origin:~/asdf.txt --> hop1 --> hop2:~/asdf.txt
Вы можете строить туннели, делая локальный порт доступным на удаленном ПК. Таким образом, мы определяем порт для открытия на удаленном ПК, который будет перенаправлением на порт, который вы перенаправили с собой при построении туннеля.
На hop2:
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.
На hop1:
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
Таким образом, у вас может быть произвольное количество переходов между ними, и с ним легче работать с точки зрения объединения более двух переходов.
Попробуйте адаптировать следующий пример конфигурации openssh для настройки, которая может использоваться для нескольких хостов:
Host uat-*
ProxyCommand ssh bastion-uat nc %h %p
Это предполагает набор серверов, начинающихся с «uat-», которые доступны только через сервер jumpbox / gateway «bastion-uat». Вы, вероятно, также захотите добавить ForwardAgent yes
если вы используете ключ для входа в систему.
Это не 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 у вас есть возможности сравнения дат, синхронизации папок и т. Д. Надеюсь, это кому-то поможет!
scp -o 'ProxyJump jumpboxname' somefilename.txt finaldestinationhost: / tmp /.