mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-05 20:26:47 +02:00
net/dns: make directManager use /tmp/resolv.conf on gokrazy
Appliances built using https://gokrazy.org/ have a read-only root file system, including /etc/resolv.conf, which is a symlink to /tmp/resolv.conf. The system’s dhcp client overwrites /tmp/resolv.conf instead, so we need to use this path in Tailscale, too. Fixes #8689 Updates gokrazy/gokrazy#209 Co-authored-by: Michael Stapelberg <michael@stapelberg.de> Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
453620dca1
commit
6dc3d6f787
@ -28,8 +28,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
backupConf = "/etc/resolv.pre-tailscale-backup.conf"
|
||||
resolvConf = "/etc/resolv.conf"
|
||||
defaultBackupConf = "/etc/resolv.pre-tailscale-backup.conf"
|
||||
defaultResolvConf = "/etc/resolv.conf"
|
||||
)
|
||||
|
||||
// writeResolvConf writes DNS configuration in resolv.conf format to the given writer.
|
||||
@ -132,6 +132,9 @@ type directManager struct {
|
||||
// but is better than having non-functioning DNS.
|
||||
renameBroken bool
|
||||
|
||||
resolvConf string // usually "/etc/resolv.conf"
|
||||
backupConf string // usually "/etc/resolv.pre-tailscale-backup.conf"
|
||||
|
||||
ctx context.Context // valid until Close
|
||||
ctxClose context.CancelFunc // closes ctx
|
||||
|
||||
@ -147,10 +150,16 @@ func newDirectManager(logf logger.Logf) *directManager {
|
||||
func newDirectManagerOnFS(logf logger.Logf, fs wholeFileFS) *directManager {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
m := &directManager{
|
||||
logf: logf,
|
||||
fs: fs,
|
||||
ctx: ctx,
|
||||
ctxClose: cancel,
|
||||
logf: logf,
|
||||
fs: fs,
|
||||
ctx: ctx,
|
||||
ctxClose: cancel,
|
||||
resolvConf: defaultResolvConf,
|
||||
backupConf: defaultBackupConf,
|
||||
}
|
||||
if distro.Get() == distro.Gokrazy {
|
||||
m.resolvConf = "/tmp/resolv.conf"
|
||||
m.backupConf = "/tmp/resolv.pre-tailscale-backup.conf"
|
||||
}
|
||||
go m.runFileWatcher()
|
||||
return m
|
||||
@ -167,7 +176,7 @@ func (m *directManager) readResolvFile(path string) (OSConfig, error) {
|
||||
// ownedByTailscale reports whether /etc/resolv.conf seems to be a
|
||||
// tailscale-managed file.
|
||||
func (m *directManager) ownedByTailscale() (bool, error) {
|
||||
isRegular, err := m.fs.Stat(resolvConf)
|
||||
isRegular, err := m.fs.Stat(m.resolvConf)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
@ -177,7 +186,7 @@ func (m *directManager) ownedByTailscale() (bool, error) {
|
||||
if !isRegular {
|
||||
return false, nil
|
||||
}
|
||||
bs, err := m.fs.ReadFile(resolvConf)
|
||||
bs, err := m.fs.ReadFile(m.resolvConf)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@ -190,11 +199,11 @@ func (m *directManager) ownedByTailscale() (bool, error) {
|
||||
// backupConfig creates or updates a backup of /etc/resolv.conf, if
|
||||
// resolv.conf does not currently contain a Tailscale-managed config.
|
||||
func (m *directManager) backupConfig() error {
|
||||
if _, err := m.fs.Stat(resolvConf); err != nil {
|
||||
if _, err := m.fs.Stat(m.resolvConf); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// No resolv.conf, nothing to back up. Also get rid of any
|
||||
// existing backup file, to avoid restoring something old.
|
||||
m.fs.Remove(backupConf)
|
||||
m.fs.Remove(m.backupConf)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
@ -208,11 +217,11 @@ func (m *directManager) backupConfig() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return m.rename(resolvConf, backupConf)
|
||||
return m.rename(m.resolvConf, m.backupConf)
|
||||
}
|
||||
|
||||
func (m *directManager) restoreBackup() (restored bool, err error) {
|
||||
if _, err := m.fs.Stat(backupConf); err != nil {
|
||||
if _, err := m.fs.Stat(m.backupConf); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// No backup, nothing we can do.
|
||||
return false, nil
|
||||
@ -223,7 +232,7 @@ func (m *directManager) restoreBackup() (restored bool, err error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
_, err = m.fs.Stat(resolvConf)
|
||||
_, err = m.fs.Stat(m.resolvConf)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return false, err
|
||||
}
|
||||
@ -232,12 +241,12 @@ func (m *directManager) restoreBackup() (restored bool, err error) {
|
||||
if resolvConfExists && !owned {
|
||||
// There's already a non-tailscale config in place, get rid of
|
||||
// our backup.
|
||||
m.fs.Remove(backupConf)
|
||||
m.fs.Remove(m.backupConf)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// We own resolv.conf, and a backup exists.
|
||||
if err := m.rename(backupConf, resolvConf); err != nil {
|
||||
if err := m.rename(m.backupConf, m.resolvConf); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@ -307,7 +316,7 @@ func (m *directManager) checkForFileTrample() {
|
||||
return
|
||||
}
|
||||
|
||||
cur, err := m.fs.ReadFile(resolvConf)
|
||||
cur, err := m.fs.ReadFile(m.resolvConf)
|
||||
if err != nil {
|
||||
m.logf("trample: read error: %v", err)
|
||||
return
|
||||
@ -365,7 +374,7 @@ func (m *directManager) SetDNS(config OSConfig) (err error) {
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
writeResolvConf(buf, config.Nameservers, config.SearchDomains)
|
||||
if err := m.atomicWriteFile(m.fs, resolvConf, buf.Bytes(), 0644); err != nil {
|
||||
if err := m.atomicWriteFile(m.fs, m.resolvConf, buf.Bytes(), 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -414,9 +423,9 @@ func (m *directManager) GetBaseConfig() (OSConfig, error) {
|
||||
if err != nil {
|
||||
return OSConfig{}, err
|
||||
}
|
||||
fileToRead := resolvConf
|
||||
fileToRead := m.resolvConf
|
||||
if owned {
|
||||
fileToRead = backupConf
|
||||
fileToRead = m.backupConf
|
||||
}
|
||||
|
||||
return m.readResolvFile(fileToRead)
|
||||
@ -429,7 +438,7 @@ func (m *directManager) Close() error {
|
||||
// things. Clean it up if it's still there.
|
||||
m.fs.Remove("/etc/resolv.tailscale.conf")
|
||||
|
||||
if _, err := m.fs.Stat(backupConf); err != nil {
|
||||
if _, err := m.fs.Stat(m.backupConf); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// No backup, nothing we can do.
|
||||
return nil
|
||||
@ -440,7 +449,7 @@ func (m *directManager) Close() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = m.fs.Stat(resolvConf)
|
||||
_, err = m.fs.Stat(m.resolvConf)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
@ -449,12 +458,12 @@ func (m *directManager) Close() error {
|
||||
if resolvConfExists && !owned {
|
||||
// There's already a non-tailscale config in place, get rid of
|
||||
// our backup.
|
||||
m.fs.Remove(backupConf)
|
||||
m.fs.Remove(m.backupConf)
|
||||
return nil
|
||||
}
|
||||
|
||||
// We own resolv.conf, and a backup exists.
|
||||
if err := m.rename(backupConf, resolvConf); err != nil {
|
||||
if err := m.rename(m.backupConf, m.resolvConf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ func (m *directManager) runFileWatcher() {
|
||||
}
|
||||
var match bool
|
||||
for _, ev := range events {
|
||||
if ev.Name == resolvConf {
|
||||
if ev.Name == m.resolvConf {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
|
||||
@ -121,7 +121,7 @@ func dnsMode(logf logger.Logf, env newOSConfigEnv) (ret string, err error) {
|
||||
dbg("resolved-ping", "yes")
|
||||
}
|
||||
|
||||
bs, err := env.fs.ReadFile(resolvConf)
|
||||
bs, err := env.fs.ReadFile(defaultResolvConf)
|
||||
if os.IsNotExist(err) {
|
||||
dbg("rc", "missing")
|
||||
return "direct", nil
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user