如何使用第二台远程主机进行 scp

我想知道是否有一种方法可以直接从本地机器通过 Remote1主机从 Remote2主机 SCP 文件。

网络只允许从 Remote1主机连接到 Remote2主机。而且,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上改变什么?

100775 次浏览

I don't know of any way to copy the file directly in one single command, but if you can concede to running an SSH instance in the background to just keep a port forwarding tunnel open, then you could copy the file in one command.

Like this:

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

Note that you connect as user2@localhost in the actual scp command, because it is on port 1234 on localhost that the first ssh instance is listening to forward connections to remote2. Note also that you don't need to run the first command for every subsequent file copy; you can simply leave it running.

Double ssh

Even in your complex case, you can handle file transfer using a single command line, simply with ssh ;-)
And this is useful if remote1 cannot connect to localhost:

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

tar

But you loose file properties (ownership, permissions...).

However, tar is your friend to keep these file properties:

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

You can also compress to reduce network bandwidth:

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

And tar also allows you transferring a recursive directory through basic ssh:

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

ionice

If the file is huge and you do not want to disturb other important network applications, you may miss network throughput limitation provided by scp and rsync tools (e.g. scp -l 1024 user@remote:file does not use more than 1 Mbits/second).

But, a workaround is using ionice to keep a single command line:

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

Note: ionice may not be available on old distributions.

This will do the trick:

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

To SCP the file from the host remote2 directly, add the two options (Host and ProxyCommand) to your ~/.ssh/config file (see also this answer on superuser). Then you can run:

scp user@remote2:path/to/file .

from your local machine without having to think about remote1.

With openssh version 7.3 and up it is easy. Use ProxyJump option in the config file.

# 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

Commands to run to login or copy

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

ofcourse you can specify bastion Jump host using option "-J" to ssh command, if not configured in config file.

Note scp does not seems to support "-J" flag as of now. (i could not find in man pages. However above scp works with config file setting)

This configuration works nice for me:

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

Then the command

scp myfile production:~

Copies myfile to production machine.

There is a new option in scp that add recently for exactly this same job that is very convenient, it is -3.

TL;DR For the current host that has authentication already set up in ssh config files, just do:

scp -3 remote1:file remote2:file

Your scp must be from recent versions.

All other mentioned technique requires you to set up authentication from remote1 to remote2 or vice versa, which not always is a good idea.
Argument -3 means you want to move files from two remote hosts by using current host as intermediary, and this host actually does the authentication to both remote hosts, so they don't have to have access to each other.
You just have to setup authentication in ssh config files, which is fairly easy and well documented, and then just run the command in TL;DR

The source for this answer is https://superuser.com/a/686527/713762

a simpler way:

scp -o 'ProxyJump your.jump.host' /local/dir/myfile.txt remote.internal.host:/remote/dir