scrapli / scrapligo

scrapli, but in go!
MIT License
244 stars 35 forks source link

Unable to read from /dev/ptmx #168

Closed vincentbernat closed 4 months ago

vincentbernat commented 6 months ago

Hey!

With this simple test program:

package main

import (
    "log"

    "github.com/scrapli/scrapligo/driver/options"
    "github.com/scrapli/scrapligo/platform"
)

func main() {
    p, err := platform.NewPlatform(
        "nokia_srl", "127.0.0.1",
        options.WithAuthNoStrictKey(),
        options.WithAuthUsername("admin"),
        options.WithAuthPassword("NokiaSrl1!"),
        options.WithPort(57401),
    )
    if err != nil {
        log.Fatalf("NewPlatform() error:\n%+v", err)
    }
    d, err := p.GetNetworkDriver()
    if err != nil {
        log.Fatalf("GetNetworkDriver() error:\n%+v", err)
    }
    err = d.Open()
    if err != nil {
        log.Fatalf("Open() error:\n%+v", err)
    }
    defer d.Close()
    r, err := d.SendCommand("show version")
    if err != nil {
        log.Fatalf("SendCommand(show version) error:\n%+v", err)
    }
    log.Printf(
        "sent command '%s', output received (SendCommand):\n %s",
        r.Input,
        r.Result,
    )
}

And a Docker container with SRLinux running and 57401 mapped to 22. I get:

 00:10 ❱ go run main.go
2024/01/07 00:10:54 Open() error:
read /dev/ptmx: input/output error
exit status 1

SSH works fine:

 00:11 ❱ ssh admin@127.0.0.1 -p 57401 "show version"
admin@127.0.0.1's password:
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Hostname             : e8a4de3b8e0a
Chassis Type         : 7220 IXR-D3L
Part Number          : Sim Part No.
Serial Number        : Sim Serial No.
System HW MAC Address: 6A:03:02:FF:00:00
Software Version     : v23.7.1
Build Number         : 163-gd408df6a0c
Architecture         : x86_64
Last Booted          : 2024-01-06T22:19:59.338Z
Total Memory         : 64214175 kB
Free Memory          : 52309761 kB
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
carlmontanari commented 6 months ago

Hey there!

This popped up once before here I believe -- short fix is to use standard transport (go crypto vs subprocess wrapper). Otherwise can probably mess with passing some other ssh flags to see (thinking -t or maybe its -T or two of them... can't recall off the top of my head!) to mess w/ pty things.

Would standard transport be ok fix for now?

carlmontanari commented 6 months ago

Or maybe there is some more reading things for future me to look at when I have some more time :) stuff like this and maybe this

vincentbernat commented 6 months ago

I have tried to enable logging to debug more and discovered that I don't get a password when running the SSH command manually:

 00:26 ❱ ssh localhost -p 57401 -o ConnectTimeout=30 -o ServerAliveInterval=30 -l admin -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -F /dev/null
Warning: Permanently added '[localhost]:57401' (ED25519) to the list of known hosts.
Received disconnect from 127.0.0.1 port 57401:2: Too many authentication failures
Disconnected from 127.0.0.1 port 57401
vincentbernat commented 6 months ago

Switching to standard transport works.

carlmontanari commented 6 months ago

can you see if adding -tt to your ssh command feels better? here is where that was sticking in my head from, wonder if its relevant?

Switching to standard transport works

ok cool. crappy "fix", but better than nothing :)

Received disconnect from 127.0.0.1 port 57401:2: Too many authentication failures

too many auth failures feels bad, does that happen every time? wonder if the ssh server is just upset at something we're doing?

vincentbernat commented 6 months ago

In fact, because of -F /dev/null, this removes my IdentitiesOnly yes I am using to workaround problems like this, where some SSH servers do not like to receive too many key attempts. I have 14 keys in my agent. I would suggest to add this option to avoid using the SSH keys inside the agent without an explicit mention?

carlmontanari commented 6 months ago

we always use /dev/null for config unless you tell it not to -- you can pass an explicit config or have it lookup default config file paths with these options! that should sort that out for ya I think ya?

hellt commented 6 months ago

yeah I now as well having too many keys in my agent and got burnt by this as well

vincentbernat commented 6 months ago

Would it be OK to unconditionally add -o IdentitiesOnly=true before the configuration file?

hellt commented 6 months ago

I don't recall from the top of my head but I'd say more appropriate would be to set this ssh client option when we define the options for the platform

carlmontanari commented 6 months ago

yeah I think hope that these two options here should give ya what you need to tune things to whatever is best for your environment. let us know if that works ok?

hellt commented 6 months ago

I had a brief look at it, and when we use the StandardTransport then you shouldn't have any issues with agent bombing the server with many keys, so this should be all good and also solving your problem with ptx mystique.

carlmontanari commented 4 months ago

think/hope this one is all ok now? will close out but feel free to reopen so we can all re-pow-wow on it if needed!