当通过ssh连接到远程主机时,我经常想将该系统上的文件带到本地系统进行查看或处理。有没有办法复制文件而没有(a)打开一个新终端/暂停ssh会话(b)再次验证本地或远程主机工作(c)即使一个或两个主机在后面NAT路由器?
目标是利用尽可能多的当前状态:两台机器之间存在连接,我在两者上都进行了身份验证,我在文件的工作目录中 - - 所以我不必打开另一个终端并复制并粘贴远程主机和路径,这就是我现在所做的。最好的解决方案也不需要在会话开始之前进行任何设置,但如果设置是一次性的或能够自动化,那么这是完全可以接受的。
答案 0 :(得分:8)
zssh(openssh上的ZMODEM包装器)完全符合您的要求。
然后,将文件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用户可以尝试具有类似功能的Le Putty。
答案 1 :(得分:4)
在Linux机器上,我使用ssh-agent和sshfs。您需要设置sshd以接受与密钥对的连接。然后使用ssh-add将密钥添加到ssh-agent,这样您就不必每次都输入密码。请务必使用-t秒,因此密钥不会永远保持加载状态。
ssh-add -t 3600 /home/user/.ssh/ssh_dsa
之后,
sshfs hostname:// PathToMountTo /
将服务器文件系统挂载到您的计算机上,以便您可以访问它。
就个人而言,我写了一个小的bash脚本,它添加了我的密钥并挂载了我最常用的服务器,所以当我开始工作时,我只需要启动脚本并输入我的密码。
答案 2 :(得分:2)
使用openssh的一些鲜为人知且很少使用的功能 实施,你可以准确地完成你想要的!
您应该只输入每个local>
,remote>
和。{
ssh>
在下面的示例中提示。
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
...
或者,更常见的是你想要走向另一个方向,例如,如果你
想做一些像转移你的~/.ssh/id_rsa.pub
文件的事情
您的本地计算机到远程的~/.ssh/authorized_keys
文件
机。
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
按顺序解释一下。
第一步是打开LocalForward
;如果你还没有
一个建立然后你可以使用~C
转义字符打开一个
ssh命令行,它将为您提供以下命令:
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
在此示例中,我在localhost的端口6666上建立LocalForward
对于客户端和服务器;端口号可以是任意的
任意开放端口。
nc
命令来自netcat
包;它被描述为
“TCP / IP瑞士军刀”;它是一个简单但非常灵活的
有用的程序。将它作为unix工具带的标准部分。
此时nc
正在侦听端口6666并等待另一端口
程序连接到该端口,以便它可以发送的内容
/etc/passwd
。
接下来,我们使用另一个转义字符~^Z
tilde
然后是control-Z
。这暂时中止了ssh进程和
让我们回到我们的壳里。
在本地系统上,您可以使用nc
连接到本地系统
转发端口6666.注意在这种情况下缺少-l
,因为那样
选项告诉nc
监听端口,就好像它是一个服务器一样
不是我们想要的;相反,我们只想使用nc
作为客户端
连接到远程端已经正在监听的nc
。
nc
命令周围的其余魔法是必需的,因为如果
你记得上面我说ssh
过程是暂时的
暂停,因此&
将放置整个(sleep + nc)
表达式
进入后台,sleep
给你足够的时间来ssh
使用fg
返回前台。
在第二个例子中,除了我们设置之外,这个想法基本相同
使用-R
而不是-L
向另一个方向移动的隧道
我们建立了RemoteForward
。然后在本地方面就在哪里
您想将-l
参数用于nc
。
默认情况下,转义字符为〜但您可以使用以下命令更改:
-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).
答案 3 :(得分:1)
使用ControlMaster(-M开关)是最好的解决方案,比这里的其他答案更简单,更容易。它允许您在多个会话之间共享单个连接。听起来它像海报想要的那样。您仍然需要键入scp或sftp命令行。试试吧。我把它用于所有的sshing。
答案 4 :(得分:0)
为了做到这一点,我将家用路由器设置为将端口22转发回我的家用机器(防火墙仅接受来自我的工作机器的ssh连接)并且我还设置了一个帐户{{3提供动态DNS,它将自动解析为我的家庭IP。
然后,当我进入我的工作计算机时,我要做的第一件事就是运行一个启动ssh-agent的脚本(如果你的服务器没有自动执行)。我运行的脚本是:
#!/bin/bash
ssh-agent sh -c 'ssh-add < /dev/null && bash'
它要求我的ssh密钥密码,这样我就不必每次都输入密码。如果您使用没有密码短语的ssh密钥,则不需要该步骤。
对于剩下的会话,将文件发送回家庭计算机就像
一样简单scp file_to_send.txt your.domain.name:~/
答案 5 :(得分:0)
这是一个hack called ssh-xfer,它解决了确切的问题,但需要修补OpenSSH,就我而言,这是一个不起作用。
答案 6 :(得分:0)
以下是此问题的首选解决方案。在创建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>
肯定:
否定:
未来的工作: 这仍然是非常kludgy。显然,可以通过适当地设置ssh键来处理身份验证问题,通过向grab()
添加参数来更容易地允许指定远程目录。更难以解决其他负面因素。选择一个动态端口会很不错,但据我所知,没有优雅的方法可以将该端口传递给远程主机上的shell;据我所知,OpenSSH不允许您在远程主机上设置任意环境变量,而bash不能从命令行参数中获取环境变量。即使您可以选择动态端口,也无法确保在未连接的情况下不在远程主机上使用它。
答案 7 :(得分:0)
您可以使用SCP协议传输文件。您可以参考此链接
答案 8 :(得分:0)
使用此方法的最佳方法是可以通过HTTP公开文件并从另一台服务器下载文件,可以使用ZSSH
Python库来实现此目的,
ZSSH -SSH上的ZIP(简单的Python脚本,用于在服务器之间交换文件)。
使用PIP安装它。
python3 -m pip install zssh
从远程服务器运行此命令。
python3 -m zssh -as --path /desktop/path_to_expose
它将为您提供一个URL,以从另一台服务器执行。
在本地系统或其他需要下载这些文件并解压缩的服务器中。
python3 -m zssh -ad --path /desktop/path_to_download --zip http://example.com/temp_file.zip
有关此库的更多信息:https://pypi.org/project/zssh/
答案 9 :(得分:-1)
你应该可以设置公共&amp;私钥,因此不需要身份验证。
你这样做的方式取决于安全要求等(请注意有linux / unix ssh蠕虫会查找密钥以找到他们可以攻击的其他主机)。
我从linksys和dlink路由器后面一直这样做。我认为您可能需要更改几个设置,但这不是什么大问题。
答案 10 :(得分:-1)
“将ssh客户端置于'主'模式进行连接共享。多个-M选项将ssh置于”主“模式,并且在接受从属连接之前需要确认。请参阅ssh_config中的ControlMaster说明( 5)详情。“
我不太明白这是如何解决OP的问题的 - 你可以稍微扩展一下,David?