sup icon indicating copy to clipboard operation
sup copied to clipboard

connect failed if no "hostname" in sshconfig

Open kadefor opened this issue 7 years ago • 9 comments

cat ~/.ssh/config
Host 192.168.16.10
    User root
    Port 22

connecting to clients failed: connecting to remote host failed: Connect("root@:22"): ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain

kadefor avatar Jun 12 '18 12:06 kadefor

Anyone able to fix this?

VojtechVitek avatar Jun 12 '18 14:06 VojtechVitek

@kadefor You're correct that ssh falls back on a valid Host if HostName is omitted when reading from an .ssh/config file. IMO this logic should exist in mikkeloscar/sshconfig. But this is an easy enough fix I'll submit a PR.

mfridman avatar Jun 14 '18 02:06 mfridman

I'm thinking about it too :-)

@mfridman Currently, sup can't set ssh config for per host, this case:

Supfile:

networks:
    prod:
        - 192.168.16.10
        - 192.168.16.11

and ~/ssh/config:

Host 192.168.16.10
    User tom

Host 192.168.16.11
    User roy

now, we get two username "tom" and "roy"

cmd/sup/main.go:

342         // check network.Hosts for match
343         for _, host := range network.Hosts {
344             conf, found := confMap[host]
345             if found {
346                 network.User = conf.User
347                 network.IdentityFile = resolvePath(conf.IdentityFile)
348                 network.Hosts = []string{fmt.Sprintf("%s:%d", conf.HostName, conf.Port)}
349             }
350         }

network.User = ?

can we set tom@<host>:<port> in network.Hosts?

@VojtechVitek this line network.Hosts = []string{fmt.Sprintf("%s:%d", conf.HostName, conf.Port)} network.Hosts only one host? is it a bug? and here network.Hosts set a new value in for network.Hosts, is it ok in golang?

kadefor avatar Jun 14 '18 02:06 kadefor

@kadefor Yep, looks like it's a bug, the network.Hosts are being overwritten with []string{....

So for now it'd make sense to do the following:

Once Sup supports per host configs, can open it up.

for i, host := range network.Hosts {
	if conf, ok := confMap[host]; ok {
		// attempt fallback on Host definition when HostName is omitted
		if conf.HostName == "" {
			conf.HostName = host
		}
		// no point setting the below until Sup supports per host configuration
		// network.User = conf.User
		// network.IdentityFile = resolvePath(conf.IdentityFile)
		network.Hosts[i] = fmt.Sprintf("%s:%d", conf.HostName, conf.Port)
	}
}

mfridman avatar Jun 14 '18 03:06 mfridman

I also think we can add "TODO" here. When Sup supports per host config, then refactor :-)

kadefor avatar Jun 14 '18 03:06 kadefor

@kadefor Looking a bit more at the code you could do the following to fix your use case of username/hostname/port like so..

Because the parseHost() method takes into account whether a username was passed in or not.

for i, host := range network.Hosts {
	if conf, ok := confMap[host]; ok {
		// attempt fallback on Host definition when HostName is omitted
		if conf.HostName == "" {
			conf.HostName = host
		}
		if conf.User == "" {
			conf.User = network.User
		}
		// no point setting the below until Sup supports per host configuration
		// network.User = conf.User
		// network.IdentityFile = resolvePath(conf.IdentityFile)
		network.Hosts[i] = fmt.Sprintf("%s@%s:%d", conf.User, conf.HostName, conf.Port)
	}
}

This will return [[email protected]:22 [email protected]:22]

mfridman avatar Jun 14 '18 03:06 mfridman

@mfridman I'll try to send a PR to support per host config, if I can handle it :-D

kadefor avatar Jun 14 '18 04:06 kadefor

No problem, I'll close my PR.

Ideally your PR will address the immediate issue with setting the correct user, hostname and port when reading from a .ssh/config file.

mfridman avatar Jun 14 '18 04:06 mfridman

It would be nice if SUP_HOST reflected Host and maybe SUP_HOSTNAME the actual endpoint from the ssh config HostName, but this would break compatibility with existing scripts I think

untoreh avatar Dec 01 '18 16:12 untoreh