题 我如何进行Multihop SCP传输?


我想将文件从我的机器A复制到服务器C,但只能通过服务器B访问服务器C.

而不是先转移到服务器B,登录然后转移到服务器C,是否可以直接用SCP或类似程序传输文件?

(Emacs tramp-mode具有远程编辑文件的功能)。


76
2017-07-08 12:09






答案:


假设OpenSSH,请在.ssh / config中添加SSH配置

Host distant
ProxyCommand ssh near nc distant 22

这将使SSH能够通过名为near的机器代理“直接”连接到名为remote的机器。然后它可以使用scp和sftp等应用程序到远程机器上。

为此,您需要在名为near的机器上安装'nc',即netcat。但是很多现代系统已经拥有它。

假设你已经记住了tar的语法和操作规则,那么towo的tar解决方案对于一次性问题更有效。


43
2017-07-08 12:25



这与我使用的方法相同......在这个例子中,'remote'将是服务器C,'near'将是服务器B以便澄清...... - Jeremy Bouse
很多现代机器都没有'nc':它通常只适用于Linux机器,只能通过请求(不是标准安装的一部分)。 - Mei
ssh现在有-W选项,自动执行此操作而没有'nc',但我想知道为什么没有scp -W - kubanczyk
如果我不是唯一一个这不明显的:如果用户名上 near 与用户名不同 distant,近用户进入 ProxyCommand ssh nearuser@near...,和远方的用户分开了 User distantuser 线。 - Mu Mind
只需键入ssh multi hope并按Google即可,我感到很幸运 - chandank


你可以加 -o 选项 scp 代替 .ssh/config

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

$jump_host 在这种情况下是你的“服务器B”。


41
2018-01-11 17:30



这是我的首选方式。如果您从网关直接访问同一主机,那么将多跳的.ssh / config弄乱并不是最好的解决方案。 - GabrieleV
伟大的片段......谢谢...... - Paul T.
如何使用不同的/自定义用户名和端口? - Pablo Bianchi


在(B)机器附近的服务器上使用更新版本的ssh,以下将在没有netcat的情况下工作:

Host distant
    ProxyCommand ssh near -W distant:22

但是,它需要AllowTcpForwarding在near(B)机器上为yes(默认值)

编辑:要求B上的OpenSSH 5.4+


19
2018-03-20 01:04



奇迹般有效 :) - gongzhitaao
至少从OpenSSH 7.4p1开始,有一个“ProxyJump”命令,其中只需要列出用逗号分隔的每个用户@ host:port。太好了! - hmijail
ProxyJump很不错,但它没有从配置文件中获取User和IdentityFile。 ProxyCommand -W执行此操作并且也适用于scp。 - rickfoosusa


您可以使用类似的东西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:

记得使用scp和ssh使用正确的p


15
2017-07-08 13:02





如果你想变得非常邪恶,你可以链接ssh和tar,就像这样 tar c mydir | ssh server "ssh otherserver | tar x",但这可能会遇到所有问题。

更简单的方法是使用SSH的内置方法建立SSH隧道;看着那(这 -D 在手册页中切换,然后将某个端口转发到另一个服务器的ssh端口。


3
2017-07-08 12:16





即使您需要使用证书进行身份验证(在AWS环境中很常见),这也是可能且相对简单的。

下面的命令将从a复制文件 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>

2
2017-10-08 01:24





你也可以反过来做,也许更容易。

假设您在要将文件发送到的计算机上打开了ssh会话。这个最跳跃的PC,我们称之为hop2。您的“代理”主机将是hop1。作为文件来源的PC,我们称之为原点。

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

您可以构建隧道,使远程PC上的本地端口可用。因此,我们定义了一个在远程PC上打开的端口,该端口将重定向到您在构建隧道时随身携带的端口。

在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都是开源的,它们被重定向到hop2的端口22.在这个会话中,以下两个都是到hop2的有效scp路由:

原产地:

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

通过这种方式,您可以在两者之间有一些任意数量的跃点,并且在将两个以上的跃点链接在一起方面更容易使用。


2
2017-11-18 20:22





尝试使用以下示例openssh config进行可用于多个主机的设置:

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

这假设一组以“uat-”开头的服务器只能通过跳转盒/网关服务器“bastion-uat”访问。您可能还想添加 ForwardAgent yes 如果您使用密钥登录。


1
2018-06-25 10:33



不要用 ForwardAgent yes 为了这。在这种情况下不需要代理转发,因为没有ssh客户端将在堡垒上运行,并且在不需要时转发代理只会降低安全性。我想 ssh 您的命令中缺少。如果是最近的 ssh 正在使用你不需要的版本 nc,你可以输入 ssh -W %h:%p bastion-uat 代替。 - kasperd
@kasperd编辑包含ssh。 Re ForwardAgent;将运行ssh客户端以运行nc命令本身。也许你指的是shell? - Benjamin Goodacre


这不是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,您可以选择日期比较,文件夹同步等。我希望这有助于某人!


1
2017-12-21 17:07