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

proposal: don't include cgo with net on Unix by default #25670

Closed
iangudger opened this issue May 31, 2018 · 6 comments
Closed

proposal: don't include cgo with net on Unix by default #25670

iangudger opened this issue May 31, 2018 · 6 comments

Comments

@iangudger
Copy link
Contributor

Currently, cgo is included by default with the net package on Unix systems when not cross-compiling to allow the use of libc DNS functions. If the pure Go resolver is sufficiently improved, it should be possible to not include cgo by default (cgo can still be an option).

The net package documentation lists a few cases where the cgo resolver is needed:

  • LOCALDOMAIN, RES_OPTIONS, HOSTALIASES environment variables
  • OS X
  • ASR_CONFIG environment variable on OpenBSD
  • mDNS
  • /etc/resolv.conf or /etc/nsswitch.conf specify the use of features that the Go resolver does not implement
  • .local domains

If we limit the scope to Unix minus darwin and openbsd, what is the minimum feature set that we need to implement in order to feel comfortable not including the cgo resolver by default?

/cc @rsc @mdempsky @mikioh @bradfitz

@gopherbot gopherbot added this to the Proposal milestone May 31, 2018
@bradfitz
Copy link
Contributor

What's the problem with including it? It's true that most users don't use it but if it's not there, that means the 0.1% or 5% of users who need (who only need it based on data available at run time on their own machine) will fail, and they'll need to recompile.

If your goal is to get rid of all cgo and only generate static binaries by default for Linux, then I assume you also want to modify os/user to not use libc?

I guess I don't see the advantage.

That doesn't mean we can't still improve the pure Go DNS resolver to handle more cases, for at least the popular & easy things. Once it gets down to esoteric, rare, complicated stuff, I'd just punt to libc if it's already there.

@iangudger
Copy link
Contributor Author

Yes, my goal is to generate static binaries by default for Linux. Modifying os/user to not use libc seems like a good idea as well.

@bradfitz
Copy link
Contributor

What does that help? If you want to generate static binaries, you can. But what's to gain by making it the default for everybody? Seems like it would only increase our support burden with bug reports of DNS and user lookups not working on weirder configs.

@iangudger
Copy link
Contributor Author

The cgo DNS resolver is disabled by default most of the time and must be explicitly enabled. Moving this from a runtime option to a compile time option doesn't seem like a big change to me. In fact, I would argue that the current state makes everyone who compiles binaries on Linux for Linux that use the net package pay in exchange for making things slightly easier for the tiny portion of people with a weird config.

I am not suggesting eliminating the option or even making this change with the current state of DNS in Go. I am asking what improvements would we need to make to the Go resolver in order to feel comfortable with moving the cgo/Go resolver option to purely a compile time option.

Here are some advantages that I think will be commonly appreciated:

Portability. Go binaries that link in libc are less portable than ones that don't. For example, Go binaries dynamically linked against libc compiled on Alpine won't work on Ubuntu and vice versa. This is because Alpine uses musl and most other distros use glibc. I recently ran into this when helping someone debug why their binaries built with the Google Cloud Container Builder didn't work elsewhere.

Cross compilation. Cross-compiling should result in the same binary (when possible) as you would get if you were compiling from the target OS/architecture. This isn't true for Go Linux binaries that include the net package without cgo explicitly disabled. I don't personally do a lot of cross compilation, but given the popularity of doing development for Linux servers on macOS, I would image that it is fairly common.

Security. glibc isn't known for a great security track record. While the code in os/user probably isn't a problem security-wise, using the libc DNS resolver absolutely could be. In fact, a quick survey of glibc CVEs found lots related to DNS.

@alexbrainman
Copy link
Member

@iangudger maybe https://dave.cheney.net/2016/01/18/cgo-is-not-go will help to make your case :-)

Alex

@rsc
Copy link
Contributor

rsc commented Jun 4, 2018

We need the cgo ability by default for all the reasons @bradfitz already listed. And the cost here is very small - if you really want static binaries it's easy to do CGO_ENABLED=0.

Note that nsswitch.conf includes the names of dynamically loaded C modules. Better to use the C library for that than somehow reinvent it ourselves.

@rsc rsc closed this as completed Jun 4, 2018
@golang golang locked and limited conversation to collaborators Jun 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants