tailscale/ipn/conf.go

138 lines
4.2 KiB
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package ipn
import (
"net/netip"
"tailscale.com/tailcfg"
"tailscale.com/types/opt"
"tailscale.com/types/preftype"
)
// ConfigVAlpha is the config file format for the "alpha0" version.
type ConfigVAlpha struct {
Version string // "alpha0" for now
Locked opt.Bool `json:",omitempty"` // whether the config is locked from being changed by 'tailscale set'; it defaults to true
ServerURL *string `json:",omitempty"` // defaults to https://controlplane.tailscale.com
AuthKey *string `json:",omitempty"` // as needed if NeedsLogin. either key or path to a file (if prefixed with "file:")
Enabled opt.Bool `json:",omitempty"` // wantRunning; empty string defaults to true
OperatorUser *string `json:",omitempty"` // local user name who is allowed to operate tailscaled without being root or using sudo
Hostname *string `json:",omitempty"`
AcceptDNS opt.Bool `json:"acceptDNS,omitempty"` // --accept-dns
AcceptRoutes opt.Bool `json:"acceptRoutes,omitempty"` // --accept-routes defaults to true
ExitNode *string `json:"exitNode,omitempty"` // IP, StableID, or MagicDNS base name
AllowLANWhileUsingExitNode opt.Bool `json:"allowLANWhileUsingExitNode,omitempty"`
AdvertiseRoutes []netip.Prefix `json:",omitempty"`
DisableSNAT opt.Bool `json:",omitempty"`
NetfilterMode *string `json:",omitempty"` // "on", "off", "nodivert"
NoStatefulFiltering opt.Bool `json:",omitempty"`
PostureChecking opt.Bool `json:",omitempty"`
RunSSHServer opt.Bool `json:",omitempty"` // Tailscale SSH
RunWebClient opt.Bool `json:",omitempty"`
ShieldsUp opt.Bool `json:",omitempty"`
AutoUpdate *AutoUpdatePrefs `json:",omitempty"`
ServeConfigTemp *ServeConfig `json:",omitempty"` // TODO(bradfitz,maisem): make separate stable type for this
// TODO(bradfitz,maisem): future something like:
// Profile map[string]*Config // keyed by alice@gmail.com, corp.com (TailnetSID)
}
func (c *ConfigVAlpha) ToPrefs() (MaskedPrefs, error) {
var mp MaskedPrefs
if c == nil {
return mp, nil
}
mp.WantRunning = !c.Enabled.EqualBool(false)
mp.WantRunningSet = mp.WantRunning || c.Enabled != ""
if c.ServerURL != nil {
mp.ControlURL = *c.ServerURL
mp.ControlURLSet = true
}
if c.AuthKey != nil && *c.AuthKey != "" {
mp.LoggedOut = false
mp.LoggedOutSet = true
}
if c.OperatorUser != nil {
mp.OperatorUser = *c.OperatorUser
mp.OperatorUserSet = true
}
if c.Hostname != nil {
mp.Hostname = *c.Hostname
mp.HostnameSet = true
}
if c.AcceptDNS != "" {
mp.CorpDNS = c.AcceptDNS.EqualBool(true)
mp.CorpDNSSet = true
}
if c.AcceptRoutes != "" {
mp.RouteAll = c.AcceptRoutes.EqualBool(true)
mp.RouteAllSet = true
}
if c.ExitNode != nil {
ip, err := netip.ParseAddr(*c.ExitNode)
if err == nil {
mp.ExitNodeIP = ip
mp.ExitNodeIPSet = true
} else {
mp.ExitNodeID = tailcfg.StableNodeID(*c.ExitNode)
mp.ExitNodeIDSet = true
}
}
if c.AllowLANWhileUsingExitNode != "" {
mp.ExitNodeAllowLANAccess = c.AllowLANWhileUsingExitNode.EqualBool(true)
mp.ExitNodeAllowLANAccessSet = true
}
if c.AdvertiseRoutes != nil {
mp.AdvertiseRoutes = c.AdvertiseRoutes
mp.AdvertiseRoutesSet = true
}
if c.DisableSNAT != "" {
mp.NoSNAT = c.DisableSNAT.EqualBool(true)
mp.NoSNAT = true
}
if c.NoStatefulFiltering != "" {
mp.NoStatefulFiltering = c.NoStatefulFiltering
mp.NoStatefulFilteringSet = true
}
if c.NetfilterMode != nil {
m, err := preftype.ParseNetfilterMode(*c.NetfilterMode)
if err != nil {
return mp, err
}
mp.NetfilterMode = m
mp.NetfilterModeSet = true
}
if c.PostureChecking != "" {
mp.PostureChecking = c.PostureChecking.EqualBool(true)
mp.PostureCheckingSet = true
}
if c.RunSSHServer != "" {
mp.RunSSH = c.RunSSHServer.EqualBool(true)
mp.RunSSHSet = true
}
if c.RunWebClient != "" {
mp.RunWebClient = c.RunWebClient.EqualBool(true)
mp.RunWebClientSet = true
}
if c.ShieldsUp != "" {
mp.ShieldsUp = c.ShieldsUp.EqualBool(true)
mp.ShieldsUpSet = true
}
if c.AutoUpdate != nil {
mp.AutoUpdate = *c.AutoUpdate
mp.AutoUpdateSet = AutoUpdatePrefsMask{ApplySet: true, CheckSet: true}
}
return mp, nil
}