Protect local Tailscale sign-in credentials
This commit is contained in:
+41
-1
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"flag"
|
||||
@@ -50,6 +51,45 @@ func serveCmd(args []string) {
|
||||
fatal("--listen must be a loopback address", "addr", *listenAddr)
|
||||
}
|
||||
|
||||
// Protect local credentials before tsnet can write state or a login URL.
|
||||
if err := os.MkdirAll(*dataDir, 0o700); err != nil {
|
||||
fatal("create data directory", "err", err)
|
||||
}
|
||||
if err := os.Chmod(*dataDir, 0o700); err != nil {
|
||||
fatal("protect data directory", "err", err)
|
||||
}
|
||||
// Keep ownership until shutdown; never unlink the lock file, since a new
|
||||
// inode would let another process lock the same data directory concurrently.
|
||||
lock, err := os.OpenFile(filepath.Join(*dataDir, "serve.lock"), os.O_CREATE|os.O_RDWR, 0o600)
|
||||
if err != nil {
|
||||
fatal("open service lock", "err", err)
|
||||
}
|
||||
defer lock.Close()
|
||||
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
|
||||
fatal("acquire service lock", "data", *dataDir, "err", err)
|
||||
}
|
||||
|
||||
token := rand.Text()
|
||||
if err := os.WriteFile(filepath.Join(*dataDir, "loopback-token"), []byte(token), 0o600); err != nil {
|
||||
fatal("write loopback credential", "err", err)
|
||||
}
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
fatal("home directory", "err", err)
|
||||
}
|
||||
logDir := filepath.Join(home, "Library", "Logs")
|
||||
if err := os.MkdirAll(logDir, 0o755); err != nil {
|
||||
fatal("create log directory", "err", err)
|
||||
}
|
||||
logFile, err := os.OpenFile(filepath.Join(logDir, "byre.log"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
|
||||
if err != nil {
|
||||
fatal("open service log", "err", err)
|
||||
}
|
||||
if err := logFile.Chmod(0o600); err != nil {
|
||||
fatal("protect service log", "err", err)
|
||||
}
|
||||
logFile.Close()
|
||||
|
||||
ts := &tsnet.Server{
|
||||
Dir: filepath.Join(*dataDir, "tsnet"),
|
||||
Hostname: *hostname,
|
||||
@@ -75,7 +115,7 @@ func serveCmd(args []string) {
|
||||
go updateDaily(ctx)
|
||||
|
||||
base := func(net.Listener) context.Context { return ctx }
|
||||
loopback := &http.Server{Addr: *listenAddr, Handler: srv.LoopbackHandler(), BaseContext: base}
|
||||
loopback := &http.Server{Addr: *listenAddr, Handler: srv.LoopbackHandler(token), BaseContext: base}
|
||||
tailnet := &http.Server{Handler: srv.Handler(), BaseContext: base}
|
||||
|
||||
go func() {
|
||||
|
||||
Reference in New Issue
Block a user