rig
rig copied to clipboard
Connection issue with keys
Hey 👋 - first off, wanted to say thanks for rig. I found it super nice to work with when I automated a couple checks.
There's one issue I ran into, when I try connecting the first time, it seems to expect the key to be loaded in the ssh-agent. So once I manually ssh in using the key it works.
Is there a way to not rely on the agent?
Yeah I think there's something messed up in the agent/keypath handling, but it has become such a bowl of spaghetti that it's very difficult to make any changes, so I'm slowly trying to simplify the logic and codebase in the v2 branch.
You can just os.Unsetenv("SSH_AUTH_SOCK") before connecting and the agent won't be used.
@kke I am happy to wait for v2. It's not a huge deal. Works well enough most of the time. 😅
@kke with the last v0.x update, this stopped working again all together.
I am building the connection like so:
connection := rig.Connection{
SSH: &rig.SSH{
Address: nodeIP,
User: "core",
KeyPath: &publicKey,
Bastion: &rig.SSH{
Address: "IP.ADDRESS_HERE",
User: "bastion",
KeyPath: &publicKey,
},
},
}
This used to work: SSH_AUTH_SOCK= go run main.go — but it doesn't anymore. Just fails with:
not connected: client connect: can't connect: create config: can't connect: no usable authentication method found
The trace log:
TRACE discovering global default keypaths
TRACE global default keypaths from ssh config: [/Users/till/.ssh/id_rsa]
TRACE [ssh] bastion.ip:22: trying to get a keyfile path from ssh config
TRACE [ssh] bastion.ip:22: detected 5 identity file paths from ssh config: [~/.ssh/id_dsa ~/.ssh/id_ecdsa ~/.ssh/id_ed25519 ~/.ssh/id_rsa ~/.ssh/identity]
TRACE [ssh] bastion.ip:22: ~/.ssh/id_dsa: invalid path: stat /Users/till/.ssh/id_dsa: no such file or directory
TRACE [ssh] bastion.ip:22: ~/.ssh/id_ecdsa: invalid path: stat /Users/till/.ssh/id_ecdsa: no such file or directory
TRACE [ssh] bastion.ip:22: ~/.ssh/id_ed25519: invalid path: stat /Users/till/.ssh/id_ed25519: no such file or directory
DEBUG [ssh] bastion.ip:22: using identity file /Users/till/.ssh/id_rsa
TRACE [ssh] bastion.ip:22: ~/.ssh/identity: invalid path: stat /Users/till/.ssh/identity: no such file or directory
TRACE [ssh] node.ip:22: trying to get a keyfile path from ssh config
TRACE [ssh] node.ip:22: detected 5 identity file paths from ssh config: [~/.ssh/id_dsa ~/.ssh/id_ecdsa ~/.ssh/id_ed25519 ~/.ssh/id_rsa ~/.ssh/identity]
TRACE [ssh] node.ip:22: ~/.ssh/id_dsa: invalid path: stat /Users/till/.ssh/id_dsa: no such file or directory
TRACE [ssh] node.ip:22: ~/.ssh/id_ecdsa: invalid path: stat /Users/till/.ssh/id_ecdsa: no such file or directory
TRACE [ssh] node.ip:22: ~/.ssh/id_ed25519: invalid path: stat /Users/till/.ssh/id_ed25519: no such file or directory
DEBUG [ssh] node.ip:22: using identity file /Users/till/.ssh/id_rsa
TRACE [ssh] node.ip:22: ~/.ssh/identity: invalid path: stat /Users/till/.ssh/identity: no such file or directory
DEBUG [ssh] node.ip:22: HashKnownHosts is set to "no", won't hash newly added keys
TRACE [ssh] node.ip:22: using known_hosts file from ssh config /Users/till/.ssh/known_hosts
TRACE [ssh] node.ip:22: failed to get ssh agent client: connect ssh agent: SSH_AUTH_SOCK is not set
TRACE [ssh] node.ip:22: checking identity file /Users/till/.ssh/id_rsa
DEBUG [ssh] node.ip:22: key /Users/till/.ssh/id_rsa is encrypted
DEBUG [ssh] node.ip:22: failed to obtain a signer for identity /Users/till/.ssh/id_rsa: can't connect: can't parse keyfile: /Users/till/.ssh/id_rsa: ssh: this private key is passphrase protected
None of these keys should be enumerated on since I am setting KeyPath?
I rebuild it with OpenSSH — must be newish? And that works when I supply an external ssh config file. :)
Yes something must be broken or could publicKey be ""? That's the only way I can think of how it could go to "trying to get a keyfile path from ssh config":
func (c *SSH) keypathsFromConfig() []string {
log.Tracef("%s: trying to get a keyfile path from ssh config", c)
...
}
// SetDefaults sets various default values
func (c *SSH) SetDefaults() {
c.once.Do(func() {
if c.KeyPath != nil && *c.KeyPath != "" {
if expanded, err := expandAndValidatePath(*c.KeyPath); err == nil {
c.keyPaths = append(c.keyPaths, expanded)
}
// keypath is explicitly set, accept the fact even if it's invalid and
// don't try to find it from ssh config/defaults
return // <--- it should get out here
}
c.KeyPath = nil
paths := c.keypathsFromConfig() // <--- this outputs the "trying to...."
....
}