Documentation ¶
Overview ¶
Package ipn implements the interactions between the Tailscale cloud control plane and the local network stack.
IPN is the abbreviated name for a Tailscale network. What's less clear is what it's an abbreviation for: Identified Private Network? IP Network? Internet Private Network? I Privately Network?
Index ¶
- Constants
- Variables
- func ReadMsg(r io.Reader) ([]byte, error)
- func SavePrefs(filename string, p *Prefs)
- func WriteMsg(w io.Writer, b []byte) error
- type Backend
- type BackendClient
- func (bc *BackendClient) FakeExpireAfter(x time.Duration)
- func (bc *BackendClient) GotNotifyMsg(b []byte)
- func (bc *BackendClient) Logout()
- func (bc *BackendClient) Quit() error
- func (bc *BackendClient) RequestEngineStatus()
- func (bc *BackendClient) SetPrefs(new *Prefs)
- func (bc *BackendClient) Start(opts Options) error
- func (bc *BackendClient) StartLoginInteractive()
- type BackendServer
- type Command
- type EngineStatus
- type FakeBackend
- type FakeExpireAfterArgs
- type FileStore
- type Handle
- func (h *Handle) AdminPageURL() string
- func (h *Handle) EngineStatus() EngineStatus
- func (h *Handle) Expiry() time.Time
- func (h *Handle) FakeExpireAfter(x time.Duration)
- func (h *Handle) LocalAddrs() []wgcfg.CIDR
- func (h *Handle) Logout()
- func (h *Handle) NetMap() *NetworkMap
- func (h *Handle) Prefs() *Prefs
- func (h *Handle) RequestEngineStatus()
- func (h *Handle) Reset()
- func (h *Handle) Start(opts Options) error
- func (h *Handle) StartLoginInteractive()
- func (h *Handle) State() State
- func (h *Handle) UpdatePrefs(updateFn func(p *Prefs))
- type LocalBackend
- func (b *LocalBackend) AdminPageURL() string
- func (b *LocalBackend) EngineStatus() EngineStatus
- func (b *LocalBackend) Expiry() time.Time
- func (b *LocalBackend) FakeExpireAfter(x time.Duration)
- func (b *LocalBackend) LocalAddrs() []wgcfg.CIDR
- func (b *LocalBackend) Logout()
- func (b *LocalBackend) NetMap() *controlclient.NetworkMap
- func (b *LocalBackend) Prefs() *Prefs
- func (b *LocalBackend) RequestEngineStatus()
- func (b *LocalBackend) SetDecompressor(fn func() (controlclient.Decompressor, error))
- func (b *LocalBackend) SetNetInfo(ni *tailcfg.NetInfo)
- func (b *LocalBackend) SetPrefs(new *Prefs)
- func (b *LocalBackend) Shutdown()
- func (b *LocalBackend) Start(opts Options) error
- func (b *LocalBackend) StartLoginInteractive()
- func (b *LocalBackend) State() State
- type MemoryStore
- type NetworkMap
- type NoArgs
- type Notify
- type Options
- type Prefs
- type SetPrefsArgs
- type StartArgs
- type State
- type StateKey
- type StateStore
Constants ¶
const ( NoState = State(iota) NeedsLogin NeedsMachineAuth Stopped Starting Running )
const MaxMessageSize = 1 << 20
MaxMessageSize is the maximum message size, in bytes.
Variables ¶
var ErrStateNotExist = errors.New("no state with given ID")
ErrStateNotExist is returned by StateStore.ReadState when the requested state ID doesn't exist.
Functions ¶
Types ¶
type Backend ¶
type Backend interface { // Start starts or restarts the backend, typically when a // frontend client connects. Start(Options) error // StartLoginInteractive requests to start a new interactive login // flow. This should trigger a new BrowseToURL notification // eventually. StartLoginInteractive() // Logout terminates the current login session and stops the // wireguard engine. Logout() // SetPrefs installs a new set of user preferences, including // WantRunning. This may cause the wireguard engine to // reconfigure or stop. SetPrefs(*Prefs) // RequestEngineStatus polls for an update from the wireguard // engine. Only needed if you want to display byte // counts. Connection events are emitted automatically without // polling. RequestEngineStatus() // FakeExpireAfter pretends that the current key is going to // expire after duration x. This is useful for testing GUIs to // make sure they react properly with keys that are going to // expire. FakeExpireAfter(x time.Duration) }
Backend is the interface between Tailscale frontends (e.g. cmd/tailscale, iOS/MacOS/Windows GUIs) and the tailscale backend (e.g. cmd/tailscaled) running on the same machine. (It has nothing to do with the interface between the backends and the cloud control plane.)
type BackendClient ¶
type BackendClient struct {
// contains filtered or unexported fields
}
func NewBackendClient ¶
func NewBackendClient(logf logger.Logf, sendCommandMsg func(jsonb []byte)) *BackendClient
func (*BackendClient) FakeExpireAfter ¶
func (bc *BackendClient) FakeExpireAfter(x time.Duration)
func (*BackendClient) GotNotifyMsg ¶
func (bc *BackendClient) GotNotifyMsg(b []byte)
func (*BackendClient) Logout ¶
func (bc *BackendClient) Logout()
func (*BackendClient) Quit ¶
func (bc *BackendClient) Quit() error
func (*BackendClient) RequestEngineStatus ¶
func (bc *BackendClient) RequestEngineStatus()
func (*BackendClient) SetPrefs ¶
func (bc *BackendClient) SetPrefs(new *Prefs)
func (*BackendClient) Start ¶
func (bc *BackendClient) Start(opts Options) error
func (*BackendClient) StartLoginInteractive ¶
func (bc *BackendClient) StartLoginInteractive()
type BackendServer ¶
type BackendServer struct { GotQuit bool // a Quit command was received // contains filtered or unexported fields }
func NewBackendServer ¶
func NewBackendServer(logf logger.Logf, b Backend, sendNotifyMsg func(b []byte)) *BackendServer
func (*BackendServer) GotCommand ¶
func (bs *BackendServer) GotCommand(cmd *Command) error
func (*BackendServer) GotCommandMsg ¶
func (bs *BackendServer) GotCommandMsg(b []byte) error
GotCommandMsg parses the incoming message b as a JSON Command and calls GotCommand with it.
func (*BackendServer) Reset ¶
func (bs *BackendServer) Reset() error
type Command ¶
type Command struct { Version string // Exactly one of the following must be non-nil. Quit *NoArgs Start *StartArgs StartLoginInteractive *NoArgs Logout *NoArgs SetPrefs *SetPrefsArgs RequestEngineStatus *NoArgs FakeExpireAfter *FakeExpireAfterArgs }
Command is a command message that is JSON encoded and sent by a frontend to a backend.
type EngineStatus ¶
type EngineStatus struct {
RBytes, WBytes wgengine.ByteCount
NumLive int
LivePeers map[tailcfg.NodeKey]wgengine.PeerStatus
}
EngineStatus contains WireGuard engine stats.
type FakeBackend ¶
type FakeBackend struct {
// contains filtered or unexported fields
}
func (*FakeBackend) FakeExpireAfter ¶
func (b *FakeBackend) FakeExpireAfter(x time.Duration)
func (*FakeBackend) Logout ¶
func (b *FakeBackend) Logout()
func (*FakeBackend) RequestEngineStatus ¶
func (b *FakeBackend) RequestEngineStatus()
func (*FakeBackend) SetPrefs ¶
func (b *FakeBackend) SetPrefs(new *Prefs)
func (*FakeBackend) Start ¶
func (b *FakeBackend) Start(opts Options) error
func (*FakeBackend) StartLoginInteractive ¶
func (b *FakeBackend) StartLoginInteractive()
type FakeExpireAfterArgs ¶
type FileStore ¶
type FileStore struct {
// contains filtered or unexported fields
}
FileStore is a StateStore that uses a JSON file for persistence.
func NewFileStore ¶
NewFileStore returns a new file store that persists to path.
type Handle ¶
type Handle struct {
// contains filtered or unexported fields
}
func (*Handle) AdminPageURL ¶
func (*Handle) EngineStatus ¶
func (h *Handle) EngineStatus() EngineStatus
func (*Handle) FakeExpireAfter ¶
func (*Handle) LocalAddrs ¶
func (*Handle) NetMap ¶
func (h *Handle) NetMap() *NetworkMap
func (*Handle) RequestEngineStatus ¶
func (h *Handle) RequestEngineStatus()
func (*Handle) StartLoginInteractive ¶
func (h *Handle) StartLoginInteractive()
func (*Handle) UpdatePrefs ¶
type LocalBackend ¶
type LocalBackend struct {
// contains filtered or unexported fields
}
LocalBackend is the scaffolding between the Tailscale cloud control plane and the local network stack, wiring up NetworkMap updates from the cloud to the local WireGuard engine.
func NewLocalBackend ¶
func NewLocalBackend(logf logger.Logf, logid string, store StateStore, e wgengine.Engine) (*LocalBackend, error)
NewLocalBackend returns a new LocalBackend that is ready to run, but is not actually running.
func (*LocalBackend) AdminPageURL ¶
func (b *LocalBackend) AdminPageURL() string
func (*LocalBackend) EngineStatus ¶
func (b *LocalBackend) EngineStatus() EngineStatus
func (*LocalBackend) Expiry ¶
func (b *LocalBackend) Expiry() time.Time
func (*LocalBackend) FakeExpireAfter ¶
func (b *LocalBackend) FakeExpireAfter(x time.Duration)
func (*LocalBackend) LocalAddrs ¶
func (b *LocalBackend) LocalAddrs() []wgcfg.CIDR
func (*LocalBackend) Logout ¶
func (b *LocalBackend) Logout()
NOTE(apenwarr): No easy way to persist logged-out status.
Maybe that's for the better; if someone logs out accidentally, rebooting will fix it.
func (*LocalBackend) NetMap ¶
func (b *LocalBackend) NetMap() *controlclient.NetworkMap
Note: return value may be nil, if we haven't received a netmap yet.
func (*LocalBackend) Prefs ¶
func (b *LocalBackend) Prefs() *Prefs
func (*LocalBackend) RequestEngineStatus ¶
func (b *LocalBackend) RequestEngineStatus()
func (*LocalBackend) SetDecompressor ¶
func (b *LocalBackend) SetDecompressor(fn func() (controlclient.Decompressor, error))
SetDecompressor sets a decompression function, which must be a zstd reader.
This exists because the iOS/Mac NetworkExtension is very resource constrained, and the zstd package is too heavy to fit in the constrained RSS limit.
func (*LocalBackend) SetNetInfo ¶
func (b *LocalBackend) SetNetInfo(ni *tailcfg.NetInfo)
func (*LocalBackend) SetPrefs ¶
func (b *LocalBackend) SetPrefs(new *Prefs)
func (*LocalBackend) Shutdown ¶
func (b *LocalBackend) Shutdown()
func (*LocalBackend) Start ¶
func (b *LocalBackend) Start(opts Options) error
func (*LocalBackend) StartLoginInteractive ¶
func (b *LocalBackend) StartLoginInteractive()
func (*LocalBackend) State ¶
func (b *LocalBackend) State() State
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore is a store that keeps state in memory only.
func (*MemoryStore) ReadState ¶
func (s *MemoryStore) ReadState(id StateKey) ([]byte, error)
ReadState implements the StateStore interface.
func (*MemoryStore) WriteState ¶
func (s *MemoryStore) WriteState(id StateKey, bs []byte) error
WriteState implements the StateStore interface.
type NetworkMap ¶
type NetworkMap = controlclient.NetworkMap
type Notify ¶
type Notify struct { Version string // version number of IPN backend ErrMessage *string // critical error message, if any LoginFinished *empty.Message // event: non-nil when login process succeeded State *State // current IPN state has changed Prefs *Prefs // preferences were changed NetMap *NetworkMap // new netmap received Engine *EngineStatus // wireguard engine stats BrowseToURL *string // UI should open a browser right now BackendLogID *string // public logtail id used by backend }
Notify is a communication from a backend (e.g. tailscaled) to a frontend (cmd/tailscale, iOS, macOS, Win Tasktray). In any given notification, any or all of these may be nil, meaning that they have not changed. They are JSON-encoded on the wire, despite the lack of struct tags.
type Options ¶
type Options struct { // FrontendLogID is the public logtail id used by the frontend. FrontendLogID string // StateKey and Prefs together define the state the backend should // use: // - StateKey=="" && Prefs!=nil: use Prefs for internal state, // don't persist changes in the backend. // - StateKey!="" && Prefs==nil: load the given backend-side // state and use/update that. // - StateKey!="" && Prefs!=nil: like the previous case, but do // an initial overwrite of backend state with Prefs. StateKey StateKey Prefs *Prefs // LegacyConfigPath optionally specifies the old-style relaynode // relay.conf location. If both LegacyConfigPath and StateKey are // specified and the requested state doesn't exist in the backend // store, the backend migrates the config from LegacyConfigPath. // // TODO(danderson): remove some time after the transition to // tailscaled is done. LegacyConfigPath string // Notify is called when backend events happen. Notify func(Notify) `json:"-"` }
type Prefs ¶
type Prefs struct { // ControlURL is the URL of the control server to use. ControlURL string // RouteAll specifies whether to accept subnet and default routes // advertised by other nodes on the Tailscale network. RouteAll bool // AllowSingleHosts specifies whether to install routes for each // node IP on the tailscale network, in addition to a route for // the whole network. // // TODO(danderson): why do we have this? It dumps a lot of stuff // into the routing table, and a single network route _should_ be // all that we need. But when I turn this off in my tailscaled, // packets stop flowing. What's up with that? AllowSingleHosts bool // CorpDNS specifies whether to install the Tailscale network's // DNS configuration, if it exists. CorpDNS bool // WantRunning indicates whether networking should be active on // this node. WantRunning bool // UsePacketFilter indicates whether to enforce centralized ACLs // on this node. If false, all traffic in and out of this node is // allowed. UsePacketFilter bool // AdvertiseRoutes specifies CIDR prefixes to advertise into the // Tailscale network as reachable through the current node. AdvertiseRoutes []wgcfg.CIDR // NotepadURLs is a debugging setting that opens OAuth URLs in // notepad.exe on Windows, rather than loading them in a browser. // // TODO(danderson): remove? NotepadURLs bool // DisableDERP prevents DERP from being used. DisableDERP bool // The Persist field is named 'Config' in the file for backward // compatibility with earlier versions. // TODO(apenwarr): We should move this out of here, it's not a pref. // We can maybe do that once we're sure which module should persist // it (backend or frontend?) Persist *controlclient.Persist `json:"Config"` }
Prefs are the user modifiable settings of the Tailscale node agent.
func LoadPrefs ¶
LoadLegacyPrefs loads a legacy relaynode config file into Prefs with sensible migration defaults set. If enforceDefaults is true, Prefs.RouteAll and Prefs.AllowSingleHosts are forced on.
func PrefsFromBytes ¶
PrefsFromBytes deserializes Prefs from a JSON blob. If enforceDefaults is true, Prefs.RouteAll and Prefs.AllowSingleHosts are forced on.
type SetPrefsArgs ¶
type SetPrefsArgs struct {
New *Prefs
}
type StateKey ¶
type StateKey string
StateKey is an opaque identifier for a set of LocalBackend state (preferences, private keys, etc.).
The reason we need this is that the Tailscale agent may be running on a multi-user machine, in a context where a single daemon is shared by several consecutive users. Ideally we would just use the username of the connected frontend as the StateKey.
However, on Windows, there seems to be no safe way to figure out the owning user of a process connected over IPC mechanisms (sockets, named pipes). So instead, on Windows, we use a capability-oriented system where the frontend generates a random identifier for itself, and uses that as the StateKey when talking to the backend. That way, while we can't identify an OS user by name, we can tell two different users apart, because they'll have different opaque state keys (and no access to each others's keys).
type StateStore ¶
type StateStore interface { // ReadState returns the bytes associated with ID. Returns (nil, // ErrStateNotExist) if the ID doesn't have associated state. ReadState(id StateKey) ([]byte, error) // WriteState saves bs as the state associated with ID. WriteState(id StateKey, bs []byte) error }
StateStore persists state, and produces it back on request.