resolvconf_path.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package resolvconf
  2. import (
  3. "context"
  4. "net/netip"
  5. "sync"
  6. "github.com/containerd/log"
  7. )
  8. const (
  9. // defaultPath is the default path to the resolv.conf that contains information to resolve DNS. See Path().
  10. defaultPath = "/etc/resolv.conf"
  11. // alternatePath is a path different from defaultPath, that may be used to resolve DNS. See Path().
  12. alternatePath = "/run/systemd/resolve/resolv.conf"
  13. )
  14. // For Path to detect systemd (only needed for legacy networking).
  15. var (
  16. detectSystemdResolvConfOnce sync.Once
  17. pathAfterSystemdDetection = defaultPath
  18. )
  19. // Path returns the path to the resolv.conf file that libnetwork should use.
  20. //
  21. // When /etc/resolv.conf contains 127.0.0.53 as the only nameserver, then
  22. // it is assumed systemd-resolved manages DNS. Because inside the container 127.0.0.53
  23. // is not a valid DNS server, Path() returns /run/systemd/resolve/resolv.conf
  24. // which is the resolv.conf that systemd-resolved generates and manages.
  25. // Otherwise Path() returns /etc/resolv.conf.
  26. //
  27. // Errors are silenced as they will inevitably resurface at future open/read calls.
  28. //
  29. // More information at https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html#/etc/resolv.conf
  30. //
  31. // TODO(robmry) - alternatePath is only needed for legacy networking ...
  32. //
  33. // Host networking can use the host's resolv.conf as-is, and with an internal
  34. // resolver it's also possible to use nameservers on the host's loopback
  35. // interface. Once legacy networking is removed, this can always return
  36. // defaultPath.
  37. func Path() string {
  38. detectSystemdResolvConfOnce.Do(func() {
  39. rc, err := Load(defaultPath)
  40. if err != nil {
  41. // silencing error as it will resurface at next calls trying to read defaultPath
  42. return
  43. }
  44. ns := rc.nameServers
  45. if len(ns) == 1 && ns[0] == netip.MustParseAddr("127.0.0.53") {
  46. pathAfterSystemdDetection = alternatePath
  47. log.G(context.TODO()).Infof("detected 127.0.0.53 nameserver, assuming systemd-resolved, so using resolv.conf: %s", alternatePath)
  48. }
  49. })
  50. return pathAfterSystemdDetection
  51. }