mirror of
https://github.com/tailscale/tailscale.git
synced 2026-05-06 04:36:15 +02:00
cmd/tailscale/cli: configure a static endpoint flag on tailscale set
Fixes #13462 Signed-off-by: Lee Briggs <lee@leebriggs.co.uk>
This commit is contained in:
parent
77123a569b
commit
9e2df8093f
@ -65,6 +65,7 @@ type setArgsT struct {
|
||||
statefulFiltering bool
|
||||
netfilterMode string
|
||||
relayServerPort string
|
||||
staticEndpoints string
|
||||
}
|
||||
|
||||
func newSetFlagSet(goos string, setArgs *setArgsT) *flag.FlagSet {
|
||||
@ -86,6 +87,7 @@ func newSetFlagSet(goos string, setArgs *setArgsT) *flag.FlagSet {
|
||||
setf.BoolVar(&setArgs.reportPosture, "report-posture", false, "allow management plane to gather device posture information")
|
||||
setf.BoolVar(&setArgs.runWebClient, "webclient", false, "expose the web interface for managing this node over Tailscale at port 5252")
|
||||
setf.StringVar(&setArgs.relayServerPort, "relay-server-port", "", "UDP port number (0 will pick a random unused port) for the relay server to bind to, on all interfaces, or empty string to disable relay server functionality")
|
||||
setf.StringVar(&setArgs.staticEndpoints, "endpoint", "", "static endpoint(s) to advertise (comma-separated, e.g. \"192.168.1.100:41641,203.0.113.1:41641\")")
|
||||
|
||||
ffcomplete.Flag(setf, "exit-node", func(args []string) ([]string, ffcomplete.ShellCompDirective, error) {
|
||||
st, err := localClient.Status(context.Background())
|
||||
@ -185,6 +187,26 @@ func runSet(ctx context.Context, args []string) (retErr error) {
|
||||
}
|
||||
}
|
||||
|
||||
if setArgs.staticEndpoints != "" {
|
||||
const max = 10 // reasonable limit for static endpoints
|
||||
remain := setArgs.staticEndpoints
|
||||
var endpoints []netip.AddrPort
|
||||
for remain != "" && len(endpoints) < max {
|
||||
var s string
|
||||
s, remain, _ = strings.Cut(remain, ",")
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
continue
|
||||
}
|
||||
ap, err := netip.ParseAddrPort(s)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid endpoint %q: %v", s, err)
|
||||
}
|
||||
endpoints = append(endpoints, ap)
|
||||
}
|
||||
maskedPrefs.Prefs.StaticEndpoints = endpoints
|
||||
}
|
||||
|
||||
warnOnAdvertiseRoutes(ctx, &maskedPrefs.Prefs)
|
||||
if err := checkExitNodeRisk(ctx, &maskedPrefs.Prefs, setArgs.acceptedRisks); err != nil {
|
||||
return err
|
||||
|
||||
@ -889,6 +889,7 @@ func init() {
|
||||
addPrefFlagMapping("advertise-connector", "AppConnector")
|
||||
addPrefFlagMapping("report-posture", "PostureChecking")
|
||||
addPrefFlagMapping("relay-server-port", "RelayServerPort")
|
||||
addPrefFlagMapping("endpoint", "StaticEndpoints")
|
||||
}
|
||||
|
||||
func addPrefFlagMapping(flagName string, prefNames ...string) {
|
||||
|
||||
@ -64,6 +64,7 @@ func (src *Prefs) Clone() *Prefs {
|
||||
if dst.RelayServerPort != nil {
|
||||
dst.RelayServerPort = ptr.To(*src.RelayServerPort)
|
||||
}
|
||||
dst.StaticEndpoints = append(src.StaticEndpoints[:0:0], src.StaticEndpoints...)
|
||||
dst.Persist = src.Persist.Clone()
|
||||
return dst
|
||||
}
|
||||
@ -101,6 +102,7 @@ var _PrefsCloneNeedsRegeneration = Prefs(struct {
|
||||
NetfilterKind string
|
||||
DriveShares []*drive.Share
|
||||
RelayServerPort *int
|
||||
StaticEndpoints []netip.AddrPort
|
||||
AllowSingleHosts marshalAsTrueInJSON
|
||||
Persist *persist.Persist
|
||||
}{})
|
||||
|
||||
@ -442,6 +442,12 @@ func (v PrefsView) RelayServerPort() views.ValuePointer[int] {
|
||||
return views.ValuePointerOf(v.ж.RelayServerPort)
|
||||
}
|
||||
|
||||
// StaticEndpoints are additional, user-defined endpoints that this node
|
||||
// should advertise amongst its wireguard endpoints.
|
||||
func (v PrefsView) StaticEndpoints() views.Slice[netip.AddrPort] {
|
||||
return views.SliceOf(v.ж.StaticEndpoints)
|
||||
}
|
||||
|
||||
// AllowSingleHosts was a legacy field that was always true
|
||||
// for the past 4.5 years. It controlled whether Tailscale
|
||||
// peers got /32 or /127 routes for each other.
|
||||
@ -493,6 +499,7 @@ var _PrefsViewNeedsRegeneration = Prefs(struct {
|
||||
NetfilterKind string
|
||||
DriveShares []*drive.Share
|
||||
RelayServerPort *int
|
||||
StaticEndpoints []netip.AddrPort
|
||||
AllowSingleHosts marshalAsTrueInJSON
|
||||
Persist *persist.Persist
|
||||
}{})
|
||||
|
||||
@ -4656,6 +4656,13 @@ func (b *LocalBackend) setPrefsLockedOnEntry(newp *ipn.Prefs, unlock unlockOnce)
|
||||
b.resetAlwaysOnOverrideLocked()
|
||||
}
|
||||
|
||||
// Update static endpoints if they've changed
|
||||
if !oldp.Valid() || !slices.Equal(oldp.StaticEndpoints().AsSlice(), prefs.StaticEndpoints().AsSlice()) {
|
||||
if ms, ok := b.sys.MagicSock.GetOK(); ok {
|
||||
ms.SetStaticEndpoints(prefs.StaticEndpoints())
|
||||
}
|
||||
}
|
||||
|
||||
unlock.UnlockEarly()
|
||||
|
||||
if oldp.ShieldsUp() != newp.ShieldsUp || hostInfoChanged {
|
||||
|
||||
@ -282,6 +282,10 @@ type Prefs struct {
|
||||
// non-nil/enabled.
|
||||
RelayServerPort *int `json:",omitempty"`
|
||||
|
||||
// StaticEndpoints are additional, user-defined endpoints that this node
|
||||
// should advertise amongst its wireguard endpoints.
|
||||
StaticEndpoints []netip.AddrPort `json:",omitempty"`
|
||||
|
||||
// AllowSingleHosts was a legacy field that was always true
|
||||
// for the past 4.5 years. It controlled whether Tailscale
|
||||
// peers got /32 or /127 routes for each other.
|
||||
@ -375,6 +379,7 @@ type MaskedPrefs struct {
|
||||
NetfilterKindSet bool `json:",omitempty"`
|
||||
DriveSharesSet bool `json:",omitempty"`
|
||||
RelayServerPortSet bool `json:",omitempty"`
|
||||
StaticEndpointsSet bool `json:",omitempty"`
|
||||
}
|
||||
|
||||
// SetsInternal reports whether mp has any of the Internal*Set field bools set
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user