我想知道是否有办法让我通过remote1主机直接从我的本地机器发送来自remote2主机的文件。
网络仅允许从remote1主机连接到remote2主机。此外,remote1主机和remote2主机都不能scp到我的本地计算机。
是否有类似的东西:
scp user1@remote1:user2@remote2:file .
第一个窗口:ssh remote1
,然后是scp remot2:file .
。
第二个shell: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
上的内容更改为什么?< / p>
答案 0 :(得分:87)
我不知道有什么方法可以直接在一个命令中复制文件,但是如果您可以承认在后台运行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
连接,因为它位于localhost上的端口1234上,第一个ssh
实例正在侦听到{{1}的前向连接}。另请注意,您不需要为每个后续文件副本运行第一个命令;你可以简单地让它继续运行。
答案 1 :(得分:64)
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
如果文件很大并且您不想打扰其他重要的网络应用程序,则可能会错过scp
和rsync
工具提供的网络吞吐量限制(例如{ {1}}使用的速度不超过1 Mbits /秒。
但是,解决方法是使用ionice
来保留单个命令行:
scp -l 1024 user@remote:file
注意:旧版本可能无法使用ionice -c2 -n7 ssh u1@remote1 'ionice -c2 -n7 ssh u2@remote2 "cat file"' > file
。
答案 2 :(得分:29)
这样可以解决问题:
scp -o 'Host remote2' -o 'ProxyCommand ssh user@remote1 nc %h %p' user@remote2:path/to/file .
直接从主机remote2
向SCP发送文件,将两个选项(Host
和ProxyCommand
)添加到〜/ .ssh / config文件中(另请参阅{{3}回答超级用户)。然后你可以运行:
scp user@remote2:path/to/file .
来自本地计算机,无需考虑remote1
。
答案 3 :(得分:5)
使用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以上配置文件设置)
答案 4 :(得分:1)
scp
中有一个新选项,最近为完全相同的工作添加了一个非常方便的选项,-3
。
TL; DR 对于已在ssh配置文件中设置了身份验证的当前主机,只需执行以下操作:
scp -3 remote1:file remote2:file
您的scp
必须来自最新版本。
上述所有其他技术都要求您设置从remote1到remote2的身份验证,反之亦然,这并不总是一个好主意。
参数-3
表示您希望通过使用当前主机作为中介从两个远程主机移动文件,并且该主机实际上对两个远程主机都进行了身份验证,因此它们不必彼此访问。
您只需要在ssh配置文件中设置身份验证即可,这很容易且有据可查,然后只需在TL; DR
答案 5 :(得分: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 复制到生产计算机。
答案 6 :(得分:0)
我在Olibre的源代码中为this的解决方案添加了少量内容。
就像您有三种使用tar
从远程主机复制到本地的方法一样,以下在双ssh情况下适用于本地主机到远程主机的复制:(在中运行它们 >必须从中复制文件的目录,否则使用fullpath / filename)
不压缩即可传输单个文件:
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"'
如果命令的前半部分不起作用,例如,如果目录丢失或源/目标路径名错误,则&&此处将阻止命令运行。