ipn{,/localapi,ipnlocal}: infer cert dir from state file location

This fixes "tailscale cert" on Synology where the var directory is
typically like /volume2/@appdata/Tailscale, or any other tailscaled
user who specifies a non-standard state file location.

This is a interim fix on the way to #2932.

Fixes #2927
Updates #2932

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/2946/head
Brad Fitzpatrick 3 years ago committed by Brad Fitzpatrick
parent 29fa8c17d2
commit 3b3994f0db

@ -1935,14 +1935,29 @@ func normalizeResolver(cfg dnstype.Resolver) dnstype.Resolver {
return cfg
}
// tailscaleVarRoot returns the root directory of Tailscale's writable
// TailscaleVarRoot returns the root directory of Tailscale's writable
// storage area. (e.g. "/var/lib/tailscale")
func tailscaleVarRoot() string {
//
// It returns an empty string if there's no configured or discovered
// location.
func (b *LocalBackend) TailscaleVarRoot() string {
switch runtime.GOOS {
case "ios", "android":
dir, _ := paths.AppSharedDir.Load().(string)
return dir
}
// Temporary (2021-09-27) transitional fix for #2927 (Synology
// cert dir) on the way towards a more complete fix
// (#2932). It fixes any case where the state file is provided
// to tailscaled explicitly when it's not in the default
// location.
if fs, ok := b.store.(*ipn.FileStore); ok {
if fp := fs.Path(); fp != "" {
if dir := filepath.Dir(fp); strings.EqualFold(filepath.Base(dir), "tailscale") {
return dir
}
}
}
stateFile := paths.DefaultTailscaledStateFile()
if stateFile == "" {
return ""
@ -1954,7 +1969,7 @@ func (b *LocalBackend) fileRootLocked(uid tailcfg.UserID) string {
if v := b.directFileRoot; v != "" {
return v
}
varRoot := tailscaleVarRoot()
varRoot := b.TailscaleVarRoot()
if varRoot == "" {
b.logf("peerapi disabled; no state directory")
return ""

@ -36,7 +36,6 @@ import (
"golang.org/x/crypto/acme"
"tailscale.com/ipn/ipnstate"
"tailscale.com/paths"
"tailscale.com/types/logger"
)
@ -53,11 +52,11 @@ var (
)
func (h *Handler) certDir() (string, error) {
base := paths.DefaultTailscaledStateFile()
if base == "" {
return "", errors.New("no default DefaultTailscaledStateFile")
d := h.b.TailscaleVarRoot()
if d == "" {
return "", errors.New("no TailscaleVarRoot")
}
full := filepath.Join(filepath.Dir(base), "certs")
full := filepath.Join(d, "certs")
if err := os.MkdirAll(full, 0700); err != nil {
return "", err
}

@ -166,6 +166,9 @@ type FileStore struct {
cache map[StateKey][]byte
}
// Path returns the path that NewFileStore was called with.
func (s *FileStore) Path() string { return s.path }
func (s *FileStore) String() string { return fmt.Sprintf("FileStore(%q)", s.path) }
// NewFileStore returns a new file store that persists to path.

Loading…
Cancel
Save