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

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

(Emacs tramp模式具有用于远程编辑文件的功能)。

#1 楼

您可以在-o而不是scp上添加.ssh/config选项。

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


$jump_host是您的“服务器B”。

评论


这是我这样做的首选方式。如果您从网关直接访问同一主机,则搞混.ssh / config进行多跳并不是最好的解决方案。

–GabrieleV
11年8月26日在22:57

不同/自定义用户名和端口的情况如何?

– Pablo A
18年8月27日在20:33

我尝试此操作,必须输入密码。我怎样才能解决这个问题。谢谢。

– hqt
19年7月1日在20:38

在我的情况下,借助于此信息stackoverflow.com/questions/22635613/…,另一个选项起作用了:scp -o ProxyCommand =“ ssh $ jump_host -W $ host:22” $ local_path $ host:$ destination_path

–阿斯卡·卡里科夫(Askar Kalykov)
20年8月17日在13:05

#2 楼

假设使用OpenSSH,请在.ssh / config

Host distant
ProxyCommand ssh near nc distant 22


中添加到您的SSH配置,这将使SSH能够通过代理通过“直接”连接到名为distant的计算机机器命名为near。然后,它可以使用诸如scp和sftp之类的应用程序到远程计算机。

要使其正常工作,您需要在名为near的计算机上安装“ nc” aka netcat。但是许多现代系统已经具备了它。

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

评论


这与我使用的方法相同。在此示例中,“ distant”将是服务器C,而“ near”将是服务器B以进行澄清...

– Jeremy Bouse
09年7月8日在13:19

许多现代机器没有'nc':通常仅对Linux机器可用,并且仅应要求提供(不是标准安装的一部分)。

–美
09年7月8日在14:32

ssh现在具有-W选项,该选项无需'nc'即可自动执行此操作,但是我想知道为什么没有scp -W

– Kubanczyk
2011-12-04 11:13

如果我不是唯一的一个,这不是显而易见的:如果Near上的用户名与distant上的用户名不同,则Near用户进入ProxyCommand ssh nearuser @ near ...,而远程用户进入单独的用户distantuser行。

– Mu Mind
2012年2月18日在4:30

只需输入ssh multi hope并按Google,我感到很幸运

– chandank
13年3月20日在1:15

#3 楼

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

编辑:在B上需要OpenSSH 5.4+

评论


奇迹般有效 :)

–恭子ita
2013年9月19日下午4:32

至少从OpenSSH 7.4p1开始,有一个“ ProxyJump”命令,其中仅需列出每个用逗号分隔的user @ host:port。真好!

–hmijail哀悼辞职者
17年8月21日在13:32

ProxyJump很不错,但是它没有从配置文件中获取User和IdentityFile。 ProxyCommand -W可以执行此操作,并且还可以与scp一起使用。

– rickfoosusa
18年6月18日在17:12

#4 楼

您可以使用诸如

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


SSH到服务器B,然后您可以使用

ssh -p 5022 <user_serverC>@localhost 
SSH到服务器C。 >类似地,scp可以使用

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


记住要在scp和ssh中使用正确的p大小写

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

-W选项内置于OpenSSH的新(旧)版本中,因此仅适用于具有以下功能的计算机:最低版本(5.4,除非发行版向后移植了任何功能;例如,RHEL6 OpenSSH 5.3p1包含此功能)。根据发行说明:http://www.openssh.com/txt/release-5.4

在ssh(1)中添加了“ netcat模式”:“ ssh -W host:port ... “这会将客户端上的stdio连接到服务器上的单个端口转发。例如,这允许使用ssh作为ProxyCommand通过中间服务器路由连接。

%h%p是主机和端口的占位符。

评论


为-W,%h:%p添加的说明将使该帖子对像我这样的初学者更加有用。 @donhector

– AATHITH RAJENDRAN
20-10-19在10:12

#6 楼

如果您想变得真正邪恶,可以将ssh和tar链接起来,例如tar c mydir | ssh server "ssh otherserver | tar x",但这会遇到很多问题。

更简单的方法是使用以下方法建立SSH隧道: SSH的内置方法;查看联机帮助中的-D开关,然后将一些端口转发到另一台服务器的ssh端口。

#7 楼

您也可以反向执行此操作,它可能会更容易。

假设您已将要发送文件的计算机打开了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


这样,您可以在它们之间具有任意数量的跃点,并且在将两个以上的跃点链接在一起时更容易使用。

#8 楼

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

#9 楼

尝试使以下示例openssh config适用于可用于多个主机的安装程序:仅可通过Jumpbox /网关服务器“ bastion-uat”访问。如果您使用密钥登录,可能还需要添加ForwardAgent yes

评论


请勿为此使用ForwardAgent yes。在这种情况下,不需要代理转发,因为没有ssh客户端将在该堡垒上运行,而在不需要代理时转发代理只是为了降低安全性。而且我认为您的命令中缺少ssh。如果使用的是最新的ssh版本,则不需要nc,而可以键入ssh -W%h:%p bastion-uat。

–卡巴斯德
2014年6月25日12:10

@kasperd编辑为包含ssh。重新转发代理; ssh客户端将运行以运行nc命令本身。也许您指的是外壳?

–本杰明·古德克雷(Benjamin Goodacre)
2014年6月25日12:55



#10 楼

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

评论


不要在这里转储一些无法解释的代码。这个问题有很多不错的答案,您需要为现有的答案增加价值-事实并非如此。

– Sven
18年11月14日在13:57