net/dns: ignore permission errors on Synology DSM7 for now

Updates #4017

Change-Id: Ia7fd4df47588c010dea8e63d88f397cc8eb748e5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2022-02-23 09:25:14 -08:00 committed by Brad Fitzpatrick
parent 29279b34fa
commit 7d897229d9
2 changed files with 34 additions and 4 deletions

View File

@ -475,7 +475,20 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, dialer *tsdial.Dialer, na
return nil, false, fmt.Errorf("createBIRDClient: %w", err)
}
}
if !useNetstack {
if useNetstack {
if runtime.GOOS == "linux" && distro.Get() == distro.Synology {
// On Synology in netstack mode, still init a DNS
// manager (directManager) to avoid the health check
// warnings in 'tailscale status' about DNS base
// configuration being unavailable (from the noop
// manager). More in Issue 4017.
// TODO(bradfitz): add a Synology-specific DNS manager.
conf.DNS, err = dns.NewOSConfigurator(logf, "") // empty interface name
if err != nil {
return nil, false, fmt.Errorf("dns.NewOSConfigurator: %w", err)
}
}
} else {
dev, devName, err := tstun.New(logf, name)
if err != nil {
tstun.Diagnose(logf, name)

View File

@ -8,8 +8,10 @@ import (
"bytes"
"context"
"crypto/rand"
"errors"
"fmt"
"io"
"io/fs"
"io/ioutil"
"os"
"os/exec"
@ -22,6 +24,7 @@ import (
"tailscale.com/net/dns/resolvconffile"
"tailscale.com/types/logger"
"tailscale.com/util/dnsname"
"tailscale.com/version/distro"
)
const (
@ -245,28 +248,42 @@ func (m *directManager) rename(old, new string) error {
if err == nil {
return nil
}
if runtime.GOOS == "linux" && distro.Get() == distro.Synology {
// Fail fast. The fallback case below won't work anyway.
return err
}
m.logf("rename of %q to %q failed (%v), falling back to copy+delete", old, new, err)
m.renameBroken = true
}
bs, err := m.fs.ReadFile(old)
if err != nil {
return fmt.Errorf("reading %q to rename: %v", old, err)
return fmt.Errorf("reading %q to rename: %w", old, err)
}
if err := m.fs.WriteFile(new, bs, 0644); err != nil {
return fmt.Errorf("writing to %q in rename of %q: %v", new, old, err)
return fmt.Errorf("writing to %q in rename of %q: %w", new, old, err)
}
if err := m.fs.Remove(old); err != nil {
err2 := m.fs.Truncate(old)
if err2 != nil {
return fmt.Errorf("remove of %q failed (%v) and so did truncate: %v", old, err, err2)
return fmt.Errorf("remove of %q failed (%w) and so did truncate: %v", old, err, err2)
}
}
return nil
}
func (m *directManager) SetDNS(config OSConfig) (err error) {
defer func() {
if err != nil && errors.Is(err, fs.ErrPermission) && runtime.GOOS == "linux" &&
distro.Get() == distro.Synology && os.Geteuid() != 0 {
// On Synology (notably DSM7 where we don't run as root), ignore all
// DNS configuration errors for now. We don't have permission.
// See https://github.com/tailscale/tailscale/issues/4017
m.logf("ignoring SetDNS permission error on Synology (Issue 4017); was: %v", err)
err = nil
}
}()
var changed bool
if config.IsZero() {
changed, err = m.restoreBackup()