目前我已经安装了 cygwin 并通过 ssh 进入一台机器并运行如下命令。
ssh user@ip "command"
唯一的问题是打开新的 ssh 会话并运行每个命令需要很长时间。
所以我的问题是:是否可以让一个 ssh 会话在后台运行,以便我可以以更快的速度运行命令(而不必为每个命令打开一个新的 ssh 会话)?
答案1
几个月前,我一直在研究如何解决这个问题,因为有一个问题需要它项目在我目前的工作中。该问题描述于openssh 漏洞,附有修补可以解决缺失的cygwin
功能。我也与上游开发人员和维护人员讨论过这个问题cygwin
,但看起来它尚未应用于任何版本。
短话长说
Cygwin 没有实现一种特殊的消息传递协议,允许在 Unix 上完全不相关的进程之间传递文件描述符。从 cygwin 维护者的话来说,在 Windows API 中实现此功能似乎是不可能的,因为文件描述符的理解方式完全不同。
不过,我的朋友指出,这是一个相当常见的问题,如果这个方法可行,我会让很多人高兴。因此,我开始破解,并想出了这个使用套接字的解决方案,并成功用于上述工具—— scap-workbench
。
如何获取?
这就是问题所在。我觉得我应该写一些如何在 cygwin 下构建 ssh,所以这是一个很好的机会。
从源代码构建
- 从以下网址下载并安装 cygwincygwin.com
从 Cygwin 存储库安装
openssh
及其依赖项(基本上这个列表应该足够了):./setup-x86_64.exe -nq -P autoconf,automake,binutils,cygport,cygwin-devel,gcc-core,git,libcom_err-devel,libcom_err2,libcrypt-devel,libcrypt0,libedit-devel,libedit0,libgcc1,libgssapi_krb5_2,libiconv-devel,libiconv2,libintl-devel,libintl8,libk5crypto3,libkrb5-devel,libkrb5_3,libkrb5support0,libncurses-devel,libncursesw10,libopenssl100,libssp0-4.9.2-3,make,openssl-devel,w32api-headers,w32api-includes,zlib-devel,zlib0-1.2.8-3,git,wget
重新打开 Cygwin 终端
下载最新发布的便携的版本(当前为 7.1p1)
wget http://mirror.steadynet.cz/pub/OpenBSD/OpenSSH/portable/openssh-7.1p1.tar.gz # or you can choose different mirror tar zxvf openssh-7.1p1.tar.gz cd openssh-7.1p1 autoreconf
应用补丁(我希望它仍然能顺利应用)
wget https://raw.githubusercontent.com/Jakuje/stuff/master/openssh_without_fdpass.patch cat openssh_without_fdpass.patch | patch
配置
mkdir build cd build ../configure --prefix=/usr \ --sysconfdir=/etc \ --libexecdir='${sbindir}' \ --localstatedir=/var \ --datadir='${prefix}/share' \ --mandir='${datadir}/man' \ --infodir='${datadir}/info' \ --with-kerberos5 \ --with-libedit \ --with-xauth=/usr/bin/xauth \ --enable-etc-default-login
建造它!
make CFLAGS=-g
下载包含所有依赖项的现成二进制文件
敦促上游
另一种可能性是敦促 openssh 或 cygwin 应用此补丁。这将使更多人受益。自从发布补丁以来,由于其他任务,我没有在这方面付出太多努力。
最小测试用例
# initiate connection
SSH_HOST="user@hostname"
C_PATH="~/.ssh/master_%r@%h:%p.socket"
./ssh -M -f -N -o -p 314 ControlPath="$C_PATH" "$SSH_HOST"
# do whatever commands you want
./ssh -o ControlPath="$C_PATH" "$SSH_HOST" -p 314 "echo test"
# terminate connectino
./ssh -o ControlPath="$C_PATH" "$SSH_HOST" -p 314 -O exit
(请注意./ssh
,因为我们想要调用在当前目录中构建的二进制文件,而不是 cygwin 提供的二进制文件,后者位于您的$PATH
)
答案2
长时间启动 ssh 会话的问题有时是因为 SSH 服务器正在尝试查找 SSH 客户端的主机名。尝试编辑 /etc/ssh_config 中的 sshd 守护进程配置文件并修改或添加(如果不存在)此指令:
UseDNS no
您必须首先使用命令生成配置文件:
ssh-host-config