What version of Go are you using (go version)?
$ go version
go version go1.13.3 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN="/Users/pjt/projects/go/bin"
GOCACHE="/Users/pjt/Library/Caches/go-build"
GOENV="/Users/pjt/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/pjt/projects/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.13.3/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.13.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/p9/y23xtnms6r90wsl5lsz2tkfh0000gq/T/go-build606914329=/tmp/go-build -gno-record-gcc-switches -fno-common"
GOROOT/bin/go version: go version go1.13.3 darwin/amd64
GOROOT/bin/go tool compile -V: compile version go1.13.3
uname -v: Darwin Kernel Version 19.0.0: Thu Oct 17 16:17:15 PDT 2019; root:xnu-6153.41.3~29/RELEASE_X86_64
ProductName: Mac OS X
ProductVersion: 10.15.1
BuildVersion: 19B88
lldb --version: lldb-1100.0.30.11
Apple Swift version 5.1.3 (swiftlang-1100.0.282.1 clang-1100.0.33.15)
What did you do?
I'm trying to open an ssh connection to my-site.com:22 using ssh.Dial where the config uses the callback provided by knownhosts.New("~/.ssh/known_hosts"). I have a known_hosts file that looks like this:
my-site.com,host1.my-site.com,1.1.1.1 ecdsa-sha2-nistp256 <public-key-1>
my-site.com,host2.my-site.com,2.2.2.2 ecdsa-sha2-nistp256 <public-key-2>
What did you expect to see?
Connection succeeds when either public key is provided.
What did you see instead?
Connection only succeeds when I happen to connect to host1.my-site.com. If it tries to connect to host2.my-site.com I get a KeyError. I can connect to either host using the ssh program.
Why did this happen?
Using knownhosts.New to build a host key callback rejects some hosts from the known_hosts file when there are multiple Public Keys of the same type. There is the assertion in the knownhosts code which says "For each key algorithm, there can be one hostkey", which I don't believe is correct. I think we need to check keys from any line that matches the current host, rather than only ones that have key types we haven't seen yet.
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
I'm trying to open an ssh connection to
my-site.com:22usingssh.Dialwhere the config uses the callback provided byknownhosts.New("~/.ssh/known_hosts"). I have aknown_hostsfile that looks like this:What did you expect to see?
Connection succeeds when either public key is provided.
What did you see instead?
Connection only succeeds when I happen to connect to
host1.my-site.com. If it tries to connect tohost2.my-site.comI get aKeyError. I can connect to either host using thesshprogram.Why did this happen?
Using
knownhosts.Newto build a host key callback rejects some hosts from the known_hosts file when there are multiple Public Keys of the same type. There is the assertion in theknownhostscode which says "For each key algorithm, there can be one hostkey", which I don't believe is correct. I think we need to check keys from any line that matches the current host, rather than only ones that have key types we haven't seen yet.