Documentation
¶
Overview ¶
Package tailscale connects an existing wgo device to a Tailscale-compatible control plane without taking ownership of the device, TUN, or operating system network configuration.
Every control, DNS, STUN, DISCO, and DERP socket or lookup made by the package is performed through the gonnect.Network supplied to New. Direct peer traffic uses that network by default, but Options can leave direct endpoints on wgo's default transport. The client reads the wgo device's existing private key and never generates, replaces, or rotates it.
Index ¶
- Constants
- Variables
- type ACLDestination
- type ACLRule
- type ACLView
- type CacheCallbacks
- type Client
- func (c *Client) ACL() ACLView
- func (c *Client) ACLAllows(source, destination netip.Addr, protocol int, port uint16) bool
- func (c *Client) ACLFirewallConfig() *gonnect.FirewallConfig
- func (c *Client) Close() error
- func (c *Client) ConfirmPeer(ctx context.Context, id string) error
- func (c *Client) CurrentInteraction() *Interaction
- func (c *Client) DERP() DERPView
- func (c *Client) DNS() DNSView
- func (c *Client) DesiredNetworkConfiguration() NetworkConfiguration
- func (c *Client) Done() <-chan struct{}
- func (c *Client) Info() ClientInfo
- func (c *Client) Peer(id string) (PeerInfo, bool)
- func (c *Client) Peers() []PeerInfo
- func (c *Client) Resolver() *MagicDNSResolver
- func (c *Client) ResumeInteraction(id uint64) error
- func (c *Client) RevokePeerConfirmation(ctx context.Context, id string) error
- func (c *Client) Snapshot() Snapshot
- func (c *Client) Start(parent context.Context) error
- func (c *Client) State() State
- func (c *Client) Subscribe(buffer int) (<-chan Event, func())
- func (c *Client) Wait() error
- type ClientInfo
- type ConfirmationState
- type DERPLatencySource
- type DERPNode
- type DERPRegion
- type DERPView
- type DNSRecord
- type DNSView
- type Event
- type EventKind
- type Interaction
- type InteractionKind
- type LocalEndpoint
- type MagicDNSResolver
- type NetworkConfiguration
- type NodeInfo
- type Options
- type PathKind
- type PeerInfo
- type PortRange
- type Route
- type Snapshot
- type State
- type UserProfile
- type WGODevice
Constants ¶
const ( // DefaultControlURL is the hosted Tailscale coordination service. DefaultControlURL = "https://controlplane.tailscale.com" // DefaultTransportID is the named wgo transport owned by a Client. DefaultTransportID device.TransportID = "tailscale" )
Variables ¶
var ( ErrAlreadyStarted = errors.New("tailscale: client already started") ErrNotStarted = errors.New("tailscale: client not started") ErrClosed = errors.New("tailscale: client closed") ErrZeroNodeKey = errors.New("tailscale: wgo device has no private node key") ErrNodeIdentityChanged = errors.New("tailscale: cached node identity does not match the wgo device") ErrControlNodeKeyMismatch = errors.New("tailscale: control returned a self node key that does not match the wgo device") ErrNodeKeyExpired = errors.New("tailscale: control requires node-key rotation, but the wgo device key is immutable to this client") ErrPeerNotFound = errors.New("tailscale: peer not found") ErrPeerConflict = errors.New("tailscale: peer public key is already owned by another wgo controller") ErrInteractionNotFound = errors.New("tailscale: interaction not found") )
Functions ¶
This section is empty.
Types ¶
type ACLDestination ¶
type ACLRule ¶
type ACLRule struct {
SourceIPs []string
SourceBits []int
Destinations []ACLDestination
IPProtocols []int
CapabilityGrants []json.RawMessage
}
type ACLView ¶
type ACLView struct {
// Rules is the deterministic, name-sorted flattening used by ACLAllows.
Rules []ACLRule
// NamedRules preserves control's PacketFilters chunks. The legacy
// PacketFilter field is represented by the "base" chunk.
NamedRules map[string][]ACLRule
Revision uint64
}
ACLView is the latest packet filter delivered by control. It is descriptive; this library does not install or enforce OS firewall rules.
func (ACLView) FirewallConfig ¶
func (view ACLView) FirewallConfig() *gonnect.FirewallConfig
FirewallConfig converts view to a gonnect incoming firewall policy. Capability grants have no FirewallConfig equivalent and are not included.
type CacheCallbacks ¶
type CacheCallbacks struct {
Load func(context.Context) ([]byte, error)
Store func(context.Context, []byte) error
}
CacheCallbacks persist private machine/discovery identity and peer confirmations. The blob is versioned JSON owned by this package. Callbacks must treat it as sensitive data and replace it atomically. Calls are serialized; a Store callback may inspect the client but must not re-enter a confirmation method.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client coordinates one Tailscale control-plane identity with one named transport and a set of peers on an existing wgo device. It never changes the device private key and never owns the device lifecycle.
func New ¶
New constructs a client. Network is mandatory for control, DNS, STUN, DISCO, and DERP. Direct peer traffic also uses it unless Options selects wgo's default transport for direct peers.
func (*Client) ACLAllows ¶
ACLAllows reports whether the latest read-only packet filter contains a matching rule. It is an application helper, not an enforcement mechanism.
func (*Client) ACLFirewallConfig ¶
func (c *Client) ACLFirewallConfig() *gonnect.FirewallConfig
ACLFirewallConfig converts the latest packet filter to a gonnect incoming firewall policy. The returned config is independent of the client state.
The config does not restrict outgoing traffic. Tailscale packet filters are allow lists, but gonnect FirewallConfig.Exclude is an outgoing deny list.
func (*Client) Close ¶
Close stops only resources and peers owned by this client. It does not stop the shared wgo device or alter peers owned by other controllers.
func (*Client) ConfirmPeer ¶
ConfirmPeer permits one control-provided peer to be published to wgo when confirmation mode is enabled. The ID is PeerInfo.PeerID, normally the control server's stable node ID.
func (*Client) CurrentInteraction ¶
func (c *Client) CurrentInteraction() *Interaction
CurrentInteraction returns a copy of the active UI-neutral interaction.
func (*Client) DesiredNetworkConfiguration ¶
func (c *Client) DesiredNetworkConfiguration() NetworkConfiguration
DesiredNetworkConfiguration returns desired interface/address/route state; it never performs operating-system configuration.
func (*Client) Done ¶
func (c *Client) Done() <-chan struct{}
Done is closed after client resources have been fully released.
func (*Client) Info ¶
func (c *Client) Info() ClientInfo
Info returns current public client identity and timestamps.
func (*Client) Resolver ¶
func (c *Client) Resolver() *MagicDNSResolver
Resolver returns a live resolver view backed by Client snapshots.
func (*Client) ResumeInteraction ¶
ResumeInteraction nudges pending authentication immediately after an application has opened its URL or completed an out-of-band admin action.
func (*Client) RevokePeerConfirmation ¶
RevokePeerConfirmation removes a prior confirmation and withdraws that peer from wgo. It is useful when application policy changes locally.
func (*Client) Start ¶
Start installs the client's named transport and starts asynchronous control synchronization. Authentication that needs a person is surfaced through Interaction and events; Start itself does not wait for that person.
type ClientInfo ¶
type ClientInfo struct {
ControlURL string
Hostname string
NodePublicKey device.NoisePublicKey
MachinePublicKey string
DiscoPublicKey string
BackendLogID string
TransportID device.TransportID
StartedAt time.Time
AuthenticatedAt time.Time
UserID int64
LoginName string
DisplayName string
ProfilePicURL string
Ephemeral bool
PeerConfirmation bool
CapabilityVersion int
MachineAuthorized bool
MapSessionHandle string
MapSequence int64
PreferredDERP int64
}
ClientInfo describes this client identity. Private keys are deliberately not exposed; the node private key remains solely on the wgo device.
type ConfirmationState ¶
type ConfirmationState string
ConfirmationState reports whether a peer may be published to wgo.
const ( PeerConfirmationNotRequired ConfirmationState = "not-required" PeerAwaitingConfirmation ConfirmationState = "awaiting-confirmation" PeerConfirmed ConfirmationState = "confirmed" )
type DERPLatencySource ¶
type DERPLatencySource string
DERPLatencySource identifies how a DERP-region RTT was measured.
const ( DERPLatencySTUN DERPLatencySource = "stun-udp" DERPLatencyHTTPS DERPLatencySource = "https" )
type DERPNode ¶
type DERPNode struct {
Name string
RegionID int64
HostName string
CertName string
IPv4 string
IPv6 string
STUNPort int
DERPPort int
STUNOnly bool
InsecureForTests bool
STUNTestIP string
}
DERPNode and DERPRegion are public, read-only views of the relay map.
type DERPRegion ¶
type DERPView ¶
type DERPView struct {
Regions []DERPRegion
Home int64
Revision uint64
}
type DNSView ¶
type DNSView struct {
Proxied bool
SearchDomains []string
CertDomains []string
Nameservers []netip.Addr
Resolvers []json.RawMessage
Routes map[string][]json.RawMessage
Records []DNSRecord
Revision uint64
}
DNSView is an immutable snapshot used by MagicDNSResolver.
type Event ¶
Event is a coalescable notification. Call Snapshot after receiving it to obtain one consistent, immutable view of all client state.
type EventKind ¶
type EventKind string
EventKind identifies a mutable part of the client view.
const ( EventState EventKind = "state" EventInteraction EventKind = "interaction" EventSelf EventKind = "self" EventPeers EventKind = "peers" EventPeerPath EventKind = "peer-path" EventDNS EventKind = "dns" EventACL EventKind = "acl" EventNetwork EventKind = "network" EventDERP EventKind = "derp" EventUsers EventKind = "users" EventMetadata EventKind = "metadata" EventError EventKind = "error" )
type Interaction ¶
type Interaction struct {
ID uint64
Kind InteractionKind
URL string
Message string
Since time.Time
}
Interaction is a UI-neutral request. ResumeInteraction either expedites the next authentication attempt or acknowledges a one-shot control URL. The client continues independently, so no application goroutine waits on a user.
type InteractionKind ¶
type InteractionKind string
InteractionKind identifies an action that application UI may present.
const ( InteractionAuthenticate InteractionKind = "authenticate" InteractionNodeKeyExpired InteractionKind = "node-key-expired" InteractionControlURL InteractionKind = "control-url" )
type LocalEndpoint ¶
LocalEndpoint is an address currently advertised to control and how it was learned. Source is one of "local", "stun", "port-mapped", or "unknown".
type MagicDNSResolver ¶
type MagicDNSResolver struct {
// contains filtered or unexported fields
}
MagicDNSResolver resolves only the control-provided in-memory DNS view. It never changes system resolver settings and never sends a DNS packet.
func (*MagicDNSResolver) LookupAddr ¶
LookupAddr performs an in-memory reverse lookup over node A/AAAA records.
func (*MagicDNSResolver) LookupHost ¶
LookupHost returns textual addresses for a MagicDNS name.
func (*MagicDNSResolver) LookupNetIP ¶
func (r *MagicDNSResolver) LookupNetIP(ctx context.Context, network, host string) ([]netip.Addr, error)
LookupNetIP implements the shape used by net.Resolver and gonnect resolvers.
type NetworkConfiguration ¶
type NetworkConfiguration struct {
InterfaceName string
Up bool
MTU int
Addresses []netip.Prefix
Routes []Route
DNS DNSView
Revision uint64
}
NetworkConfiguration is desired state for the host application. No entry is installed by this package.
type NodeInfo ¶
type NodeInfo struct {
ID int64
StableID string
Name string
UserID int64
PublicKey device.NoisePublicKey
MachinePublicKey string
DiscoPublicKey string
Addresses []netip.Prefix
AllowedIPs []netip.Prefix
Endpoints []netip.AddrPort
HomeDERP int64
LegacyDERPString string
CapabilityVersion int
KeySignature []byte
KeyExpiry time.Time
Created time.Time
LastSeen *time.Time
Online *bool
MachineAuthorized bool
Tags []string
PrimaryRoutes []netip.Prefix
Capabilities []string
CapabilityMap map[string][]json.RawMessage
UnsignedPeerAPIOnly bool
ComputedName string
ComputedNameWithHost string
DataPlaneAuditLogID string
Expired bool
SelfNodeV4MasqAddrForThisPeer *netip.Addr
SelfNodeV6MasqAddrForThisPeer *netip.Addr
IsWireGuardOnly bool
IsJailed bool
ExitNodeDNSResolvers []json.RawMessage
HostinfoJSON json.RawMessage
RawJSON json.RawMessage
}
NodeInfo is a read-only copy of control-plane node data. RawJSON preserves fields this library version does not yet understand.
type Options ¶
type Options struct {
// ControlURL is a Tailscale-compatible coordination server URL.
ControlURL string
// Hostname is the node name advertised to control. It is required.
Hostname string
// AuthKey is an optional reusable or one-shot pre-authentication key.
AuthKey string
// Ephemeral asks control to remove the node after it goes offline.
Ephemeral bool
// ConfirmPeers holds newly observed peers outside wgo until ConfirmPeer is
// called. Confirmations are stable-ID based and can be cached.
ConfirmPeers bool
// Obfuscation is copied onto every wgo peer owned by this client. All peers
// must have a compatible AmneziaWG configuration.
Obfuscation *device.AmneziaWGConfig
// TransportID names the wgo transport owned by this client. It must not be
// the empty default-UDP transport ID.
TransportID device.TransportID
// UseDefaultTransportForDirectPeers uses wgo's default transport for direct
// UDP peer endpoints. DERP traffic still uses this client's named transport.
UseDefaultTransportForDirectPeers bool
// ListenPort requests a local UDP port. Zero asks the network for one.
ListenPort uint16
// InterfaceName and MTU describe the desired interface in
// NetworkConfiguration. They are never applied to the operating system.
InterfaceName string
MTU int
// DisableDERP disables the TLS DERP fallback. Direct UDP remains enabled.
DisableDERP bool
// DisableDiscovery disables local endpoint advertisement, STUN, and Disco.
// Control-provided direct endpoints remain available; WireGuard-only peers
// use them as their primary path and other peers use them if DERP is
// unavailable.
DisableDiscovery bool
// TLSConfig configures all outgoing TLS connections. It is required and is
// cloned before use.
TLSConfig *tls.Config
// Cache is optional. Without it a new machine/discovery identity is made on
// each process run, while the wgo node identity remains unchanged.
Cache CacheCallbacks
// Logger receives diagnostic messages. The default discards logs.
Logger *slog.Logger
// AuthenticationPollInterval controls follow-up registration while user
// authorization is pending.
AuthenticationPollInterval time.Duration
// ReconnectMin and ReconnectMax bound map-stream retry backoff.
ReconnectMin time.Duration
ReconnectMax time.Duration
}
Options configures a Client. Zero values select conservative defaults.
type PeerInfo ¶
type PeerInfo struct {
Node NodeInfo
PeerID string
Confirmation ConfirmationState
AppliedToWGO bool
Path PathKind
Direct netip.AddrPort
PathLatency time.Duration
PathUpdated time.Time
LastError string
}
PeerInfo combines a control-plane node with local confirmation, publication, and path state.
type Route ¶
type Route struct {
Prefix netip.Prefix
PeerID string
PeerPublicKey device.NoisePublicKey
Primary bool
}
Route describes one desired route and its owning Tailscale peer.
type Snapshot ¶
type Snapshot struct {
Revision uint64
At time.Time
State State
LastError string
Interaction *Interaction
Client ClientInfo
Self *NodeInfo
Peers []PeerInfo
Users []UserProfile
DNS DNSView
ACL ACLView
Network NetworkConfiguration
DERP DERPView
Domain string
Health []string
LocalEndpoints []LocalEndpoint
ControlTime *time.Time
}
Snapshot is a coherent deep copy of all mutable client information.
type UserProfile ¶
type UserProfile struct {
ID int64
LoginName string
DisplayName string
ProfilePicURL string
Groups []string
}
UserProfile is display data delivered with network maps.
type WGODevice ¶
type WGODevice interface {
PrivateKey() device.NoisePrivateKey
UpsertPeer(device.PeerSpec) error
DeletePeer(device.NoisePublicKey) (bool, error)
PeerSpec(device.NoisePublicKey) (device.PeerSpec, bool)
AddTransport(device.TransportID, device.TransportConfig) error
RemoveTransport(device.TransportID) error
}
WGODevice is the portion of a master-branch wgo device used by Client. A *device.Device implements this interface. The narrow interface also makes it possible to test control-plane behavior without creating a TUN.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
tailscale_real_e2e
command
|
|
|
internal
|
|
|
tests
|
|
|
e2e/cmd/multi_node
command
|
|
|
e2e/cmd/node
command
|
|
|
e2e/cmd/vtun_server
command
|