douhuanbai6729 2017-03-01 19:18
浏览 241

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 <kbd>Ctrl+C</kbd>. 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.

  • 写回答

1条回答 默认 最新

  • duan_88598 2017-06-23 06:28
    关注

    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

    评论

报告相同问题?

悬赏问题

  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)
  • ¥20 怎么在stm32门禁成品上增加查询记录功能
  • ¥15 Source insight编写代码后使用CCS5.2版本import之后,代码跳到注释行里面
  • ¥50 NT4.0系统 STOP:0X0000007B
  • ¥15 想问一下stata17中这段代码哪里有问题呀