我怀疑我会在这里得到答案,因为AIX是非常罕见的事情,但我至少应该尝试一下。
背景
我们有程序。该程序使用golang.org/x/crypto/ssh
库连接到远程服务并执行某些操作。该程序是大型服务的一部分,并已受到最终用户的广泛测试。它不仅可以与所有基于Linux的客户端(包括非常老的东西,如Ubuntu 12.02)一起使用,而且与FreeBSD,OpenBSD,NetBSD,MacOSX,Solaris SPARC,HP-UX和其他操作系统上的客户端一样,也不会出现问题(至少与连接有关) *尼克斯。因此,看起来它并没有仅在三星冰箱上进行过测试。昨天,我确定它可以连接到冰箱,并且可以做任何需要的事情。但是那是昨天
问题
今天,我们决定将AIX支持添加到我们的程序中。我们部分失败了。
问题描述很简单:在pty
请求程序停止运行之后。我的意思是我可以执行ssh.RequestPty
,它执行时没有任何问题,但是当应用程序挂起后,我尝试执行命令时。没有错误,就什么都没有。挂了
什么时候有效?
requestPty
-一切正常。但是我们需要pty
作为sudo
。 session.Shell
,即使我请求pty
,它也能正常工作。因此,如果我编写一种交互式 shell ,它会完美地工作。 到目前为止我尝试了什么
我已尽力调试。最后执行的命令是
ch.sendMessage(msg)
中的ssh/channel.go
。我的意思是它写了数据包,仅此而已。远程主机未返回任何数据。对于测试,我使用了3个版本的AIX-5.3、6.1和7.1。没有不同。
OpenSSH版本不同:
所有机器都在LPAR中运行,但是我怀疑这与问题有关。
我不知道怎么了。而且我什至不能说这是常见的AIX问题还是仅是我们的测试机器。这是示例程序,如果可以,应编写
IT WORKS
package main
import (
"golang.org/x/crypto/ssh"
)
func main() {
server := "127.0.0.1:22"
user := "root"
p := "password"
config := &ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{ssh.Password(p)},
}
conn, err := ssh.Dial("tcp", server, config)
if err != nil {
panic(err.Error())
}
defer conn.Close()
session, err := conn.NewSession()
if err != nil {
panic(err.Error())
}
defer session.Close()
// Comment below and everything works
modes := ssh.TerminalModes{
ssh.ECHO: 0,
ssh.TTY_OP_ISPEED: 14400,
ssh.TTY_OP_OSPEED: 14400,
}
if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
panic(err.Error())
}
// Comment above and everything works
session.Run("echo 1")
println("IT WORKS")
}
如果您周围有AIX,并且可以针对它运行此代码,则感谢您的反馈。
如果您有任何想法(甚至是疯狂的),为什么它可能会失败以及我可以在其他地方看到,请不要害羞。
更新(2017-03-02):
根据@LorinczyZsigmond的建议,我以 Debug模式启动了
sshd
。结果有点奇怪。这是示例程序执行后
Debian 9.0 OpenSSH_6.0p1 Debian-4+deb7u3, OpenSSL 1.0.1t 3 May 2016
日志的一部分:debug1: session_input_channel_req: session 0 req pty-req
debug1: Allocating pty.
debug1: session_pty_req: session 0 alloc /dev/pts/1
debug1: SELinux support disabled
debug1: server_input_channel_req: channel 0 request exec reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req exec
debug2: fd 3 setting TCP_NODELAY
debug3: packet_set_tos: set IP_TOS 0x10
debug1: Setting controlling tty using TIOCSCTTY.
debug2: channel 0: rfd 10 isatty
debug2: fd 10 setting O_NONBLOCK
debug3: fd 8 is O_NONBLOCK
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
它按预期工作。
现在来自
AIX 7.1 OpenSSH_6.0p1, OpenSSL 1.0.1e 11 Feb 2013
日志的相同块:debug1: session_input_channel_req: session 0 req pty-req
debug1: Allocating pty.
debug1: session_pty_req: session 0 alloc /dev/pts/42
debug1: server_input_channel_req: channel 0 request exec reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req exec
debug1: Values: options.num_allow_users: 0
debug1: RLOGIN VALUE :1
debug1: audit run command euid 0 user root command 'whoami'
setsid: Operation not permitted.
在
setsid: Operation not permitted.
之后,它什么都不做,直到我用Ctrl + C杀死它为止。当我杀死它时返回:debug2: fd 4 setting TCP_NODELAY
debug3: packet_set_tos: set IP_TOS 0x10
debug2: channel 0: rfd 10 isatty
debug2: fd 10 setting O_NONBLOCK
debug3: fd 8 is O_NONBLOCK
debug2: notify_done: reading
Exiting on signal 2
debug1: do_cleanup
debug1: session_pty_cleanup: session 0 release /dev/pts/42
debug1: audit session close euid 0 user root tty name /dev/pts/42
debug1: audit event euid 0 user root event 12 (SSH_connabndn)
debug1: Return Val-1 for auditproc:0
并将
whoami
的结果发送回客户端。这看起来像是SSH服务器中的错误,但这是否可以用于2个不同的版本?另一个有趣的事实是,当我将
sshd
与truss
(AIX的strace
种类)一起运行时,输出如下所示:debug1: session_input_channel_req: session 0 req pty-req
debug1: Allocating pty.
debug1: session_pty_req: session 0 alloc /dev/pts/42
debug1: server_input_channel_req: channel 0 request exec reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req exec
debug1: Values: options.num_allow_users: 0
debug1: RLOGIN VALUE :1
debug1: audit run command euid 0 user root command 'whoami'
debug2: fd 4 setting TCP_NODELAY
debug3: packet_set_tos: set IP_TOS 0x10
debug2: channel 0: rfd 10 isatty
debug2: fd 10 setting O_NONBLOCK
debug3: fd 8 is O_NONBLOCK
setsid: Operation not permitted.
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
但是
truss
的输出比strace
的输出有些奇怪(至少对于每天不使用* nix跟踪工具的人而言),因此我不了解日志中发生了什么。如果有人对此有所了解,这是debug1: RLOGIN VALUE :1
的跟踪数据http://pastebin.com/YdzQwbt2的一部分。另外,在日志中,我发现
ssh.Shell()
可以正常工作,因为它不要求pty
。它开始一个交互式 session (或类似的 session )。但就我而言,交互式 session 不是一种选择。 最佳答案
迟到总比不到好
IBM表示这是opensh的错误-PTY分配时出现竞争状态
https://www-01.ibm.com/support/docview.wss?uid=isg1IV82042
固定在包openssh.base.server:7.5.102.1500中
奇怪的是,该错误仅发生在aix中,而没有在Linux中发生。但是,我的问题解决了
关于go - Go的SSH客户端和AIX上的PTY,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42540183/