我试图了解如何ProxyCommand
运作
%> ssh -oProxyCommand='ls' root@ubuntu
ssh_exchange_identification: Connection closed by remote host
%> ssh -oProxyCommand='useradd' root@ubuntu
/bin/bash: line 0: exec: useradd: not found
ssh_exchange_identification: Connection closed by remote host
我也尝试了诸如 之类的内置命令env
,但它也没有输出。
任何想法,为什么我不能执行任意命令?
编辑
我知道我可以执行类似的命令ssh host $command
,我只是想弄清楚为什么 ProxyCommand 不能只运行任何命令,真的不知道为什么人们反对它。
答案1
这ProxyCommand
选项不是在远程系统上运行的任意命令,而是用于代理一些数据流。来自手册页ssh_config
(强调):
代理命令
指定要使用的命令连接到服务器。命令字符串延伸到行尾,并使用用户的 shell 'exec' 指令执行以避免 shell 进程延迟。
在命令字符串中,任何出现的“%h”都将替换为要连接的主机名,“%p”将替换为端口,“%r”将替换为远程用户名。该命令基本上可以是任何内容,并且应该从其标准输入读取并写入其标准输出。 它最终应该连接在某些机器上运行的 sshd(8) 服务器,或者在某处执行 sshd -i。
如果您只想在远程系统上运行命令,请在命令行末尾提供它ssh
,如下所示
ssh root@ubuntu ls
答案2
您ProxyCommand
指定的是不是在远程主机上执行。它在本地(客户端)端运行,作为打开到远程主机的 TCP 连接(通常是端口 22)的替代连接方法。运行的可执行文件ProxyCommand
预计通过stdout
和stdin
作为套接字自己的代理recv()
和与本地 ssh 客户端进行通信send()
,但从客户端的角度来看,其行为应该是逐字节替换到实际 ssh 服务器的 TCP 会话。
通常的用法ProxyCommand
是通过一台服务器设置 ssh 隧道以连接到辅助服务器,否则辅助服务器将无法建立直接连接。使用带有netcat
(nc) 命令的 ssh 客户端可以实现此目的,其中处理套接字端的to和to 的netcat
链接。stdout
send()
stdin
recv()
当您调用ProxyCommand
未建立stdout
并stdin
匹配 SSH 协议期望的内容以协商正确的 SSH 传输时,客户端会退出并显示错误:ssh_exchange_identification: Connection closed by remote host
。
如果您实际上希望在建立 ssh 会话并经过身份验证后在远程主机上执行该命令,则可以将其包含在 ssh 命令行的末尾(不带ProxyCommand
),并且 ssh 客户端将在远程主机上调用该命令。远程主机,而不是交互式 shell。
尝试ssh root@ubuntu ls
一下。