Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It was very relevant to me a couple days ago, so I think it's not the case that Go programs that look up names link by default dynamically to libc, just for whatever that's worth to anyone.

(Our company, Fly.io, runs container images for customers on Firecracker microVMs around the world, and I had to build a DNS-dependent service, in Go, that runs directly from our (Rust) init and can't assume a libc exists).



The downside to Go shipping it's own implementation of DNS resolution is that on systems that support far more rich set of DNS options (such as split DNS based upon hostnames in macOS) is that it doesn't work if the binary is built with a pure Go implementation.

That leaves users annoyed, because sending all DNS into a VPN tunnel is not always an option.


If cgo is enabled (the usual case), Go uses libc for DNS if the configuration looks exotic enough that the pure-Go code wouldn't give the same results.

https://golang.org/pkg/net/#hdr-Name_Resolution


This is a long standing issue in various open source projects that use Go, where they want to ship static binaries.

Most recently, this happened with Concourse and it's Fly binary: https://github.com/concourse/concourse/issues/3691

The developers don't want to use CGO, or when they do use CGO they disable the net part... and now stuff doesn't work.

Projects have to specifically build with cgo enabled on macOS, or else it fails.


Is your Rust init private? What does it do?


Mostly just init stuff. We're transforming Docker containers (mostly) into standalone VMs, so it's doing all the scut work of taking a completely stripped-bare booted kernel and getting it to a state where you can run an arbitrary Linux program on it.

I wouldn't want to take the thread off on a huge tangent, it's just funny that this was just recently super relevant to me (it would have been problematic if DNS-dependent Go programs depended on libc, because right now I can't assume there's a libc binary to be dynamically linked to).

Bringing it back to Go and its (sometimes libc-dependent) DNS libraries: it is very annoying how fiddly it is to get a Go program to use an alternative DNS server.


Had a similar problem a couple years ago where I needed to use alternative DNS libraries to troubleshoot issues in a company's infrastructure.

Golang's rules for what implementation to use are found here: https://golang.org/pkg/net/#hdr-Name_Resolution

A really solid alternative DNS client implementation can be found here: https://github.com/miekg/dns. Real easy to read and vet compared to a few other libraries I ran into when working on this problem.


I'm currently in the process, right now, of writing a minimal init in Rust to do exactly the same thing. Is yours something you'd consider sharing?

The sum total of what I want to do: bring up loopback, bring up the one and only Ethernet interface, set up its IP and basic routing, run another program, and do some basic log reporting.


I hack on our init, but I didn't write it. So it's not my place to share it. And there's some us-specific stuff in it that wouldn't be super helpful to you. But you could definitely ask Jerome on our team; he's a super helpful guy, even if he's super quiet here (he's like the anti-me). One way or the other I'm sure we can help you get where you're going!


I reached out to Jerome. Thanks!


Feel free to follow up with Kurt, me or Michael if you don't get a quick response; Jerome is in Montreal and he may be buried under a mountain of snow and brown gravy.


If you can can control which DNS servers it talks to, implementing the DNS spec directly is a pretty trivial exercise to get full control. (If you can't, the main complexity is dealing with implementation quirks)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: