【发布时间】:2017-07-21 06:42:21
【问题描述】:
我怀疑我会在这里得到答案,因为 AIX 是非常罕见的东西,但我至少应该尝试一下。
背景
我们有程序。该程序使用golang.org/x/crypto/ssh 库连接到远程服务并做一些事情。该程序是大型服务的一部分,并经过最终用户的广泛测试。它不仅适用于所有基于 Linux 的客户端(包括相当古老的东西,如 Ubuntu 12.02),而且适用于 FreeBSD、OpenBSD、NetBSD、MacOSX、Solaris SPARC、HP-UX 和其他客户端*尼克斯。所以看起来它不仅仅在三星冰箱上进行了测试。昨天我确信它将能够连接到冰箱并执行所需的操作而不会出现任何问题。但那是昨天...
问题
今天我们决定将 AIX 支持添加到我们的程序中。我们部分失败了。
问题描述很简单:pty请求程序停止工作后。我的意思是我可以做到ssh.RequestPty 它可以毫无问题地执行,但是当我在应用程序挂起后尝试执行命令时。没有错误,没有任何东西。就挂了。
什么时候起作用?
- 它适用于 PuTTY/KitTY,因此我可以连接到远程主机。
- 如果我删除
requestPty- 一切正常。但是对于sudo,我们需要pty。 - 如果我请求
session.Shell,即使请求pty,它也可以正常工作。因此,如果我编写一种交互式 shell,它会完美运行。
到目前为止我做了什么
我尽量调试。最后执行的命令是来自ssh/channel.go 的ch.sendMessage(msg)。我的意思是它写数据包,仅此而已。没有从远程主机返回数据。
对于测试,我使用了 3 个版本的 AIX - 5.3、6.1 和 7.1。没有区别。
OpenSSH 版本不同:
- 5.3 - OpenSSH_5.2p1,OpenSSL 0.9.8k 2009 年 3 月 25 日
- 6.1 和 7.1 - OpenSSH_6.0p1、OpenSSL 1.0.1e 2013 年 2 月 11 日
所有机器都在 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 的建议,我在调试模式下启动了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。它启动一个交互式会话(或类似的东西)。但就我而言,交互式会话不是一种选择。
【问题讨论】:
-
IBM 网站上有 AIX 支持论坛。 (抱歉,我不再有 URL(而且它们可能已经改变了))。此外,ittoolbox.com 论坛上有相当不错的 AIX 用户组。你做一个简单的注册,然后搜索/浏览他们的论坛。一旦找到 AIX 论坛,您可能需要单独“加入”它。我认为您不会在那里找到确切的答案,但这是获得 AIX 帮助的更好地方。祝你好运。
-
呃。为什么选择 xterm?程序不应该远程运行吗?如果是,它是否有机会成功地做到这一点(也就是说,在其环境块中看到一个适当的 DISPLAY 变量等)?如果您尝试其他方法怎么办?
-
随机问题:如果以
root连接,为什么要使用sudo?为什么不升级到 OpenSSL-1.0.2k 和 OpenSSH-7.4p1?是否尝试在调试模式下运行 sshd (sshd -D -d -d -d p anotherport)? -
@shellter 谢谢。我会试试的。
-
嗯。我想知道指定
vt100甚至dumb是否可以解决问题。