Documentation ¶
Index ¶
- Constants
- Variables
- func CheckTag(tag string) error
- type CapType
- type Capability
- type CapabilityID
- type DERPMap
- type DERPNode
- type DERPRegion
- type DNSConfig
- type Debug
- type DiscoKey
- type FilterRule
- type Group
- type GroupID
- type Hostinfo
- type ID
- type Login
- type LoginID
- type MachineKey
- type MachineStatus
- type MapRequest
- type MapResponse
- type NetInfo
- type NetPortRange
- type Node
- type NodeID
- type NodeKey
- type PortRange
- type RegisterRequest
- type RegisterResponse
- type Role
- type RoleID
- type Service
- type ServiceProto
- type User
- type UserID
- type UserProfile
Constants ¶
const ( CapRead = CapType("read") CapWrite = CapType("write") )
const ( MachineUnknown = MachineStatus(iota) MachineAuthorized // server has approved MachineInvalid // server has explicitly rejected this machine key )
const ( TCP = ServiceProto("tcp") UDP = ServiceProto("udp") )
Variables ¶
var FilterAllowAll = []FilterRule{ FilterRule{ SrcIPs: []string{"*"}, SrcBits: nil, DstPorts: []NetPortRange{NetPortRange{ IP: "*", Bits: nil, Ports: PortRange{0, 65535}, }}, }, }
var PortRangeAny = PortRange{0, 65535}
Functions ¶
func CheckTag ¶ added in v0.98.1
CheckTag valids whether a given string can be used as an ACL tag. For now we allow only ascii alphanumeric tags, and they need to start with a letter. No unicode shenanigans allowed, and we reserve punctuation marks other than '-' for a possible future URI scheme.
Because we're ignoring unicode entirely, we can treat utf-8 as a series of bytes. Anything >= 128 is disqualified anyway.
We might relax these rules later.
Types ¶
type Capability ¶
type Capability struct { ID CapabilityID Type CapType Val ID }
type CapabilityID ¶
type CapabilityID ID
func (CapabilityID) String ¶
func (id CapabilityID) String() string
type DERPMap ¶ added in v0.98.1
type DERPMap struct { // Regions is the set of geographic regions running DERP node(s). // // It's keyed by the DERPRegion.RegionID. // // The numbers are not necessarily contiguous. Regions map[int]*DERPRegion }
DERPMap describes the set of DERP packet relay servers that are available.
type DERPNode ¶ added in v0.98.1
type DERPNode struct { // Name is a unique node name (across all regions). // It is not a host name. // It's typically of the form "1b", "2a", "3b", etc. (region // ID + suffix within that region) Name string // RegionID is the RegionID of the DERPRegion that this node // is running in. RegionID int // HostName is the DERP node's hostname. // // It is required but need not be unique; multiple nodes may // have the same HostName but vary in configuration otherwise. HostName string // CertName optionally specifies the expected TLS cert common // name. If empty, HostName is used. If CertName is non-empty, // HostName is only used for the TCP dial (if IPv4/IPv6 are // not present) + TLS ClientHello. CertName string `json:",omitempty"` // IPv4 optionally forces an IPv4 address to use, instead of using DNS. // If empty, A record(s) from DNS lookups of HostName are used. // If the string is not an IPv4 address, IPv4 is not used; the // conventional string to disable IPv4 (and not use DNS) is // "none". IPv4 string `json:",omitempty"` // IPv6 optionally forces an IPv6 address to use, instead of using DNS. // If empty, AAAA record(s) from DNS lookups of HostName are used. // If the string is not an IPv6 address, IPv6 is not used; the // conventional string to disable IPv6 (and not use DNS) is // "none". IPv6 string `json:",omitempty"` // Port optionally specifies a STUN port to use. // Zero means 3478. // To disable STUN on this node, use -1. STUNPort int `json:",omitempty"` // STUNOnly marks a node as only a STUN server and not a DERP // server. STUNOnly bool `json:",omitempty"` // DERPTestPort is used in tests to override the port, instead // of using the default port of 443. If non-zero, TLS // verification is skipped. DERPTestPort int `json:",omitempty"` // STUNTestIP is used in tests to override the STUN server's IP. // If empty, it's assumed to be the same as the DERP server. STUNTestIP string `json:",omitempty"` }
DERPNode describes a DERP packet relay node running within a DERPRegion.
type DERPRegion ¶ added in v0.98.1
type DERPRegion struct { // RegionID is a unique integer for a geographic region. // // It corresponds to the legacy derpN.tailscale.com hostnames // used by older clients. (Older clients will continue to resolve // derpN.tailscale.com when contacting peers, rather than use // the server-provided DERPMap) // // RegionIDs must be non-zero, positive, and guaranteed to fit // in a JavaScript number. RegionID int // RegionCode is a short name for the region. It's usually a popular // city or airport code in the region: "nyc", "sf", "sin", // "fra", etc. RegionCode string // Nodes are the DERP nodes running in this region, in // priority order for the current client. Client TLS // connections should ideally only go to the first entry // (falling back to the second if necessary). STUN packets // should go to the first 1 or 2. // // If nodes within a region route packets amongst themselves, // but not to other regions. That said, each user/domain // should get a the same preferred node order, so if all nodes // for a user/network pick the first one (as they should, when // things are healthy), the inter-cluster routing is minimal // to zero. Nodes []*DERPNode }
DERPRegion is a geographic region running DERP relay node(s).
Client nodes discover which region they're closest to, advertise that "home" DERP region (previously called "home node", when there was only 1 node per region) and maintain a persistent connection that region as long as it's the closest. Client nodes will further connect to other regions as necessary to communicate with peers advertising other regions as their homes.
type DNSConfig ¶ added in v1.0.1
type DNSConfig struct { Nameservers []netaddr.IP `json:",omitempty"` Domains []string `json:",omitempty"` PerDomain bool Proxied bool }
DNSConfig is the DNS configuration.
type Debug ¶ added in v0.98.1
type Debug struct { // LogHeapPprof controls whether the client should log // its heap pprof data. Each true value sent from the server // means that client should do one more log. LogHeapPprof bool `json:",omitempty"` // LogHeapURL is the URL to POST its heap pprof to. // Empty means to not log. LogHeapURL string `json:",omitempty"` // ForceBackgroundSTUN controls whether magicsock should // always do its background STUN queries (see magicsock's // periodicReSTUN), regardless of inactivity. ForceBackgroundSTUN bool `json:",omitempty"` }
Debug are instructions from the control server to the client to adjust debug settings.
type DiscoKey ¶ added in v0.100.0
type DiscoKey [32]byte
DiscoKey is the curve25519 public key for path discovery key. It's never written to disk or reused between network start-ups.
func (DiscoKey) MarshalText ¶ added in v0.100.0
func (DiscoKey) ShortString ¶ added in v0.100.0
func (*DiscoKey) UnmarshalText ¶ added in v0.100.0
type FilterRule ¶ added in v0.98.1
type FilterRule struct { SrcIPs []string SrcBits []int DstPorts []NetPortRange }
FilterRule represents one rule in a packet filter.
type Hostinfo ¶
type Hostinfo struct { // TODO(crawshaw): mark all these fields ",omitempty" when all the // iOS apps are updated with the latest swift version of this struct. IPNVersion string // version of this code FrontendLogID string // logtail ID of frontend instance BackendLogID string // logtail ID of backend instance OS string // operating system the client runs on (a version.OS value) OSVersion string // operating system version, with optional distro prefix ("Debian 10.4", "Windows 10 Pro 10.0.19041") DeviceModel string // mobile phone model ("Pixel 3a", "iPhone 11 Pro") Hostname string // name of the host the client runs on GoArch string // the host's GOARCH value (of the running binary) RoutableIPs []wgcfg.CIDR `json:",omitempty"` // set of IP ranges this client can route RequestTags []string `json:",omitempty"` // set of ACL tags this node wants to claim Services []Service `json:",omitempty"` // services advertised by this machine NetInfo *NetInfo `json:",omitempty"` }
Hostinfo contains a summary of a Tailscale host.
Because it contains pointers (slices), this type should not be used as a value type.
type MachineKey ¶
type MachineKey [32]byte
MachineKey is the curve25519 public key for a machine.
func (MachineKey) MarshalText ¶
func (k MachineKey) MarshalText() ([]byte, error)
func (MachineKey) String ¶
func (k MachineKey) String() string
func (*MachineKey) UnmarshalText ¶
func (k *MachineKey) UnmarshalText(text []byte) error
type MachineStatus ¶
type MachineStatus int
func (MachineStatus) MarshalText ¶
func (m MachineStatus) MarshalText() ([]byte, error)
func (MachineStatus) String ¶
func (m MachineStatus) String() string
func (*MachineStatus) UnmarshalText ¶
func (m *MachineStatus) UnmarshalText(b []byte) error
type MapRequest ¶
type MapRequest struct { Version int // current version is 4 Compress string // "zstd" or "" (no compression) KeepAlive bool // server sends keep-alives NodeKey NodeKey DiscoKey DiscoKey Endpoints []string // caller's endpoints (IPv4 or IPv6) IncludeIPv6 bool // include IPv6 endpoints in returned Node Endpoints Stream bool // if true, multiple MapResponse objects are returned Hostinfo *Hostinfo // DebugForceDisco is a temporary flag during the deployment // of magicsock active discovery. It says that that the client // has environment variables explicitly turning discovery on, // so control should not disable it. DebugForceDisco bool `json:"debugForceDisco,omitempty"` }
MapRequest is sent by a client to start a long-poll network map updates. The request includes a copy of the client's current set of WireGuard endpoints and general host information.
The request is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box, using the local machine key, and sent to:
https://login.tailscale.com/machine/<mkey hex>/map
type MapResponse ¶
type MapResponse struct { KeepAlive bool // if set, all other fields are ignored // Networking Node *Node Peers []*Node DERPMap *DERPMap // DNS is the same as DNSConfig.Nameservers. // // TODO(dmytro): should be sent in DNSConfig.Nameservers once clients have updated. DNS []wgcfg.IP // SearchPaths are the same as DNSConfig.Domains. // // TODO(dmytro): should be sent in DNSConfig.Domains once clients have updated. SearchPaths []string DNSConfig DNSConfig // ACLs Domain string PacketFilter []FilterRule UserProfiles []UserProfile Roles []Role // Debug is normally nil, except for when the control server // is setting debug settings on a node. Debug *Debug `json:",omitempty"` }
type NetInfo ¶
type NetInfo struct { // MappingVariesByDestIP says whether the host's NAT mappings // vary based on the destination IP. MappingVariesByDestIP opt.Bool // HairPinning is their router does hairpinning. // It reports true even if there's no NAT involved. HairPinning opt.Bool // WorkingIPv6 is whether IPv6 works. WorkingIPv6 opt.Bool // WorkingUDP is whether UDP works. WorkingUDP opt.Bool // UPnP is whether UPnP appears present on the LAN. // Empty means not checked. UPnP opt.Bool // PMP is whether NAT-PMP appears present on the LAN. // Empty means not checked. PMP opt.Bool // PCP is whether PCP appears present on the LAN. // Empty means not checked. PCP opt.Bool // PreferredDERP is this node's preferred DERP server // for incoming traffic. The node might be be temporarily // connected to multiple DERP servers (to send to other nodes) // but PreferredDERP is the instance number that the node // subscribes to traffic at. // Zero means disconnected or unknown. PreferredDERP int // LinkType is the current link type, if known. LinkType string // "wired", "wifi", "mobile" (LTE, 4G, 3G, etc) // DERPLatency is the fastest recent time to reach various // DERP STUN servers, in seconds. The map key is the // "regionID-v4" or "-v6"; it was previously the DERP server's // STUN host:port. // // This should only be updated rarely, or when there's a // material change, as any change here also gets uploaded to // the control plane. DERPLatency map[string]float64 `json:",omitempty"` }
NetInfo contains information about the host's network state.
func (*NetInfo) BasicallyEqual ¶
BasicallyEqual reports whether ni and ni2 are basically equal, ignoring changes in DERP ServerLatency & RegionLatency.
type NetPortRange ¶ added in v0.98.1
type NetPortRange struct { IP string Bits *int // backward compatibility: if missing, means "all" bits Ports PortRange // contains filtered or unexported fields }
NetPortRange represents a single subnet:portrange.
type Node ¶
type Node struct { ID NodeID Name string // DNS User UserID Key NodeKey KeyExpiry time.Time Machine MachineKey DiscoKey DiscoKey Addresses []wgcfg.CIDR // IP addresses of this Node directly AllowedIPs []wgcfg.CIDR // range of IP addresses to route to this node Endpoints []string `json:",omitempty"` // IP+port (public via STUN, and local LANs) DERP string `json:",omitempty"` // DERP-in-IP:port ("127.3.3.40:N") endpoint Hostinfo Hostinfo Created time.Time LastSeen *time.Time `json:",omitempty"` KeepAlive bool // open and keep open a connection to this peer MachineAuthorized bool // TODO(crawshaw): replace with MachineStatus }
type NodeKey ¶
type NodeKey [32]byte
NodeKey is the curve25519 public key for a node.
func (NodeKey) MarshalText ¶
func (NodeKey) ShortString ¶ added in v0.98.0
func (*NodeKey) UnmarshalText ¶
type RegisterRequest ¶
type RegisterRequest struct { Version int // currently 1 NodeKey NodeKey OldNodeKey NodeKey Auth struct { // One of Provider/LoginName, Oauth2Token, or AuthKey is set. Provider, LoginName string Oauth2Token *oauth2.Token AuthKey string // contains filtered or unexported fields } Expiry time.Time // requested key expiry, server policy may override Followup string // response waits until AuthURL is visited Hostinfo *Hostinfo // contains filtered or unexported fields }
RegisterRequest is sent by a client to register the key for a node. It is encoded to JSON, encrypted with golang.org/x/crypto/nacl/box, using the local machine key, and sent to:
https://login.tailscale.com/machine/<mkey hex>
func (*RegisterRequest) Clone ¶
func (req *RegisterRequest) Clone() *RegisterRequest
Clone makes a deep copy of RegisterRequest. The result aliases no memory with the original.
TODO: extend cmd/cloner to generate this method.
type RegisterResponse ¶
type RegisterResponse struct { User User Login Login NodeKeyExpired bool // if true, the NodeKey needs to be replaced MachineAuthorized bool // TODO(crawshaw): move to using MachineStatus AuthURL string // if set, authorization pending }
RegisterResponse is returned by the server in response to a RegisterRequest.
type Role ¶
type Role struct { ID RoleID Name string Capabilities []CapabilityID }
type Service ¶
type Service struct { Proto ServiceProto // TCP or UDP Port uint16 // port number service is listening on Description string // text description of service // contains filtered or unexported fields }
type ServiceProto ¶
type ServiceProto string
type User ¶
type User struct { ID UserID LoginName string `json:"-"` // not stored, filled from Login // TODO REMOVE DisplayName string // if non-empty overrides Login field ProfilePicURL string // if non-empty overrides Login field Domain string Logins []LoginID Roles []RoleID Created time.Time }
User is an IPN user.
A user can have multiple logins associated with it (e.g. gmail and github oauth). (Note: none of our UIs support this yet.)
Some properties are inhereted from the logins and can be overridden, such as display name and profile picture.
Other properties must be the same for all logins associated with a user. In particular: domain. If a user has a "tailscale.io" domain login, they cannot have a general gmail address login associated with the user.
type UserProfile ¶
type UserProfile struct { ID UserID LoginName string // "alice@smith.com"; for display purposes only (provider is not listed) DisplayName string // "Alice Smith" ProfilePicURL string Roles []RoleID }
A UserProfile is display-friendly data for a user. It includes the LoginName for display purposes but *not* the Provider. It also includes derived data from one of the user's logins.