Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: host lookup on non-GNU-libc systems #33019

Open
tomkcook opened this issue Jul 10, 2019 · 1 comment
Milestone

Comments

@tomkcook
Copy link

@tomkcook tomkcook commented Jul 10, 2019

What version of Go are you using (go version)?

$ go version
go version go1.12.6 linux/arm

Does this issue reproduce with the latest release?

Not tested on 1.12.7 but I don't believe any of the tickets included between 1.12.6 and 1.12.7 affect this issue.

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="arm"
GOBIN=""
GOCACHE="/home/vsys/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/vsys/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_arm"
GCCGO="gccgo"
GOARM="6"
CC="gcc"
CXX="g++"
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 -marm -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build834352528=/tmp/go-build -gno-record-gcc-switches"

What did you do?

package main

import (
	"net"
	"fmt"
	"os"
)

func main() {
	ips, err := net.LookupIP("localhost")
	if err != nil {
		fmt.Fprintf(os.Stderr, "Could not get IPs: %v\n", err)
		os.Exit(1)
	}
	for _, ip := range ips {
		fmt.Printf("localhost. IN A %s\n", ip.String())
	}
}

The above program gives the wrong address for localhost if:

  • The system does not use GNU libc AND
  • The combination of the DNS server configured on the system and the system's default domain do not produce a correct result for localhost.

The system where this was observed is running Alpine Linux 3.9. This uses the musl libc. This libc does not support /etc/nsswitch.conf and so that file is usually missing.

On this type of system, it seems that golang's name resolution code looks for /etc/nsswitch.conf, doesn't find it, and then defaults to DNS only, skipping any lookup in /etc/hosts. The DNS query that is sent is not for localhost but for localhost.x.y.z where x.y.z is the domain setting from resolv.conf.

If the configured DNS server produces a correct response for localhost.x.y.z then all is still well, but if it doesn't then lookup fails (or even worse, as below, returns an address for another host).

My suggestion is that golang on musl libc systems should follow the musl libc convention, which is to check /etc/hosts first and then DNS.

A workaround is to add a file /etc/nsswitch.conf that specifies hosts: files dns.

What did you expect to see?

On a system with IPv6 enabled:

localhost. IN A ::1
localhost. IN A 127.0.0.1

What did you see instead?

The exact output varies with the environment where it is run, but eg:

localhost. IN A 192.64.119.254
@ianlancetaylor ianlancetaylor changed the title net host lookup on non-GNU-libc systems net: host lookup on non-GNU-libc systems Jul 10, 2019
@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jul 10, 2019

When using glibc the default when there is no /etc/nsswitch.conf is dns [!UNAVAIL=return] files, according to https://www.gnu.org/software/libc/manual/html_node/Notes-on-NSS-Configuration-File.html. It sounds like you are saying that musl behaves differently. That seems unfortunate.

You can force the use of the C resolver by setting GODEBUG=netdns=cgo. I guess we could consider adding a GODEBUG setting that looks at /etc/hosts first and then falls back to the Go resolver.

I'm not excited about doing a run-time test for whether we are using musl.

@ianlancetaylor ianlancetaylor added this to the Go1.14 milestone Jul 10, 2019
@rsc rsc modified the milestones: Go1.14, Backlog Oct 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.