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


82

我想知道是否有一种方法可以让我通过本地主机从本地计算机直接从本地主机从SCP主机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

Answers:


94

我不知道有任何一种方法可以直接在一个命令中直接复制文件,但是如果您可以允许在后台运行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命令进行连接,因为第一个ssh实例在localhost的端口1234上侦听到的转发连接remote2。另请注意,您无需为每个后续文件副本都运行第一个命令。您可以简单地使其运行。


1
谢谢,这似乎接近我的需要。因此,我创建了隧道,指纹与服务器之一匹配,但是出现了“拒绝拒绝(公钥)”错误。我想我要问我的网络/系统管理员为什么不起作用。
Danosaure '02

3
谢谢!我不得不改变-p 45678-p 22我的REMOTE1 SSH监听端口22
Montaro

我还不得不使用-p 22代替-p 45678。也scp -P 1234 ...对我不起作用。我越来越ssh: connect to host localhost port 1234: Connection refused。当我尝试使用scp -P 22 ...它时,它可以复制文件,remote 1而不是在本地计算机(remote2)上。
罪人

是否有任何相同的UI工具?
探索

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

如果文件很大,并且您不想打扰其他重要的网络应用程序,则可能会错过网络吞吐量限制scprsync工具提供的(例如scp -l 1024 user@remote:file,使用的速度不超过1 Mbit / s)。

但是,一种解决方法是使用 ionice保留单个命令行:

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

注意:ionice在旧发行版中可能不可用。


感谢所有描述,但我认为Dolda2000的解决方案更容易。这是我正在尝试的方法,但无法弄清楚。
Danosaure '02

5
这是一个非常好的答案,值得更多投票。在我看来,这比接受的答案要容易得多。
里克·史密斯·翁纳

2
我同意这是一个比公认的答案更好的解决方案。这样,连接将自动清除。
道格

谢谢,很好的回答!从本地复制到远程的另一种方式呢?
DomTomCat

31

这将达到目的:

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

remote2直接从主机SCP文件,请将两个选项(HostProxyCommand)添加到〜/ .ssh / config文件中(另请参见超级用户的答案)。然后,您可以运行:

scp user@remote2:path/to/file .

从您的本地计算机上不必考虑remote1


不错的方法!虽然-o 'Host remote2'从命令行启动时似乎并不是真正需要的(例如,无需触摸〜/ .ssh / config即可复制一次)
Mike

同样在这里。这对我没有作用-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.** 

当然,如果未在配置文件中配置,则可以使用选项“ -J”向ssh命令指定堡垒跳转主机。

注意到目前为止,scp似乎还不支持“ -J”标志。(我在手册页中找不到。但是上面的scp可用于配置文件设置)


1
如果仅将堡垒服务器用于配置(即没有其他IdentityFile等),则无需将堡垒服务器添加到配置文件中,只需将ProxyJump bastion.client.com添加到appMachine部分。
Tomer Cohen

1

scp最近有一个新的选项可为完全相同的工作添加,非常方便-3

TL; DR对于已在ssh配置文件中设置了身份验证的当前主机,请执行以下操作:

scp -3 remote1:file remote2:file

scp必须使用最新版本。

所有其他提到的技术都要求您设置从remote1到remote2的身份验证,反之亦然,这并不是一个好主意。
参数-3意味着您要通过使用当前主机作为中介从两个远程主机移动文件,并且该主机实际上对两个远程主机都进行了身份验证,因此它们不必相互访问。
您只需要在ssh配置文件中设置身份验证即可,这很容易且有据可查,然后只需在TL; DR中运行命令即可。

该答案的来源是https://superuser.com/a/686527/713762


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复制到生产计算机。


0

这里是Olibre解决方案的少量补充,我使用源代码进行了处理。

就像您有三种tar用于从远程主机复制到本地的方法一样,以下方法在双ssh情况下也适用于本地主机到远程主机的复制:(必须从中复制文件的目录中运行它们,否则请使用fullpath /文件名)

传输单个文件而不进行压缩:

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"'

如果命令的前半部分不起作用,例如,如果目录丢失或源/目标路径名错误,则&&阻止命令运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.