go - Go的SSH客户端和AIX上的PTY

标签 go ssh aix pty

我怀疑我会在这里得到答案,因为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-一切正常。但是我们需要pty作为sudo
  • 即使我请求session.Shell,即使我请求pty,它也能正常工作。因此,如果我编写一种交互式 shell ,它会完美地工作。

  • 到目前为止我尝试了什么

    我已尽力调试。最后执行的命令是ch.sendMessage(msg)中的ssh/channel.go。我的意思是它写了数据包,仅此而已。远程主机未返回任何数据。

    对于测试,我使用了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的建议,我以 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个不同的版本?

    另一个有趣的事实是,当我将sshdtruss(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/

    相关文章:

    linux - 面对巨大(30 秒)的延迟,如何使用 ssh?

    node.js - 无法解析私钥 : Unsupported key format

    bash - 如何查看/bin/sh 指向的内容

    regex - Perl 程序可有效处理目录中的 500,000 个小文件

    pointers - 如何获取指向被屏蔽为接口(interface)的变量的指针?

    mongodb - 如何在没有规范的扩展JSON添加的情况下获取DecodeBytes()输出

    python - 为什么我通过shell可以连接MySQL,但通过Python却无法连接?

    linux - 关于 Cron 的困惑

    types - golang 中的通用 slice 类型?

    go - 有没有办法在 Go 中快速排序类型?