1

I have an alpine linux system which uses the musl libc and therefore has no /etc/nsswitch.conf.

According to tcpdump on this system, net.LookupIP("localhost") actually does a query for localhost.a.b.c, where a.b.c is taken from domain a.b.c in /etc/resolv.conf. But if I add an /etc/nsswitch.conf with hosts: files dns, it correctly looks up localhost from /etc/hosts.

As far as I can tell, no libc implementation tries to add a domain to localhost when looking it up in DNS. So (a) is there some good reason it's done this way or is it a bug? and (b) is there a way to work around it without adding an nsswitch.conf and while still using just the name localhost?

Edit More details:

ldd ./dnstest
    /lib/ld-musl-armhf.so.1 (0x76f2c000)
    libc.so => /lib/ld-musl-armhf.so.1 (0x76f2c000)

So yes, there is a dependency on libc.so. I have tried this with CGO_ENABLED=1 and with CGO_ENABLED=0 in the build commandline, too.

kostix
  • 51,517
  • 14
  • 93
  • 176
Tom
  • 7,269
  • 1
  • 42
  • 69
  • Is it _fully static_ build or not? IOW, does running `ldd ./that_binary` displays dependency on some `libc`? – kostix Jul 08 '19 at 14:56
  • 1
    I'm asking because by default the `net` package uses `libc` for name resolution; in fully static builds, a custom stub code is used. See [this](https://golang.org/pkg/net/#hdr-Name_Resolution) and [this](https://www.google.com/search?q=golang+cgo+resolver) in general. – kostix Jul 08 '19 at 14:58
  • Plus the go resolver will read resolv.conf and nsswitch.conf, as long as they don't specify any features that require the system resolver. – JimB Jul 08 '19 at 15:00
  • @kostix I've added some detail to the question. – Tom Jul 08 '19 at 15:13
  • If the binary is linked to libc, and this happens both with and without CGO regardless of `GODEBUG=netdns` settings, then it appears that both resolvers act identically. Without `hosts: files` in nsswitch, a linux system resolver is not going to read `/etc/hosts` first, which is where `localhost` is defined. – JimB Jul 08 '19 at 15:47
  • @JimB as far as I can tell, that's only true for GNU libc systems - other libc implementations don't use nsswitch.conf. – Tom Jul 08 '19 at 15:50
  • Even if it's only glibc, Go following the behavior of the most common resolver wouldn't be surprising, especially since that implementation was partly a concession to match existing system behaviors to begin with. Though it appears from your description here the musl resolver does the same? – JimB Jul 08 '19 at 16:09
  • After reading [this](https://wiki.musl-libc.org/functional-differences-from-glibc.html#Name-Resolver/DNS) I wonder what's the value of your `ndots` conf. variable? – kostix Jul 08 '19 at 17:10
  • @kostix ndots is not set in my resolv.conf. I think it defaults to 1. – Tom Jul 10 '19 at 14:49

1 Answers1

0

So currently, it still needs RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf as workaround to use alpine image as base image to run golang binary.

chestack
  • 71
  • 7