net/dns: properly detect newer debian resolvconf

Tailscale attempts to determine if resolvconf or openresolv
is in use by running `resolvconf --version`, under the assumption
this command will error when run with Debian's resolvconf. This
assumption is no longer true and leads to the wrong commands being
run on newer versions of Debian with resolvconf >= 1.90. We can
now check if the returned version string starts with "Debian resolvconf"
if the command is successful.

Fixes #9218

Signed-off-by: Galen Guyer <galen@galenguyer.com>
This commit is contained in:
Galen Guyer 2023-10-11 11:08:08 -04:00 committed by Brad Fitzpatrick
parent 4e083e4548
commit 04a8b8bb8e
1 changed files with 6 additions and 1 deletions

View File

@ -6,6 +6,7 @@
package dns package dns
import ( import (
"bytes"
"os/exec" "os/exec"
) )
@ -13,13 +14,17 @@ func resolvconfStyle() string {
if _, err := exec.LookPath("resolvconf"); err != nil { if _, err := exec.LookPath("resolvconf"); err != nil {
return "" return ""
} }
if _, err := exec.Command("resolvconf", "--version").CombinedOutput(); err != nil { output, err := exec.Command("resolvconf", "--version").CombinedOutput()
if err != nil {
// Debian resolvconf doesn't understand --version, and // Debian resolvconf doesn't understand --version, and
// exits with a specific error code. // exits with a specific error code.
if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 99 { if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 99 {
return "debian" return "debian"
} }
} }
if bytes.HasPrefix(output, []byte("Debian resolvconf")) {
return "debian"
}
// Treat everything else as openresolv, by far the more popular implementation. // Treat everything else as openresolv, by far the more popular implementation.
return "openresolv" return "openresolv"
} }