如何进行多跳 SCP 传输?

sve*_*joh 91 ssh scp

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

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

(Emacs tramp-mode 有这个功能可以远程编辑文件)。

小智 53

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

scp -o ProxyCommand="ssh $jump_host nc $host 22" $local_path $host:$destination_path
Run Code Online (Sandbox Code Playgroud)

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

  • 就我而言,借助此信息/sf/ask/1584492941/ Between-ssh-proxycommand-w-nc-exec-nc,另一个选项有效:`scp - o ProxyCommand="ssh $jump_host -W $host:22" $local_path $host:$destination_path` (3认同)

小智 46

假设使用 OpenSSH,在 .ssh/config 中添加到您的 SSH 配置

Host distant
ProxyCommand ssh near nc distant 22
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 如果我不是唯一一个,这不是显而易见的:如果 `near` 上的用户名与 `distant` 上的用户名不同,near 用户进入 `ProxyCommand ssh nearuser@near...`,并且远程用户进入单独的“用户远程用户”行。 (3认同)

dan*_*ack 22

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

Host distant
    ProxyCommand ssh near -W distant:22
Run Code Online (Sandbox Code Playgroud)

然而,它需要 AllowTcpForwarding 在近 (B) 机器上为是(默认值)

编辑:在 B 上需要 OpenSSH 5.4+

  • 至少从 OpenSSH 7.4p1 开始,有一个“ProxyJump”命令,其中只需要列出每个 user@host:port 用逗号分隔。好的! (2认同)

Sau*_*iya 19

您可以使用类似的 SSH 连接到服务器 B

ssh -L 5022:<server C IP>:22 <user_serverB>@<server B IP>
Run Code Online (Sandbox Code Playgroud)

然后你可以使用ssh到服务器C

ssh -p 5022 <user_serverC>@localhost 
Run Code Online (Sandbox Code Playgroud)

同样 scp 可以使用

scp -P 5022 foo.txt <user_serverc>@localhost:
Run Code Online (Sandbox Code Playgroud)

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


don*_*tor 7

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

下面的命令将把从复制文件remotePathserver2直接进入您的机型localPath。在内部,scp 请求通过server1.

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>
Run Code Online (Sandbox Code Playgroud)

另一种方法也适用(上传文件):

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" <localpath> user2@server2:/<remotePath>
Run Code Online (Sandbox Code Playgroud)

如果您改用密码身份验证,请尝试使用

scp -o ProxyCommand="ssh -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>
Run Code Online (Sandbox Code Playgroud)

如果您在两台服务器中使用相同的用户凭据:

scp -o ProxyCommand="ssh -W %h:%p commonuser@server1" commonuser@server2:/<remotePath> <localpath>
Run Code Online (Sandbox Code Playgroud)

-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是主机和端口的占位符。


小智 5

这不是 scp(OP 要求的),但我发现rsync通过单跳从本地复制到远程使用非常简单:

rsync -v -e 'ssh -A -t user@jumpserver ssh -A -t user@destinationserver' /path/to/sourcefile :/path/to/destination
Run Code Online (Sandbox Code Playgroud)

来源:http : //mjbright.blogspot.com/2012/09/using-rsync-over-multi-hop-ssh.html

我已经尝试了上面的 -o ProxyPass 建议,但不想根据我不断变化的需求更改配置。正如上面链接中的作者所说,冒号 (:) 前面的目标文件对于指示指定路径在目标服务器上很重要。此外,使用 rsync,您可以选择日期比较、文件夹同步等。我希望这对某人有所帮助!


tow*_*owo 3

如果你想变得非常邪恶,你可以链接 ssh 和 tar 之类的东西tar c mydir | ssh server "ssh otherserver | tar x",但这可能会遇到各种问题。

更简单的方法是使用 SSH 的内置方法建立 SSH 隧道;查看-D联机帮助页中的交换机,只需将某些端口转发到其他服务器的 ssh 端口。