我们有两个主要的环境:
开发和质量保证
每个环境都有两台服务器:
- 跳箱
- 应用程序服务器
为了连接到应用程序服务器,您必须先连接到跳转盒,然后通过 SSH 连接到应用程序服务器。
防火墙制定了几条规则:
- 您必须通过跳转盒连接到应用服务器
- 应用服务器无法连接到任一跳转盒
- 跳转盒位于同一子网,并且可以相互通信。
我们的问题
我们在 上有大量内容(670 GB)DEVELOPMENT APPLICATION SERVER
,我们需要将其转移到QA APPLICATION SERVER
。
将这些数据复制到跳转框是不可能的,因为它们缺少所需的空间。
我做了一些研究,发现我们可以通过这些服务器建立一系列隧道,这样我们就可以通过隧道将数据从一个应用服务器直接传输到另一个应用服务器。但是,问题是我们无法从应用服务器连接到跳转箱。
我们还有其他选择吗?情况越来越危急,时间至关重要。我们没有时间下载数据并重新上传。通过网络在服务器上复制会很快,因为这是千兆位连接。
答案1
到目前为止,最简单的方法就是通过 scp 进行复制。此外,与其他一些建议不同,这种语法实际上有效。
这种语法非常简便。它允许您以递归方式复制、rsync 或任何您想要的操作,而无需考虑可能复杂的管道。这种语法直观清晰,更容易被跟随您的系统管理员支持,并且不会使猫的无用用途。
scp -3 devappserver:/path/to/copy/from qaappserver:/path/to/copy/to
从scp 手册页:-3
两个远程主机之间的副本通过本地主机传输。如果没有此选项,数据将直接在两个远程主机之间复制。请注意,此选项会禁用进度表。
在下面的例子中
- 您的工作站名为 MacBook-Pro。
- Dev Jump Box 被命名为 devjumpserver
- Dev Application Server 名为 devapplicationserver
- 位于名为 .local 的 LAN DNS 区域
- QA Jump Box 名为 qajumpserver
- QA 应用程序服务器名为 qaapplicationserver
- 位于名为 .local 的 LAN DNZ 区域
- 我们将对 670GB 的 /etc/hosts 文件进行测试复制 ;-)
- 假设您已经配置了 SSH 公钥认证。
这是一个 ~/.ssh/config 文件,它通过适当的跳转(又名堡垒服务器)设置从您的工作站到应用程序服务器的直接访问。
MacBook Pro:〜barrychapman$猫〜/ .ssh /配置 主持人 * 服务器存活间隔 60 托管 devapplicationsever 主机名 devapplicationserver.local 代理命令 ssh -i ~/.ssh/id_rsa[电子邮件保护]-W%h:%p 用户 barrychapman 主机 qaapplicationserver 主机名 qaapplicationserver.local 代理命令 ssh -i ~/.ssh/id_rsa[电子邮件保护]-W%h:%p 用户 barrychapman MacBook Pro:〜barrychapman$
测试目标服务器上文件是否存在,结果文件不存在。
MacBook Pro:〜barrychapman$ssh qaapplicationserver ls /tmp/hosts ls:无法访问 /tmp/hosts:没有此文件或目录 被信号 1 杀死。 MacBook Pro:〜barrychapman$
现在让我们通过您的工作站将文件从 Dev 应用程序服务器复制到 QA 应用程序。
MacBook Pro:〜barrychapman$scp -3 devapplicationserver:/etc/hosts qaapplicationserver:/tmp/ 被信号 1 杀死。 被信号 1 杀死。 MacBook Pro:〜barrychapman$
现在让我们检查 QA 应用服务器上是否存在复制的文件。这次它将在那里。
MacBook Pro:〜barrychapman$ssh qaapplicationserver ls /tmp/hosts /tmp/主机 被信号 1 杀死。 MacBook Pro:〜barrychapman$
笔记
关闭 ProxyCommand 连接时,您将看到警告消息“被信号 1 杀死”。这是 SSH 正在断开 ProxyCommand 连接,无需担心。您可以通过将其添加LogLevel Quiet
到堡垒主机配置节来摆脱它。
答案2
管道!
如果互联网一系列的管子,Unix 是一系列的管道——类似于:
cat ginormous-file | ssh user@host1 "cat | ssh user@host2 \"cat >out\" "
应该管用。
如果需要遍历更多主机,请\
根据需要添加更多管道(以及更多嵌套的 -escaped 引号层)。(但请注意,如果管道/转义变得非常复杂,您必须绘制图表或依靠手指计数确定你需要加倍逃跑的次数也许是时候承认失败并设置一个合适的 VPN 了!)
答案3
如果我理解正确的话,您有两个跳转服务器(jump-qa 和 jump-dev)保护两个应用服务器(app-qa 和 app-dev);跳转服务器可以 ssh 到彼此;除了相关跳转服务器之外,没有其他设备可以 ssh 到相应的应用服务器。应用服务器无法 ssh 到任何人。文件将从 app-dev 传输到 app-qa。两个跳转服务器都缺少用于临时复制数据的存储空间。
您可以使用 ssh 隧道解决此问题。我们设置与一台远程应用服务器的连接,并携带一个远程隧道,该隧道连接回其跳转服务器上未使用的端口。我们设置从一个跳转服务器到另一个跳转服务器的第二个连接,并携带一个隧道,该隧道从隧道一中拾取远程转发端口的悬空端,并将其发送到另一个应用服务器的 ssh 端口。
设置隧道(每个命令都需要在单独的窗口中运行jump-qa
):
jump-qa% ssh app-qa -R 2345:localhost:2346
jump-qa% ssh jump-dev -L 2346:app-dev:22
现在您应该发现,在 app-qa 上,您可以执行telnet localhost 2345
并获取 app-dev 的 ssh 横幅。然后您可以复制数据文件:
app-qa% scp -P 2345 localhost:/path/on/app-dev/data.dat data.dat
答案4
-J [user@]host[:port]
首先与跳转主机建立 ssh 连接,然后从那里建立到最终目的地的 TCP 转发,从而连接到目标主机。可以用逗号分隔指定多个跳转点。这是指定 ProxyJump 配置指令的快捷方式。
对于 A → B → C,在 A 上,只需:
tar -cf - file1 file_n | pv | ssh -C -J userB@B:portB userB@C -p portC 'tar -C destDir -xvf -'
- 使用 ssh 选项时可以使用任意数量的跳数
-J
。 - 省略 tar 的远程
-C
以将文件留在主文件夹中。 - 立即发送任何文件(文本或二进制)。
- 通过使用 或 ssh
-C
(或 tar-z
)压缩流来提高速度。如果数据是纯文本(未压缩),则特别有用。 pv
监控管道中数据的传输进度。另一种方法是progress
。
灵感来自弗洛里安·菲达和Dan Garthwaite 的答案。