通过SSH会话将文件从远程主机传送到本地主机的最佳方式是什么?

通过SSH会话将文件从远程主机传送到本地主机的最佳方式是什么?,ssh,Ssh,当通过ssh连接到远程主机时,我经常希望将该系统上的文件带到本地系统进行查看或处理。有没有一种方法可以在不打开新终端/暂停ssh会话的情况下复制文件(b)再次对本地或远程主机进行身份验证(c)即使一个或两个主机都在NAT路由器后面也可以正常工作 目标是尽可能多地利用当前状态:两台机器之间存在连接,我在两台机器上都经过身份验证,我在文件的工作目录中——因此我不必打开另一个终端,复制并粘贴远程主机和路径,这就是我现在所做的。最好的解决方案也不需要在会话开始之前进行任何设置,但是如果设置是一次性的或能

当通过ssh连接到远程主机时,我经常希望将该系统上的文件带到本地系统进行查看或处理。有没有一种方法可以在不打开新终端/暂停ssh会话的情况下复制文件(b)再次对本地或远程主机进行身份验证(c)即使一个或两个主机都在NAT路由器后面也可以正常工作


目标是尽可能多地利用当前状态:两台机器之间存在连接,我在两台机器上都经过身份验证,我在文件的工作目录中——因此我不必打开另一个终端,复制并粘贴远程主机和路径,这就是我现在所做的。最好的解决方案也不需要在会话开始之前进行任何设置,但是如果设置是一次性的或能够自动进行,那么这是完全可以接受的

您应该能够设置公钥和私钥,这样就不需要身份验证

具体操作方式取决于安全要求等(请注意,有些linux/unix ssh蠕虫会通过查看密钥来找到它们可以攻击的其他主机)


我一直在linksys和dlink路由器后面做这件事。我认为您可能需要更改一些设置,但这并不是什么大问题。

为了做到这一点,我将我的家庭路由器设置为将端口22转发回我的家庭机器(它通过防火墙仅接受来自我工作机器的ssh连接)我也有一个帐户设置为提供动态DNS,将自动解析到我的家庭IP

然后,当我使用ssh连接到我的工作计算机时,我要做的第一件事就是运行一个启动ssh代理的脚本(如果您的服务器没有自动执行该操作)。我运行的脚本是:

#!/bin/bash

ssh-agent sh -c 'ssh-add < /dev/null && bash'

这里有一个解决确切问题的方法,但需要修补OpenSSH,就我而言,这是一个不成功的方法。

在linux机器上,我使用ssh代理和sshfs。您需要设置sshd以接受具有密钥对的连接。然后使用ssh add将密钥添加到ssh代理,这样就不必每次都键入密码。确保使用-t秒,这样密钥不会永远处于加载状态
ssh add-t 3600/home/user/.ssh/ssh_dsa

之后,
sshfs主机名://PathToMountTo/
将在您的计算机上装载服务器文件系统,以便您可以访问它

就我个人而言,我编写了一个小bash脚本,添加我的密钥并装载我最常用的服务器,因此当我开始工作时,我只需启动脚本并键入我的密码

(openssh上的包装器)正是您想要的

  • 安装并使用它,而不是openssh(我假设您通常使用openssh)

  • 您必须在两个系统上都安装该软件包

然后,要将文件
zyxel.png
从远程主机传输到本地主机:

antti@local:~$ zssh remote
Press ^@ (C-Space) to enter file transfer mode, then ? for help
...
antti@remote:~$ sz zyxel.png
**B00000000000000
^@
zssh > rz
Receiving: zyxel.png
Bytes received:  104036/ 104036   BPS:16059729

Transfer complete
antti@remote:~$ 
上传的方式也很相似,只是你只需切换和

Putty用户可以尝试,它具有类似的功能。

将ssh客户端置于“主”模式以进行连接共享。多个-M选项将ssh置于“主”模式,并在接受从属连接之前进行确认。有关详细信息,请参阅ssh_配置(5)中对ControlMaster的描述


我不太明白这是如何回答OP的问题的——大卫,你能把这个问题再详细一点吗?

这是我对这个问题的首选解决方案。在创建ssh会话时设置反向ssh隧道。这通过两个bash函数实现:grabfrom()需要在本地主机上定义,而grab()应该在远程主机上定义。您可以添加您认为合适的任何其他ssh变量(例如-X或-Y)

function grabfrom() { ssh -R 2202:127.0.0.1:22 ${@}; };
function grab() { scp -P 2202 $@ localuser@127.0.0.1:~; };
用法:

localhost% grabfrom remoteuser@remotehost
password: <remote password goes here>
remotehost% grab somefile1 somefile2 *.txt
password: <local password goes here>
localhost%grabfromremoteuser@remotehost
密码:
远程主机%grab somefile1 somefile2*.txt
密码:
积极因素:

  • 除了OpenSSH之外,它在任何主机上都不需要特殊软件
  • 当本地主机位于NAT路由器后面时,它工作
  • 它可以实现为一对两个单行bash函数
负片:

  • 它使用固定端口号,因此:
    • 无法使用到远程主机的多个连接
    • 可能与远程主机上使用该端口的进程冲突
  • 它需要本地主机接受ssh连接
  • 启动会话时需要一个特殊命令
  • 它不会隐式处理对本地主机的身份验证
  • 它不允许在localhost上指定目标目录
  • 如果从多个本地主机抓取到同一个远程主机,ssh将不喜欢密钥更改
今后的工作: 这仍然是相当混乱的。显然,可以通过适当地设置ssh密钥来处理身份验证问题,而且通过向grab()添加一个参数来允许指定远程目录更容易


更困难的是解决其他消极因素。选择一个动态端口会很好,但据我所知,没有优雅的方式将该端口传递给远程主机上的shell;正如我所知,OpenSSH不允许您在远程主机上设置任意环境变量,bash也不能从命令行参数中获取环境变量。即使您可以选择一个动态端口,也无法确保它在未首先连接的情况下不在远程主机上使用。

使用ControlMaster(-M交换机)是最好的解决方案,比这里的其他答案更简单、更容易。它允许您在多个会话之间共享单个连接。听起来像是海报想要的。不过,您仍然必须键入scp或sftp命令行。试试看。我将它用于我的所有sshing。

使用一些鲜为人知且很少使用的openssh特性 你可以实现你想要的

  • 利用
    localhost% grabfrom remoteuser@remotehost
    password: <remote password goes here>
    remotehost% grab somefile1 somefile2 *.txt
    password: <local password goes here>
    
    local> ssh username@remote
    remote> ~C
    ssh> -L6666:localhost:6666
    remote> nc -l 6666 < /etc/passwd
    remote> ~^Z
    [suspend ssh]
    [1]+  Stopped                 ssh username@remote
    local> (sleep 1; nc localhost 6666 > /tmp/file) & fg
    [2] 17357
    ssh username@remote
    remote> exit
    [2]-  Done                    ( sleep 1; nc localhost 6666 > /tmp/file )
    local> cat /tmp/file
    root:x:0:0:root:/root:/bin/bash
    bin:x:1:1:bin:/bin:/sbin/nologin
    daemon:x:2:2:daemon:/sbin:/sbin/nologin
    ...
    
    local> ssh username@remote
    remote> ~C
    ssh> -R5555:localhost:5555
    remote> ~^Z
    [suspend ssh]
    [1]+  Stopped                 ssh username@remote
    local> nc -l 5555 < ~/.ssh/id_rsa.pub &
    [2] 26607
    local> fg
    ssh username@remote
    remote> nc localhost 5555 >> ~/.ssh/authorized_keys
    remote> cat ~/.ssh/authorized_keys
    ssh-rsa AAAAB3NzaC1yc2ZQQQQBIwAAAQEAsgaVp8mnWVvpGKhfgwHTuOObyfYSe8iFvksH6BGWfMgy8poM2+5sTL6FHI7k0MXmfd7p4rzOL2R4q9yjG+Hl2PShjkjAVb32Ss5ZZ3BxHpk30+0HackAHVqPEJERvZvqC3W2s4aKU7ae4WaG1OqZHI1dGiJPJ1IgFF5bWbQl8CP9kZNAHg0NJZUCnJ73udZRYEWm5MEdTIz0+Q5tClzxvXtV4lZBo36Jo4vijKVEJ06MZu+e2WnCOqsfdayY7laiT0t/UsulLNJ1wT+Euejl+3Vft7N1/nWptJn3c4y83c4oHIrsLDTIiVvPjAj5JTkyH1EA2pIOxsKOjmg2Maz7Pw== username@local
    
    remote> ~C
    ssh> help
    Commands:
          -L[bind_address:]port:host:hostport    Request local forward
          -R[bind_address:]port:host:hostport    Request remote forward
          -D[bind_address:]port                  Request dynamic forward
          -KR[bind_address:]port                 Cancel remote forward
    
     -e escape_char
             Sets the escape character for sessions with a pty (default: ‘~’).  The escape character is only recognized at the beginning of a line.  The escape character followed by a dot
             (‘.’) closes the connection; followed by control-Z suspends the connection; and followed by itself sends the escape character once.  Setting the character to “none” disables any
             escapes and makes the session fully transparent.
    
    ESCAPE CHARACTERS
         When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape character.
    
         A single tilde character can be sent as ~~ or by following the tilde by a character other than those described below.  The escape character must always follow a newline to be interpreted
         as special.  The escape character can be changed in configuration files using the EscapeChar configuration directive or on the command line by the -e option.
    
         The supported escapes (assuming the default ‘~’) are:
    
         ~.      Disconnect.
    
         ~^Z     Background ssh.
    
         ~#      List forwarded connections.
    
         ~&      Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate.
    
         ~?      Display a list of escape characters.
    
         ~B      Send a BREAK to the remote system (only useful for SSH protocol version 2 and if the peer supports it).
    
         ~C      Open command line.  Currently this allows the addition of port forwardings using the -L, -R and -D options (see above).  It also allows the cancellation of existing remote port-
                 forwardings using -KR[bind_address:]port.  !command allows the user to execute a local command if the PermitLocalCommand option is enabled in ssh_config(5).  Basic help is avail‐
                 able, using the -h option.
    
         ~R      Request rekeying of the connection (only useful for SSH protocol version 2 and if the peer supports it).
    
    python3 -m pip install zssh
    
    python3 -m zssh -as --path /desktop/path_to_expose
    
    python3 -m zssh -ad --path /desktop/path_to_download --zip http://example.com/temp_file.zip