Skip to content

Commit

Permalink
net/dns: detect when resolvconf points to systemd-resolved.
Browse files Browse the repository at this point in the history
There are /etc/resolv.conf files out there where resolvconf wrote
the file but pointed to systemd-resolved as the nameserver.
We're better off handling those as systemd-resolved.

> # Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
> #     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
> # 127.0.0.53 is the systemd-resolved stub resolver.
> # run "systemd-resolve --status" to see details about the actual nameservers.

Fixes #3026
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
  • Loading branch information
DentonGentry committed Oct 18, 2021
1 parent e7eb46b commit 40b7c2e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
11 changes: 6 additions & 5 deletions net/dns/direct.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,12 @@ func (m directManager) readResolvConf() (OSConfig, error) {
// configuration in bs - one of "resolvconf", "systemd-resolved" or
// "NetworkManager", or "" if no known owner was found.
func resolvOwner(bs []byte) string {
likely := ""
b := bytes.NewBuffer(bs)
for {
line, err := b.ReadString('\n')
if err != nil {
return ""
return likely
}
line = strings.TrimSpace(line)
if line == "" {
Expand All @@ -106,15 +107,15 @@ func resolvOwner(bs []byte) string {
if line[0] != '#' {
// First non-empty, non-comment line. Assume the owner
// isn't hiding further down.
return ""
return likely
}

if strings.Contains(line, "systemd-resolved") {
return "systemd-resolved"
likely = "systemd-resolved"
} else if strings.Contains(line, "NetworkManager") {
return "NetworkManager"
likely = "NetworkManager"
} else if strings.Contains(line, "resolvconf") {
return "resolvconf"
likely = "resolvconf"
}
}
}
Expand Down
30 changes: 30 additions & 0 deletions net/dns/manager_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,36 @@ func TestLinuxDNSMode(t *testing.T) {
wantLog: "dns: [rc=resolved nm=no ret=systemd-resolved]",
want: "systemd-resolved",
},
{
// More than one user has had resolvconf write a config that points to
// systemd-resolved. We're better off using systemd-resolved.
// regression test for https://github.com/tailscale/tailscale/issues/3026
name: "allegedly_resolvconf_but_actually_systemd-resolved",
env: env(resolvDotConf(
"# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)",
"# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN",
"# 127.0.0.53 is the systemd-resolved stub resolver.",
"# run \"systemd-resolve --status\" to see details about the actual nameservers.",
"nameserver 127.0.0.53"),
resolvedRunning()),
wantLog: "dns: [rc=resolved nm=no ret=systemd-resolved]",
want: "systemd-resolved",
},
{
// More than one user has had resolvconf write a config that points to
// systemd-resolved. We're better off using systemd-resolved.
// ...but what if systemd-resolved isn't running?
// regression test for https://github.com/tailscale/tailscale/issues/3026
name: "allegedly_resolvconf_but_actually_systemd-resolved_but_not_really",
env: env(resolvDotConf(
"# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)",
"# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN",
"# 127.0.0.53 is the systemd-resolved stub resolver.",
"# run \"systemd-resolve --status\" to see details about the actual nameservers.",
"nameserver 127.0.0.53")),
wantLog: "dns: [rc=resolved resolved=no ret=direct]",
want: "direct",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down

0 comments on commit 40b7c2e

Please sign in to comment.