mirror of
https://github.com/tailscale/tailscale.git
synced 2026-07-28 08:16:28 -04:00
Add a new modular syslog feature providing a tailscaled --syslog flag that sends the daemon's logs to the system syslog daemon instead of stderr, which is useful when running as a daemon without a service manager that captures stderr (e.g. OpenWrt's procd). The feature package registers two new hooks: one to register its flag before flag parsing, and one that tailscaled calls early in main to redirect the standard library's default logger. Because logpolicy later points the default logger at logtail, whose local console copy writes to stderr, logpolicy now also consults the hook and sends its console copy to the same sink (with timestamps disabled, as syslog records its own). The feature is linked by default only on Linux, FreeBSD, and OpenBSD, and can be removed with the ts_omit_syslog build tag. If connecting to the syslog daemon fails at startup, tailscaled logs a warning and continues logging to stderr. Fixes #16270 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: I8f3a92d4c1e6b70a5d29e4f61b3c874250a9de13
104 lines
3.6 KiB
Go
104 lines
3.6 KiB
Go
// Copyright (c) Tailscale Inc & contributors
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package feature
|
|
|
|
import (
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"sync"
|
|
|
|
"tailscale.com/types/logger"
|
|
"tailscale.com/types/persist"
|
|
)
|
|
|
|
// HookRegisterLogSinkFlags is a hook for the syslog feature to register
|
|
// its flags (such as tailscaled's --syslog) with the process's default
|
|
// flag set. If set, tailscaled calls it before flag parsing.
|
|
var HookRegisterLogSinkFlags Hook[func()]
|
|
|
|
// HookLogSink is a hook for the syslog feature to redirect the process's
|
|
// logs to an alternate sink. If set, tailscaled calls it once early in
|
|
// main, after flag parsing; on that first call, if the user requested an
|
|
// alternate sink, it points the standard library's default logger at that
|
|
// sink. It returns the sink, or nil if logs are not being redirected.
|
|
// Later callers (such as logpolicy, which otherwise writes its console
|
|
// copy of logs to stderr) use the returned writer to send their logs to
|
|
// the same place.
|
|
var HookLogSink Hook[func() io.Writer]
|
|
|
|
// HookCanAutoUpdate is a hook for the clientupdate package
|
|
// to conditionally initialize.
|
|
var HookCanAutoUpdate Hook[func() bool]
|
|
|
|
var testAllowAutoUpdate = sync.OnceValue(func() bool {
|
|
return os.Getenv("TS_TEST_ALLOW_AUTO_UPDATE") == "1"
|
|
})
|
|
|
|
// CanAutoUpdate reports whether the current binary is built with auto-update
|
|
// support and, if so, whether the current platform supports it.
|
|
func CanAutoUpdate() bool {
|
|
if testAllowAutoUpdate() {
|
|
return true
|
|
}
|
|
if f, ok := HookCanAutoUpdate.GetOk(); ok {
|
|
return f()
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HookProxyFromEnvironment is a hook for feature/useproxy to register
|
|
// a function to use as http.ProxyFromEnvironment.
|
|
var HookProxyFromEnvironment Hook[func(*http.Request) (*url.URL, error)]
|
|
|
|
// HookProxyInvalidateCache is a hook for feature/useproxy to register
|
|
// [tshttpproxy.InvalidateCache].
|
|
var HookProxyInvalidateCache Hook[func()]
|
|
|
|
// HookProxyGetAuthHeader is a hook for feature/useproxy to register
|
|
// [tshttpproxy.GetAuthHeader].
|
|
var HookProxyGetAuthHeader Hook[func(*url.URL) (string, error)]
|
|
|
|
// HookProxySetSelfProxy is a hook for feature/useproxy to register
|
|
// [tshttpproxy.SetSelfProxy].
|
|
var HookProxySetSelfProxy Hook[func(...string)]
|
|
|
|
// HookProxySetTransportGetProxyConnectHeader is a hook for feature/useproxy to register
|
|
// [tshttpproxy.SetTransportGetProxyConnectHeader].
|
|
var HookProxySetTransportGetProxyConnectHeader Hook[func(*http.Transport)]
|
|
|
|
// HookTPMAvailable is a hook that reports whether a TPM device is supported
|
|
// and available.
|
|
var HookTPMAvailable Hook[func() bool]
|
|
|
|
var HookGenerateAttestationKeyIfEmpty Hook[func(p *persist.Persist, logf logger.Logf) (bool, error)]
|
|
|
|
// TPMAvailable reports whether a TPM device is supported and available.
|
|
func TPMAvailable() bool {
|
|
if f, ok := HookTPMAvailable.GetOk(); ok {
|
|
return f()
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HookGetSSHHostKeyPublicStrings is a hook for the ssh/hostkeys package to
|
|
// provide SSH host key public strings to ipn/ipnlocal without ipnlocal needing
|
|
// to import golang.org/x/crypto/ssh.
|
|
var HookGetSSHHostKeyPublicStrings Hook[func(varRoot string, logf logger.Logf) ([]string, error)]
|
|
|
|
// HookHardwareAttestationAvailable is a hook that reports whether hardware
|
|
// attestation is supported and available.
|
|
var HookHardwareAttestationAvailable Hook[func() bool]
|
|
|
|
// HardwareAttestationAvailable reports whether hardware attestation is
|
|
// supported and available (TPM on Windows/Linux, Secure Enclave on macOS|iOS,
|
|
// KeyStore on Android)
|
|
func HardwareAttestationAvailable() bool {
|
|
if f, ok := HookHardwareAttestationAvailable.GetOk(); ok {
|
|
return f()
|
|
}
|
|
return false
|
|
}
|