Go的SSH客户端和AIX上的PTY

I doubt that I'll get an answer here as AIX is very rare thing but I should try at least.

The background

We have the program. The program uses golang.org/x/crypto/ssh library to connect to the remote services and do some things. The program is part of the large service and widely tested by end-users. It works without issues (at least related to connection) not only with all Linux-based clients (include quite old things like Ubuntu 12.02) but also with the clients on FreeBSD, OpenBSD, NetBSD, MacOSX, Solaris SPARC, HP-UX and other *nixes. So looks like it wasn't tested only on the Samsung refrigerators. And yesterday I was sure that it will be able to connect to the refrigerator and do what is needed without any issues. But that was yesterday...

The problem

Today we decided to add AIX support to our program. And we partly failed.

The problem description is simple: after pty request program stops working. I mean I can do ssh.RequestPty it executes without any issues but when I'm trying to execute commands after the app just hangs. Without errors, without nothing. Just hangs.

When it works?

  1. It works in PuTTY/KiTTY so I'm able to connect to the remote host.
  2. If I remove requestPty - everything works. But we need pty for the sudo.
  3. It works without issues if I request session.Shell even with pty requested. So if I write kind of interactive shell, it works perfectly.

What have I tried so far

I tried to debug so far as I could. The last command that executes is ch.sendMessage(msg) from ssh/channel.go. I mean it writes packet and that's all. No data returned from the remote host.

For the tests, I used 3 versions of AIX - 5.3, 6.1 and 7.1. No difference.

OpenSSH versions are different:

  • 5.3 - OpenSSH_5.2p1, OpenSSL 0.9.8k 25 Mar 2009
  • 6.1 & 7.1 - OpenSSH_6.0p1, OpenSSL 1.0.1e 11 Feb 2013

All machines are running in LPARs but I doubt this is related to the issue.

I have no idea what is wrong. And I even can't say if this is common AIX issue or only our test machine. Here is the sample program that should write IT WORKS if 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")
}

If you have AIX somewhere around and can run this code against it I'd appreciate your feedback.

If you have any ideas (even crazy) why it may fail and where else I can look, don't be shy.

Update (2017-03-02):

By suggestion from @LorinczyZsigmond I launched sshd in debug mode. Results are a bit strange.

Here is part of Debian 9.0 OpenSSH_6.0p1 Debian-4+deb7u3, OpenSSL 1.0.1t 3 May 2016 log after sample program execution:

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

It works as expected.

Now the same block from AIX 7.1 OpenSSH_6.0p1, OpenSSL 1.0.1e 11 Feb 2013 log:

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.

After setsid: Operation not permitted. it does nothing until I kill it with Ctrl+C. When I kill it it returns:

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

And sends the result of whoami back to the client. This looks like a bug in SSH server, but is this possible for the 2 different versions?

Another interesting fact is when I run sshd with truss (kind of strace for AIX) the output looks like this:

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

But truss output is a bit more strange than strace one (at least for someone who don't use *nix trace tools on daily basis) so I don't understand what is going on in the logs. If there is someone more skilled with this stuff here is the part of the trace data http://pastebin.com/YdzQwbt2 from debug1: RLOGIN VALUE :1.

Also, in the logs, I found that ssh.Shell() works because it doesn't request pty. It starts an interactive session (or something like that). But in my case, the interactive session is not an option.

duanmaduan1848
duanmaduan1848 在setsid()手册页中:EPERM调用进程已经是进程组负责人,或者除调用进程之外的其他进程的进程组ID与调用进程的进程ID相匹配。-但是为什么sshd会实现这一点超出了我。为什么这是特定于您的特定路径的,这也很奇怪。
3 年多之前 回复
doumie7914
doumie7914 我比较了Debian和AIXsshd调试输出并更新了帖子。这似乎是OpenSSH中的错误,但我不知道这对于两种不同版本的OpenSSH是否可行。无论如何,我现在很确定这不是GoSSH实施问题。因此,我将尽可能尝试将要求sudo的命令替换为替代命令。
3 年多之前 回复
duankousong9637
duankousong9637 您也可以使用-vvv与openssh客户端连接,以查看它可能如何以不同方式处理连接。
3 年多之前 回复
dongtu1789
dongtu1789 建议,但不确定是否会显示与pty相关的问题。
3 年多之前 回复
dpafea04148
dpafea04148 嗯。我不知道指定vt100还是哑巴可以解决此问题。
3 年多之前 回复
duanniubeng2265
duanniubeng2265 抱歉,无视我的评论:我在移动设备上,没有简单的方式查看文档,因此我认为RequestPty()也可以启动远程进程。现在,我看到的是终端名称字符串。
3 年多之前 回复
dongzhenbi8919
dongzhenbi8919 谢谢您的回复。我们不需要使用最终用户的root帐户。他们可以以root用户身份,具有sudo特权的用户和简单用户身份登录。您是对的,在第一种和最后一种情况下,我们不需要pty,但是我们的部分用户使用了第二种变体,因此我们也应该支持它。还要感谢您提供有关从服务器端进行调试的想法。我会尽力。
3 年多之前 回复
dsfds2353
dsfds2353 谢谢你的问题。也许我解释不正确。该程序通过SSH连接到远程服务器,然后收集一些数据并将其发送回主服务。另外,我们有推荐使用本地代理的方式来使用我们的服务,但是Go不支持AIX,因此收集数据的唯一方法是使用问题中的程序。
3 年多之前 回复
douwei7976
douwei7976 谢谢。我会尽力。
3 年多之前 回复
doujiayao8433
doujiayao8433 随机问题:如果以root用户身份连接,为什么还要使用sudo?为什么不升级到OpenSSL-1.0.2k和OpenSSH-7.4p1?是否尝试在调试模式(sshd-D-d-d-dpanotherport)中运行sshd?
3 年多之前 回复
douni9620
douni9620 呃。为什么选择xterm?该程序不是应该远程运行吗?如果是,它是否有机会成功完成此操作(即在其环境块中看到适当的DISPLAY变量等)?如果您尝试其他方法怎么办?
3 年多之前 回复
dsajdgjadwqe3247382
dsajdgjadwqe3247382 在IBM网站上有关于AIX的支持论坛。(很抱歉,我没有URLS(而且它们可能无论如何都已更改))。另外,在ittoolbox.com论坛上有相当多的AIX用户。您进行简单的注册,然后搜索/浏览他们的论坛。找到AIX论坛后,可能需要单独“加入”它。我认为您不会在此处找到确切的答案,但是可以找到AIX的更好帮助。祝好运。
3 年多之前 回复

1个回答



我在“分配pty”时遇到了类似的问题,然后退出了ssh会话。 这是我的sshd调试日志:</ p>

sshd断开连接,错误:3004-010设置终端所有权和模式失败。</ p>


debug1:分配pty。</ strong>

debug1:session_pty_req:会话0 alloc / dev / pts / 2

debug1:忽略不受支持的tty模式操作码13(0xd)

debug1:忽略不受支持的tty模式操作码18(0x12)</ strong>

debug1:server_input_channel_req:通道0请求环境回复0

debug1:session_by_channel:会话0通道0

debug1:session_input_channel_req:会话0 req env

debug2:忽略env请求LANG:不允许的名称

debug1:server_input_channel_req:通道0请求shell回复1

debug1:session_by_channel:会话 0通道0

debug1:session_input_channel_req:会话0 req shell

debug1:值:options.num_allow_users:0

debug1:RLOGIN VALUE:1 </ p>

< p> setsid:不允许操作。</ p>

操作系统为AIX 7.1(7100-04-0 3-1642)</ p>
</ blockquote>

我的环境的目标是通过ssh(ldap服务器实际上是Novell eDirectory)通过远程ldap用户对AIX上的用户进行身份验证。

因此,我在用户身份验证方面也遇到了类似的问题。</ p>

我像在eDirectory架构(rfc2703)中一样,通过ssh修复了登录,并向用户添加了以下对象扩展名:</ p>
\ n

posixAccount

posixGroup

shadowAccount

uamPosixUser(因为我不确定是否需要此对象)</ p>

我只想注意一下 以下用户的OS AIX不是本地用户,在 / etc / passwd </ code>和 / etc / group </ code>中不存在。</ p>

V.Davidov </ p>
</ div>

展开原文

原文

I had similar problem with "Allocating pty" and then exiting from ssh session. Here is log of my sshd debug:

sshd drops connection with error :3004-010 Failed setting terminal ownership and mode.

debug1: Allocating pty.
debug1: session_pty_req: session 0 alloc /dev/pts/2
debug1: Ignoring unsupported tty mode opcode 13 (0xd)
debug1: Ignoring unsupported tty mode opcode 18 (0x12)

debug1: server_input_channel_req: channel 0 request env reply 0
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req env
debug2: Ignoring env request LANG: disallowed name
debug1: server_input_channel_req: channel 0 request shell reply 1
debug1: session_by_channel: session 0 channel 0
debug1: session_input_channel_req: session 0 req shell
debug1: Values: options.num_allow_users: 0
debug1: RLOGIN VALUE :1

setsid: Operation not permitted.

The OS is AIX 7.1 (7100-04-03-1642)

The goal of my environment is to authenticate user on AIX through remote ldap user over ssh (ldap server actually is novell eDirectory). So, I had similar issue with user authentication.

I fixed login over ssh as in eDirectory Schema (rfc2703), added following object extensions to the user:

posixAccount
posixGroup
shadowAccount
uamPosixUser (as I am not sure is it necessary this object)

I just want to note that on OS AIX following user isn't local, not exist in /etc/passwd and /etc/group.

V.Davidov

dongnao2582
dongnao2582 谢谢。 我会尽力。
3 年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问