jjzjj

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

coder 2023-06-29 原文

我怀疑我会在这里得到答案,因为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/

    有关go - Go的SSH客户端和AIX上的PTY的更多相关文章

    1. ruby - Capistrano 3 在任务中更改 ssh_options - 2

      我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

    2. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

      我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

    3. ruby-on-rails - openshift 上的 rails 控制台 - 2

      我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

    4. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

      我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

    5. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

      我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

    6. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

      我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

    7. ruby-on-rails - rails 上的 ruby : radio buttons for collection select - 2

      我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/

    8. ruby - 将命令行上的变量传递给 Cucumber 测试 - 2

      我正在尝试将cucumber项目的用户名和密码置于版本控制之外。有没有办法在命令行上手动将用户名和密码等变量传递给Cucumber脚本?我的备份计划是将它们放在一个YML文件中,然后将该文件添加到gitignore,这样它们就不会被置于版本控制中。 最佳答案 所以,我看到了您对铁皮人的评论,答案是肯定的。cucumberPASSWORD=my_passwordPASSWORD被设置为环境变量,您可以通过将其引用为ENV['PASSWORD']来使用它的值。例如,browser.text_field(:id=>'pwd').setEN

    9. ruby - 将哈希值保存到 Ruby 上的文件 - 2

      我刚刚迈出了编程的第一步。我刚刚完成了CodeAcademy的另一门类(class)。这次我被要求创建一个小电影目录。这是我的问题:如何在文件中保存/加载带有电影标题和评级的哈希值而不是自己的代码?下面是代码现在的样子(几句葡萄牙语,但您可以忽略它:movies={Memento:3,Primer:4,Ishtar:1}puts"Oquevocêgostariadefazer?"puts"--Digite'add'paraadicionarumfilme."puts"--Digite'update'paraatualizarumfilme."puts"--Digite'display'

    10. ruby - 使用 ruby​​ gem net-ssh-multi 同时在多个服务器上执行 sudo 命令 - 2

      在previousquestion中我想出了如何在多个服务器上启动经过密码验证的sshsession来运行单个命令。现在我需要能够执行“sudo”命令。问题是,net-ssh-multi没有分配sudo需要运行的伪终端(pty),导致以下错误:[127.0.0.1:stderr]sudo:sorry,youmusthaveattytorunsudo根据documentation,可以通过调用channel对象的方法来分配伪终端,但是,以下代码不起作用:它会生成上面的“notty”错误:require'net/ssh'require'net/ssh/multi'Net::SSH::Mul

    随机推荐