Commit Graph

1826 Commits (038cdb4640275e44fd8cf5a95f23d5d5b4987ba3)

Author SHA1 Message Date
Nick Khyl 1a2185b1ee ipn/ipnlocal: rename setAutoExitNodeIDLockedOnEntry to pickNewAutoExitNode; drop old function
Currently, (*LocalBackend).pickNewAutoExitNode() is just a wrapper around
setAutoExitNodeIDLockedOnEntry that sends a prefs-change notification at the end.
It doesn't need to do that, since setPrefsLockedOnEntry already sends the notification
(setAutoExitNodeIDLockedOnEntry calls it via editPrefsLockedOnEntry).

This PR removes the old pickNewAutoExitNode function and renames
setAutoExitNodeIDLockedOnEntry to pickNewAutoExitNode for clarity.

Updates tailscale/corp#29969

Signed-off-by: Nick Khyl <nickk@tailscale.com>
5 months ago
Andrew Lytvynov 172e26b3e3
tailcfg: report StateEncrypted in Hostinfo (#16434)
Report whether the client is configured with state encryption (which
varies by platform and can be optional on some). Wire it up to
`--encrypt-state` in tailscaled, which is set for Linux/Windows, and set
defaults for other platforms. Macsys will also report this if full
Keychain migration is done.

Updates #15830

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
5 months ago
kari-ts d15b2312c4
tailcfg: add CapabilityOwner (#16426)
We would like to start sending whether a node is a Tailnet owner in netmap responses so that clients can determine what information to display to a user who wants to request account deletion.

Updates tailscale/corp#30016

Signed-off-by: kari-ts <kari@tailscale.com>
5 months ago
Percy Wegmann 454d856be8 drive,ipn/ipnlocal: calculate peer taildrive URLs on-demand
Instead of calculating the PeerAPI URL at the time that we add the peer,
we now calculate it on every access to the peer. This way, if we
initially did not have a shared address family with the peer, but
later do, this allows us to access the peer at that point. This
follows the pattern from other places where we access the peer API,
which also calculate the URL on an as-needed basis.

Additionally, we now show peers as not Available when we can't get
a peer API URL.

Lastly, this moves some of the more frequent verbose Taildrive logging
from [v1] to [v2] level.

Updates #29702

Signed-off-by: Percy Wegmann <percy@tailscale.com>
5 months ago
Percy Wegmann 6a9bf9172b ipn/ipnlocal: add verbose Taildrive logging on client side
This allows logging the following Taildrive behavior from the client's perspective
when --verbose=1:

- Initialization of Taildrive remotes for every peer
- Peer availability checks
- All HTTP requests to peers (not just GET and PUT)

Updates tailscale/corp#29702

Signed-off-by: Percy Wegmann <percy@tailscale.com>
5 months ago
Andrew Lytvynov 76b9afb54d
ipn/store: make StateStore.All optional (#16409)
This method is only needed to migrate between store.FileStore and
tpm.tpmStore. We can make a runtime type assertion instead of
implementing an unused method for every platform.

Updates #15830

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
5 months ago
Andrew Lytvynov 6feb3c35cb
ipn/store: automatically migrate between plaintext and encrypted state (#16318)
Add a new `--encrypt-state` flag to `cmd/tailscaled`. Based on that
flag, migrate the existing state file to/from encrypted format if
needed.

Updates #15830

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
5 months ago
JerryYan 99aaa6e92c
ipn/ipnlocal: update PeerByID to return SelfNode and rename it to NodeByID (#16096)
Like NodeByKey, add an if stmt for checking the NodeId is SelfNode.

Updates #16052

Signed-off-by: Jerry Yan <792602257@qq.com>
5 months ago
Nick Khyl 9e28bfc69c ipn/ipnlocal,wgengine/magicsock: wait for magicsock to process pending events on authReconfig
Updates #16369

Signed-off-by: Nick Khyl <nickk@tailscale.com>
5 months ago
Andrew Lytvynov 4979ce7a94
feature/tpm: implement ipn.StateStore using TPM sealing (#16030)
Updates #15830

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
6 months ago
Jordan Whited fcab50b276
ipn/ipnlocal,wgengine{/magicsock}: replace SetNetworkMap with eventbus (#16299)
Same with UpdateNetmapDelta.

Updates tailscale/corp#27502
Updates #15160

Signed-off-by: Jordan Whited <jordan@tailscale.com>
6 months ago
Anton Tolchanov a91fcc8813 ipn/ipnlocal: make pricing restriction message for Tailnet Lock clearer
Fixes tailscale/corp#24417

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
6 months ago
Juan Francisco Cantero Hurtado cbc14bd3b0 ipn: add missing entries for OpenBSD
Signed-off-by: Juan Francisco Cantero Hurtado <jfch@30041993.xyz>
6 months ago
Percy Wegmann 4431fb89c2 ipn/ipnlocal: add some verbose logging to taildrive peerapi handler
Updates tailscale/corp#29702

Signed-off-by: Percy Wegmann <percy@tailscale.com>
6 months ago
Brad Fitzpatrick 259bab9bff scripts/check_license_headers.sh: delete, rewrite as a Go test
Updates tailscale/corp#29650

Change-Id: Iad4e4ccd9d68ebb1d1a12f335cc5295d0bd05b60
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
6 months ago
Jordan Whited 8e6f63cf11
ipn/ipnlocal,wgengine/magicsock: use eventbus for node & filter updates (#16271)
nodeBackend now publishes filter and node changes to eventbus topics
that are consumed by magicsock.Conn

Updates tailscale/corp#27502
Updates tailscale/corp#29543

Signed-off-by: Jordan Whited <jordan@tailscale.com>
6 months ago
Nick Khyl 733bfaeffe ipn/ipnlocal: signal nodeBackend readiness and shutdown
We update LocalBackend to shut down the current nodeBackend
when switching to a different node, and to mark the new node's
nodeBackend as ready when the switch completes.

Updates tailscale/corp#28014
Updates tailscale/corp#29543
Updates #12614

Signed-off-by: Nick Khyl <nickk@tailscale.com>
6 months ago
Nick Khyl 6a4d92ecef ipn/ipnlocal: replace nodeContext with nodeBackend in comments
We renamed the type in #15866 but didn't update the comments at the time.

Updates #cleanup

Signed-off-by: Nick Khyl <nickk@tailscale.com>
6 months ago
Claus Lensbøl 6010812f0c
ipn/localapi,client/local: add debug watcher for bus events (#16239)
Updates: #15160

Signed-off-by: Claus Lensbøl <claus@tailscale.com>
6 months ago
Anton Tolchanov db34cdcfe7 cmd/tailscale/cli: add a risk message about rp_filter
We already present a health warning about this, but it is easy to miss
on a server when blackholing traffic makes it unreachable.

In addition to a health warning, present a risk message when exit node
is enabled.

Example:

```
$ tailscale up --exit-node=lizard
The following issues on your machine will likely make usage of exit nodes impossible:
- interface "ens4" has strict reverse-path filtering enabled
- interface "tailscale0" has strict reverse-path filtering enabled
Please set rp_filter=2 instead of rp_filter=1; see https://github.com/tailscale/tailscale/issues/3310
To skip this warning, use --accept-risk=linux-strict-rp-filter
$
```

Updates #3310

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
6 months ago
James Sanderson 5716d0977d health: prefix Warnables received from the control plane
Updates tailscale/corp#27759

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
6 months ago
KevinLiang10 7b06532ea1
ipn/ipnlocal: Update hostinfo to control on service config change (#16146)
This commit fixes the bug that c2n requests are skiped when updating vipServices in serveConfig. This then resulted
netmap update being skipped which caused inaccuracy of Capmap info on client side. After this fix, client always
inform control about it's vipServices config changes.

Fixes tailscale/corp#29219

Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
6 months ago
James Sanderson 5fde183754 ipn: add watch opt to include actions in health messages
Updates tailscale/corp#27759

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
6 months ago
James Sanderson 8a3afa5963 ipn/ipnlocal: fix deadlock when filtering DisplayMessage URLs
Updates tailscale/corp#27759

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
6 months ago
James Sanderson 11e83f9da5 controlclient,health,ipnlocal,tailcfg: add DisplayMessage support
Updates tailscale/corp#27759

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
6 months ago
Nick Khyl 4cccd15eeb ipn/ipnlocal: fix data race when accessing b.appConnector
The field must only be accessed while holding LocalBackend's mutex,
but there are two places where it's accessed without the mutex:
 - (LocalBackend).MaybeClearAppConnector()
 - handleC2NAppConnectorDomainRoutesGet()

Fixes #16123

Signed-off-by: Nick Khyl <nickk@tailscale.com>
6 months ago
Jonathan Nobels 842df37803
ipn: set RouteAll=true by default for new accounts on iOS and Android (#16110)
fixes tailscale/tailscale#16082

RouteAll should be true by default on iOS and Android.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
6 months ago
Zach Buchheit 4a11514db5
ipn/ipnlocal: improve dohQuery error to suggest `?dns=` and `?q=` (#16056)
Previously, a missing or invalid `dns` parameter on GET `/dns-query`
returned only “missing ‘dns’ parameter”. Now the error message guides
users to use `?dns=` or `?q=`.

Updates: #16055

Signed-off-by: Zach Buchheit <zachb@tailscale.com>
6 months ago
James 'zofrex' Sanderson aa8bc23c49
control/controlclient,health,tailcfg: refactor control health messages (#15839)
* control/controlclient,health,tailcfg: refactor control health messages

Updates tailscale/corp#27759

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
Signed-off-by: Paul Scott <408401+icio@users.noreply.github.com>
Co-authored-by: Paul Scott <408401+icio@users.noreply.github.com>
7 months ago
Andrew Lytvynov 0bab16448e
ipn/store: remove a layer of indirection for registering stores (#15986)
Registering a new store is cheap, it just adds a map entry. No need to
lazy-init it with sync.Once and an intermediate slice holding init
functions.

Updates #cleanup

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
7 months ago
Brad Fitzpatrick 30a89ad378 ipn/ipnlocal: make GetExt work earlier, before extension init
Taildrop wasn't working on iOS since #15971 because GetExt didn't work
until after init, but that PR moved Init until after Start.

This makes GetExt work before LocalBackend.Start (ExtensionHost.Init).

Updates #15812

Change-Id: I6e87257cd97a20f86083a746d39df223e5b6791b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Nick Khyl 824985afe1 feature/taildrop,ipn/ipn{ext,local}: initialize taildrop for initial profile
Currently, LocalBackend/ExtensionHost doesn't invoke the profile change callback for the initial profile.
Since the initial profile may vary depending on loaded extensions and applied policy settings,
it can't be reliably determined until all extensions are initialized. Additionally, some extensions
may asynchronously trigger a switch to the "best" profile (based on system state and policy settings) during
initialization.

We intended to address these issues as part of the ongoing profileManager/LocalBackend refactoring,
but the changes didn't land in time for the v1.84 release and the Taildrop refactoring.

In this PR, we update the Taildrop extension to retrieve the current profile at initialization time
and handle it as a profile change.

We also defer extension initialization until LocalBackend has started, since the Taildrop extension
already relies on this behavior (e.g., it requires clients to call SetDirectFileRoot before Init).

Fixes #15970
Updates #15812
Updates tailscale/corp#28449

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Anton Tolchanov 65e005ccaa ipn/ipnlocal: attach Tailnet Lock status to bugreports
Fixes tailscale/corp#28524

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
7 months ago
Nick Khyl ffb1dda245 ipn/ipnlocal,wgengine: move (*tsdial.Dialer).SetRoutes() calls from LocalBackend to userspaceEngine
This avoids reconfiguring the dialer unless the router config has changed.

Updates #12027

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Nick Khyl 565ebbdeb8 ipn/ipnlocal: move nodeBackend methods from local.go to node_backend.go
We previously kept these methods in local.go when we started moving node-specific state
from LocalBackend to nodeBackend, to make those changes easier to review. But it's time
to move them to node_backend.go.

Updates #cleanup
Updates #12614

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Nick Khyl f0a27066c4 ipn/ipn{server,test}: extract the LocalAPI test client and server into ipntest
In this PR, we extract the in-process LocalAPI client/server implementation from ipn/ipnserver/server_test.go
into a new ipntest package to be used in high‑level black‑box tests, such as those for the tailscale CLI.

Updates #15575

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Nick Khyl a9be049c19 ipn/ipnlocal,net/dns/resolver: use the user dialer and routes for DNS forwarding by default, except on iOS and Android
In this PR, we make the "user-dial-routes" behavior default on all platforms except for iOS and Android.
It can be disabled by setting the TS_DNS_FORWARD_USE_ROUTES envknob to 0 or false.

Updates #12027
Updates #13837

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Jonathan Nobels 7d6d2b4c50
health, ipn/ipnlocal: add metrics for various client events (#15828)
updates tailscale/corp#28092

Adds metrics for various client events:
* Enabling an exit node
* Enabling a mullvad exit node
* Enabling a preferred exit node
* Setting WantRunning to true/false
* Requesting a bug report ID
* Profile counts
* Profile deletions
* Captive portal detection

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
7 months ago
Brad Fitzpatrick 165b99278b feature/taildrop, ipn/ipnlocal: remove leftover dup calls to osshare
I'd moved the osshare calls to feature/taildrop hooks, but forgot to
remove them from ipnlocal, or lost them during a rebase.

But then I noticed cmd/tailscaled also had some, so turn those into a
hook.

Updates #12614

Change-Id: I024fb1d27fbcc49c013158882ee5982c2737037d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
James Sanderson 85a7abef0c tsnet: add test for packet filter generation from netmap
This is an integration test that covers all the code in Direct, Auto, and
LocalBackend that processes NetMaps and creates a Filter. The test uses
tsnet as a convenient proxy for setting up all the client pieces correctly,
but is not actually a test specific to tsnet.

Updates tailscale/corp#20514

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
7 months ago
Brad Fitzpatrick 5be6ff9b62 all: remove non-applicable "linux" deps on Android
Updates #12614

Change-Id: I0e2a18eca3515d3d6206c059110556d2bbbb0c5c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick fd263adc1b ipn/store: don't link in AWS & Kubernetes stuff on Android
Android is Linux, but that not much Linux.

Updates #12614

Change-Id: Ice80bd3e3d173511c30d05a43d25a31e18928db7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick 068d5ab655 feature/taildrop: move rest of Taildrop out of LocalBackend
Updates #12614

Change-Id: If451dec1d796f6a4216fe485975c87f0c62a53e5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Co-authored-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Brad Fitzpatrick cf6a593196 cmd/tailscale/cli: rename "--posture-checking" to "--report-posture"
For consistency with other flags, per Slack chat.

Updates #5902

Change-Id: I7ae1e4c97b37185573926f5fafda82cf8b46f071
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick 597d0e8fd5 ipn/ipnlocal, tailcfg: add MagicDNS opt-in attr for IPv6 AAAA records
Until we turn on AAAA by default (which might make some people rely on
Happy Eyeballs for targets without IPv6), this lets people turn it on
explicitly if they want.

We still should add a peer cap as well in the future to let a peer
explicitly say that it's cool with IPv6.

Related: #9574

Updates #1813
Updates #1152

Change-Id: Iec6ec9b4b5db7a4dc700ecdf4a11146cc5303989
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick 32ce1bdb48 ipn/ipnlocal: use "nb" consistently as receiver for nodeBackend
Cleanup after #15866. It was using a mix of "b" and "c" before. But "b"
is ambiguous with LocalBackend's usual "b".

Updates #12614

Change-Id: I8c2e84597555ec3db0d783a00ac1c12549ce6706
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick 653c45585e ipn/ipnlocal: rename localNodeContext to nodeBackend
As just discussed on Slack with @nickkhyl.

Updates #12614

Change-Id: I138dd7eaffb274494297567375d969b4122f3f50
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick a0d7c81a27 ipn/ipnlocal: fix Taildrop regression from refactoring
This fixes a refactoring bug introduced in 8b72dd7873

Tests (that failed on this) are coming in a separate change.

Updates #15812

Change-Id: Ibbf461b4eaefe22ad3005fc243d0a918e8af8981
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick c09cd34f59 ipn/ipnlocal: fix Taildrop deadlock
This fixes the Taildrop deadlock from 8b72dd7873.

Fixes #15824

Change-Id: I5ca583de20dd0d0b513ce546439dc632408ca1f1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Nick Khyl 66371f392a feature,ipn/ipnlocal: add profileManager.StateChangeHook
We update profileManager to allow registering a single state (profile+prefs) change hook.
This is to invert the dependency between the profileManager and the LocalBackend, so that
instead of LocalBackend asking profileManager for the state, we can have profileManager
call LocalBackend when the state changes.

We also update feature.Hook with a new (*feature.Hook).GetOk method to avoid calling both
IsSet and Get.

Updates tailscale/corp#28014
Updates #12614

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Nick Khyl 0cfd643d95 ipn/ipnlocal: update profileManager to use SwitchToProfile when switching to the initial profile
This further minimizes the number of places where the profile manager updates the current profile and prefs.

We also document a scenario where an implicit profile switch can occur.
We should be able to address it after (partially?) inverting the dependency between
LocalBackend and profileManager, so that profileManager notifies LocalBackend
of profile changes instead of the other way around.

Updates tailscale/corp#28014
Updates #12614

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Nick Khyl 8b72dd7873 ipn/ipnlocal: add localNodeContext with netmap-related fields and methods
Updates #12614

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Brad Fitzpatrick dbf13976d3 types/mapx, ipn/ipnext: add ordered map, akin to set.Slice
We had an ordered set type (set.Slice) already but we occasionally want
to do the same thing with a map, preserving the order things were added,
so add that too, as mapsx.OrderedMap[K, V], and then use in ipnext.

Updates #12614

Change-Id: I85e6f5e11035571a28316441075e952aef9a0863
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick 3bc10ea585 ipn/ipnext: remove some interface indirection to add hooks
Now that 25c4dc5fd7 removed unregistering hooks and made them into
slices, just expose the slices and remove the setter funcs.

This removes boilerplate ceremony around adding new hooks.

This does export the hooks and make them mutable at runtime in theory,
but that'd be a data race. If we really wanted to lock it down in the
future we could make the feature.Hooks slice type be an opaque struct
with an All() iterator and a "frozen" bool and we could freeze all the
hooks after init. But that doesn't seem worth it.

This means that hook registration is also now all in one place, rather
than being mixed into ProfilesService vs ipnext.Host vs FooService vs
BarService. I view that as a feature. When we have a ton of hooks and
the list is long, then we can rearrange the fields in the Hooks struct
as needed, or make sub-structs, or big comments.

Updates #12614

Change-Id: I05ce5baa45a61e79c04591c2043c05f3288d8587
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick 3d8533b5d0 ipn/{ipnext,ipnlocal}: add a SafeBackend interface
Updates #12614

Change-Id: I197e673666e86ea74c19e3935ed71aec269b6c94
Co-authored-by: Nick Khyl <nickk@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Brad Fitzpatrick 25c4dc5fd7 ipn/ipnext: remove support for unregistering extension
Updates #12614

Change-Id: I893e3ea74831deaa6f88e31bba2d95dc017e0470
Co-authored-by: Nick Khyl <nickk@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
7 months ago
Nick Khyl bd33eb7bd7 ipn/ipnlocal: use tsd.NewSystem instead of &tsd.System in a few more tests
These were likely added after everything else was updated to use tsd.NewSystem,
in a feature branch, and before it was merged back into main.

Updates #15160

Signed-off-by: Nick Khyl <nickk@tailscale.com>
7 months ago
Nick Khyl 7090f7fffc ipn/ipnlocal: use MagicDNSName of the current profile instead of generating a full ipnstate.Status
Both are populated from the current netmap's MagicDNSSuffix.
But building a full ipnstate.Status (with peers!) is expensive and unnecessary.

Updates #cleanup

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Brad Fitzpatrick 898cf06898 ipn/ipnlocal: remove another copy of slicesx.MapValues
We added this helper in 1e2e319e7d. Remove this copy.

Updates #cleanup

Change-Id: I5b0681acc23692beed35951c9902ac9ceca0a8b9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Brad Fitzpatrick 0c78f081a4 feature/taildrop: start moving Taildrop out of LocalBackend
This adds a feature/taildrop package, a ts_omit_taildrop build tag,
and starts moving code to feature/taildrop. In some cases, code
remains where it was but is now behind a build tag. Future changes
will move code to an extension and out of LocalBackend, etc.

Updates #12614

Change-Id: Idf96c61144d1a5f707039ceb2ff59c99f5c1642f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
David Anderson 5399fa159a net/netmon: publish events to event bus
Updates #15160

Signed-off-by: David Anderson <dave@tailscale.com>
8 months ago
M. J. Fromberger deb0b255ff all: update the tsd.System constructor name (#15372)
Replace NewSystemWithEventBus with plain NewSystem, and update all usage.
See https://github.com/tailscale/tailscale/pull/15355#discussion_r2003910766

Updates #15160

Change-Id: I64d337f09576b41d9ad78eba301a74b9a9d6ebf4
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
8 months ago
M. J. Fromberger 418e19fb5e portmapper: update NewClient to use a Config argument
In preparation for adding more parameters (and later, moving some away), rework
the portmapper constructor to accept its arguments on a Config struct rather
than positionally.

This is a breaking change to the function signature, but one that is very easy
to update, and a search of GitHub reveals only six instances of usage outside
clones and forks of Tailscale itself, that are not direct copies of the code
fixed up here.

While we could stub in another constructor, I think it is safe to let those
folks do the update in-place, since their usage is already affected by other
changes we can't test for anyway.

Updates #15160

Change-Id: I9f8a5e12b38885074c98894b7376039261b43f43
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
8 months ago
M. J. Fromberger ffb22ee353 all: construct new System values with an event bus pre-populated
Although, at the moment, we do not yet require an event bus to be present, as
we start to add more pieces we will want to ensure it is always available.  Add
a new constructor and replace existing uses of new(tsd.System) throughout.
Update generated files for import changes.

Updates #15160

Change-Id: Ie5460985571ade87b8eac8b416948c7f49f0f64b
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
8 months ago
Andrew Lytvynov 34b97a3c75
ipn/ipnlocal: fix TestOnTailnetDefaultAutoUpdate on macOS (#15697)
https://github.com/tailscale/tailscale/pull/15395 changed the logic to
skip `EditPrefs` when the platform doesn't support auto-updates. But the
old logic would only fail `EditPrefs` if the auto-update value was
`true`. If it was `false`, `EditPrefs` would succeed and store `false`
in prefs. The new logic will keep the value `unset` even if the tailnet
default is `false`.

Fixes #15691

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
8 months ago
Nick Khyl e6eba4efee ipn/{auditlog,ipnext,ipnlocal}: convert the profile-change callback to a profile-state-change callback
In this PR, we enable extensions to track changes in the current prefs. These changes can result from a profile switch
or from the user or system modifying the current profile’s prefs. Since some extensions may want to distinguish between
the two events, while others may treat them similarly, we rename the existing profile-change callback to become
a profile-state-change callback and invoke it whenever the current profile or its preferences change. Extensions can still
use the sameNode parameter to distinguish between situations where the profile information, including its preferences,
has been updated but still represents the same tailnet node, and situations where a switch to a different profile has been made.

Having dedicated prefs-change callbacks is being considered, but currently seems redundant. A single profile-state-change callback
is easier to maintain. We’ll revisit the idea of adding a separate callback as we progress on extracting existing features from LocalBackend,
but the conversion to a profile-state-change callback is intended to be permanent.

Finally, we let extensions retrieve the current prefs or profile state (profile info + prefs) at any time using the new
CurrentProfileState and CurrentPrefs methods. We also simplify the NewControlClientCallback signature to exclude
profile prefs. It’s optional, and extensions can retrieve the current prefs themselves if needed.

Updates #12614
Updates tailscale/corp#27645
Updates tailscale/corp#26435
Updates tailscale/corp#27502

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Jordan Whited 7833145289
ipn/auditlog: fix featureName doc typo (#15696)
Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
8 months ago
Brad Fitzpatrick 4107056612 ipn/ipnlocal: skip broken TestOnTailnetDefaultAutoUpdate on macOS
Updates #15691

Change-Id: I131aed8bcd83be8e97399c905683e046381c9106
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Nick Khyl 60614fa4e5 ipn/desktop: fix panics on Windows 10, x86
[G,S]etWindowLongPtrW are not available on 32-bit Windows, where [G,S]etWindowLongW should be used instead.
The initial revision of #14945 imported the win package for calling and other Win32 API functions, which exported
the correct API depending on the platform. However, the same logic wasn't implemented when we removed
the win package dependency in a later revision, resulting in panics on Windows 10 x86 (there's no 32-bit Windows 11).

In this PR, we update the ipn/desktop package to use either [G,S]etWindowLongPtrW or [G,S]etWindowLongW
depending on the platform.

Fixes #15684

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Jonathan Nobels d6fd865d41
hostinfo, ipnlocal: add optional os-specific callback for querying the hostname (#15647)
updates tailscale/tailscale#13476

On darwin, os.Hostname is no longer reliable when called
from a sandboxed process.  To fix this, we will allow clients
to set an optional callback to query the hostname via an
alternative native API.

We will leave the default implementation as os.Hostname since
this works perfectly well for almost everything besides sandboxed
darwin clients.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
8 months ago
Nick Khyl f28c8d0ec0 ipn/ipn{ext,local}: allow extension lookup by name or type
In this PR, we add two methods to facilitate extension lookup by both extensions,
and non-extensions (e.g., PeerAPI or LocalAPI handlers):
 - FindExtensionByName returns an extension with the specified name.
   It can then be type asserted to a given type.
 - FindMatchingExtension is like errors.As, but for extensions.
   It returns the first extension that matches the target type (either a specific extension
   or an interface).

Updates tailscale/corp#27645
Updates tailscale/corp#27502

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Nick Khyl 4941cd7c73 cmd/tailscaled,ipn/{auditlog,desktop,ipnext,ipnlocal},tsd: extract LocalBackend extension interfaces and implementation
In this PR, we refactor the LocalBackend extension system, moving from direct callbacks to a more organized extension host model.

Specifically, we:
- Extract interface and callback types used by packages extending LocalBackend functionality into a new ipn/ipnext package.
- Define ipnext.Host as a new interface that bridges extensions with LocalBackend.
  It enables extensions to register callbacks and interact with LocalBackend in a concurrency-safe, well-defined, and controlled way.
- Move existing callback registration and invocation code from ipnlocal.LocalBackend into a new type called ipnlocal.ExtensionHost,
  implementing ipnext.Host.
- Improve docs for existing types and methods while adding docs for the new interfaces.
- Add test coverage for both the extracted and the new code.
- Remove ipn/desktop.SessionManager from tsd.System since ipn/desktop is now self-contained.
- Update existing extensions (e.g., ipn/auditlog and ipn/desktop) to use the new interfaces where appropriate.

We're not introducing new callback and hook types (e.g., for ipn.Prefs changes) just yet, nor are we enhancing current callbacks,
such as by improving conflict resolution when more than one extension tries to influence profile selection via a background profile resolver.
These further improvements will be submitted separately.

Updates #12614
Updates tailscale/corp#27645
Updates tailscale/corp#26435
Updates tailscale/corp#18342

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Brad Fitzpatrick 6c914409cd Revert "ipn/ipnstate: add home DERP to tailscale status JSON"
This reverts commit 476a4c6ff1.

Reason: redundant with `tailscale status --json | jq '.Self.Relay'`
which we all forgot about. Whoops.

Updates #15625
8 months ago
Nick Khyl 94f4f83731 ipn, ipn/ipnlocal: reduce coupling between LocalBackend/profileManager and the Windows-specific "current user" model
Ultimately, we'd like to get rid of the concept of the "current user". It is only used on Windows,
but even then it doesn't work well in multi-user and enterprise/managed Windows environments.

In this PR, we update LocalBackend and profileManager to decouple them a bit more from this obsolete concept.
This is done in a preparation for extracting ipnlocal.Extension-related interfaces and types, and using them
to implement optional features like tailscale/corp#27645, instead of continuing growing the core ipnlocal logic.

Notably, we rename (*profileManager).SetCurrentUserAndProfile() to SwitchToProfile() and change its signature
to accept an ipn.LoginProfileView instead of an ipn.ProfileID and ipn.WindowsUserID. Since we're not removing
the "current user" completely just yet, the method sets the current user to the owner of the target profile.

We also update the profileResolver callback type, which is typically implemented by LocalBackend extensions,
to return an ipn.LoginProfileView instead of ipn.ProfileID and ipn.WindowsUserID.

Updates tailscale/corp#27645
Updates tailscale/corp#18342

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Brad Fitzpatrick 476a4c6ff1 ipn/ipnstate: add home DERP to tailscale status JSON
Fixes #15625

Change-Id: Ic20dad2dab4ac52c666057845bdc3cf5c0ffcd8f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
kari-ts 5c562116fc
ipnlocal: log when client reports new peerAPI ports (#15463)
Updates tailscale/tailscale#14393

Signed-off-by: kari-ts <kari@tailscale.com>
8 months ago
Jordan Whited 6133f44344
ipn/ipnlocal: fix peerapi ingress endpoint (#15611)
The http.StatusMethodNotAllowed status code was being erroneously
set instead of http.StatusBadRequest in multiple places.

Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
8 months ago
Jordan Whited e17abbf461
cmd/tailscale,ipn: add relay-server-port "tailscale set" flag and Prefs field (#15594)
This flag is currently no-op and hidden. The flag does round trip
through the related pref. Subsequent commits will tie them to
net/udprelay.Server. There is no corresponding "tailscale up" flag,
enabling/disabling of the relay server will only be supported via
"tailscale set".

This is a string flag in order to support disablement via empty string
as a port value of 0 means "enable the server and listen on a random
unused port". Disablement via empty string also follows existing flag
convention, e.g. advertise-routes.

Early internal discussions settled on "tailscale set --relay="<port>",
but the author felt this was too ambiguous around client vs server, and
may cause confusion in the future if we add related flags.

Updates tailscale/corp#27502

Signed-off-by: Jordan Whited <jordan@tailscale.com>
8 months ago
Andrew Lytvynov 463b47a0ab
ipn/ipnlocal: include previous cert in new ACME orders (#15595)
When we have an old cert that is being rotated, include it in the order.
If we're in the ARI-recommended rotation window, LE should exclude us
from rate limits. If we're not within that window, the order still
succeeds, so there's no risk in including the old cert.

Fixes #15542

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
8 months ago
Brad Fitzpatrick fd580611bd ipn: use slices.Equal in another spot
Updates #8632

Change-Id: I91edd800f97eb0bf9a00866a1e39effc5e4f4e94
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Jordan Whited 8c062c07c6
ipn/ipnlocal: fix taildrive logf formatting verb (#15514)
Updates #cleanup

Signed-off-by: Jordan Whited <jordan@tailscale.com>
8 months ago
Brad Fitzpatrick b3953ce0c4 ssh/tailssh: add Plan 9 support for Tailscale SSH
Updates #5794

Change-Id: I7b05cd29ec02085cb503bbcd0beb61bf455002ac
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Brad Fitzpatrick 03b9b879ee ipn/ipnserver: treat all plan9 safesocket connections as permitted
Updates #5794

Change-Id: Ibf74d017e38e0713d19bef437f26685280d79f6f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Brad Fitzpatrick bbdd3c3bde wgengine/router: add Plan 9 implementation
Updates #5794

Change-Id: Ib78a3ea971a2374d405b024ab88658ec34be59a6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Percy Wegmann a7be3a3d86 ipn/ipnlocal: add debug logging to initPeerAPIListener
initPeerAPIListener may be returning early unexpectedly. Add debug logging to
see what causes it to return early when it does.

Updates #14393

Signed-off-by: Percy Wegmann <percy@tailscale.com>
8 months ago
Kristoffer Dalby cdde301ca5 ipn/ipnlocal: return old hwaddrs if missing
If we previously knew of macaddresses of a node, and they
suddenly goes to zero, ignore them and return the previous
hardware addresses.

Updates tailscale/corp#25168

Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
8 months ago
Nick Khyl 6a9a7f35d9 cmd/tailscaled,ipn/{auditlog,ipnlocal},tsd: omit auditlog unless explicitly imported
In this PR, we update ipnlocal.LocalBackend to allow registering callbacks for control client creation
and profile changes. We also allow to register ipnauth.AuditLogFunc to be called when an auditable
action is attempted.

We then use all this to invert the dependency between the auditlog and ipnlocal packages and make
the auditlog functionality optional, where it only registers its callbacks via ipnlocal-provided hooks
when the auditlog package is imported.

We then underscore-import it when building tailscaled for Windows, and we'll explicitly
import it when building xcode/ipn-go-bridge for macOS. Since there's no default log-store
location for macOS, we'll also need to call auditlog.SetStoreFilePath to specify where
pending audit logs should be persisted.

Fixes #15394
Updates tailscale/corp#26435
Updates tailscale/corp#27012

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Nick Khyl 272854df41 ipn/ipnlocal: unconfigure wgengine when switching profiles
LocalBackend transitions to ipn.NoState when switching to a different (or new) profile.
When this happens, we should unconfigure wgengine to clear routes, DNS configuration,
firewall rules that block all traffic except to the exit node, etc.

In this PR, we update (*LocalBackend).enterStateLockedOnEntry to do just that.

Fixes #15316
Updates tailscale/corp#23967

Signed-off-by: Nick Khyl <nickk@tailscale.com>
8 months ago
Simon Law e9324236e8 cmd/tailscale: fix default for `tailscale set --accept-routes`
The default values for `tailscale up` and `tailscale set` are supposed
to agree for all common flags. But they don’t for `--accept-routes`
on Windows and from the Mac OS App Store, because `tailscale up`
computes this value based on the operating system:

    user@host:~$ tailscale up --help 2>&1 | grep -A1 accept-routes
      --accept-dns, --accept-dns=false
            accept DNS configuration from the admin panel (default true)
    user@host:~$ tailscale set --help 2>&1 | grep -A1 accept-routes
      --accept-dns, --accept-dns=false
            accept DNS configuration from the admin panel

Luckily, `tailscale set` uses `ipn.MaskedPrefs`, so the default values
don’t logically matter. But someone will get the wrong idea if they
trust the `tailscale set --help` documentation.

In addition, `ipn.Prefs.RouteAll` defaults to true so it disagrees
with both of the flags above.

This patch makes `--accept-routes` use the same logic for in both
commands by hoisting the logic that was buried in `cmd/tailscale/cli`
to `ipn.Prefs.DefaultRouteAll`. Then, all three of defaults can agree.

Fixes: #15319

Signed-off-by: Simon Law <sfllaw@sfllaw.ca>
8 months ago
Irbe Krumina 4777cc2cda
ipn/store/kubestore: skip cache for the write replica in cert share mode (#15417)
ipn/store/kubestore: skip cache for the write replica in cert share mode

This is to avoid issues where stale cache after Ingress recreation
causes the certs not to be re-issued.

Updates tailscale/corp#24795

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
8 months ago
Jonathan Nobels 725c8d298a
ipn/ipnlocal: remove misleading [unexpected] log for auditlog (#15421)
fixes tailscale/tailscale#15394

In the current iteration, usage of the memstore for the audit
logger is expected on some platforms.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
8 months ago
Percy Wegmann e78055eb01 ipn/ipnlocal: add more logging for initializing peerAPIListeners
On Windows and Android, peerAPIListeners may be initialized after a link change.
This commit adds log statements to make it easier to trace this flow.

Updates #14393

Signed-off-by: Percy Wegmann <percy@tailscale.com>
8 months ago
Brad Fitzpatrick 14db99241f net/netmon: use Monitor's tsIfName if set by SetTailscaleInterfaceName
Currently nobody calls SetTailscaleInterfaceName yet, so this is a
no-op. I checked oss, android, and the macOS/iOS client. Nobody calls
this, or ever did.

But I want to in the future.

Updates #15408
Updates #9040

Change-Id: I05dfabe505174f9067b929e91c6e0d8bc42628d7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Brad Fitzpatrick d0c50c6072 clientupdate: cache CanAutoUpdate, avoid log spam when false
I noticed logs on one of my machines where it can't auto-update with
scary log spam about "failed to apply tailnet-wide default for
auto-updates".

This avoids trying to do the EditPrefs if we know it's just going to
fail anyway.

Updates #282

Change-Id: Ib7db3b122185faa70efe08b60ebd05a6094eed8c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
8 months ago
Nick Khyl f3f2f72f96 ipn/ipnlocal: do not attempt to start the auditlogger with a nil transport
(*LocalBackend).setControlClientLocked() is called to both set and reset b.cc.
We shouldn't attempt to start the audit logger when b.cc is being reset (i.e., cc is nil).

However, it's fine to start the audit logger if b.cc implements auditlog.Transport, even if it's not a controlclient.Auto but a mock control client.

In this PR, we fix both issues and add an assertion that controlclient.Auto is an auditlog.Transport. This ensures a compile-time failure if controlclient.Auto ever stops being a valid transport due to future interface or implementation changes.

Updates tailscale/corp#26435

Signed-off-by: Nick Khyl <nickk@tailscale.com>
9 months ago
Nick Khyl e07c1573f6 ipn/ipnlocal: do not reset the netmap and packet filter in (*LocalBackend).Start()
Resetting LocalBackend's netmap without also unconfiguring wgengine to reset routes, DNS, and the killswitch
firewall rules may cause connectivity issues until a new netmap is received.

In some cases, such as when bootstrap DNS servers are inaccessible due to network restrictions or other reasons,
or if the control plane is experiencing issues, this can result in a complete loss of connectivity until the user disconnects
and reconnects to Tailscale.

As LocalBackend handles state resets in (*LocalBackend).resetForProfileChangeLockedOnEntry(), and this includes
resetting the netmap, resetting the current netmap in (*LocalBackend).Start() is not necessary.
Moreover, it's harmful if (*LocalBackend).Start() is called more than once for the same profile.

In this PR, we update resetForProfileChangeLockedOnEntry() to reset the packet filter and remove
the redundant resetting of the netmap and packet filter from Start(). We also update the state machine
tests and revise comments that became inaccurate due to previous test updates.

Updates tailscale/corp#27173

Signed-off-by: Nick Khyl <nickk@tailscale.com>
9 months ago
Irbe Krumina f34e08e186
ipn: ensure that conffile is source of truth for advertised services. (#15361)
If conffile is used to configure tailscaled, always update
currently advertised services from conffile, even if they
are empty in the conffile, to ensure that it is possible
to transition to a state where no services are advertised.

Updates tailscale/corp#24795

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
9 months ago
Irbe Krumina f50d3b22db
cmd/k8s-operator: configure proxies for HA Ingress to run in cert share mode (#15308)
cmd/k8s-operator: configure HA Ingress replicas to share certs

Creates TLS certs Secret and RBAC that allows HA Ingress replicas
to read/write to the Secret.
Configures HA Ingress replicas to run in read-only mode.

Updates tailscale/corp#24795


Signed-off-by: Irbe Krumina <irbe@tailscale.com>
9 months ago
Irbe Krumina 34734ba635
ipn/store/kubestore,kube,envknob,cmd/tailscaled/depaware.txt: allow kubestore read/write custom TLS secrets (#15307)
This PR adds some custom logic for reading and writing
kube store values that are TLS certs and keys:
1) when store is initialized, lookup additional
TLS Secrets for this node and if found, load TLS certs
from there
2) if the node runs in certs 'read only' mode and
TLS cert and key are not found in the in-memory store,
look those up in a Secret
3) if the node runs in certs 'read only' mode, run
a daily TLS certs reload to memory to get any
renewed certs

Updates tailscale/corp#24795

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
9 months ago
James Sanderson 27ef9b666c ipn/ipnlocal: add test for CapMap packet filters
Updates tailscale/corp#20514

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
9 months ago
Irbe Krumina cd391b37a6
ipn/ipnlocal, envknob: make it possible to configure the cert client to act in read-only mode (#15250)
* ipn/ipnlocal,envknob: add some primitives for HA replica cert share.

Add an envknob for configuring
an instance's cert store as read-only, so that it
does not attempt to issue or renew TLS credentials,
only reads them from its cert store.
This will be used by the Kubernetes Operator's HA Ingress
to enable multiple replicas serving the same HTTPS endpoint
to be able to share the same cert.

Also some minor refactor to allow adding more tests
for cert retrieval logic.


Signed-off-by: Irbe Krumina <irbe@tailscale.com>
9 months ago
Jonathan Nobels 52710945f5
control/controlclient, ipn: add client audit logging (#14950)
updates tailscale/corp#26435

Adds client support for sending audit logs to control via /machine/audit-log.
Specifically implements audit logging for user initiated disconnections.

This will require further work to optimize the peristant storage and exclusion
via build tags for mobile:
tailscale/corp#27011
tailscale/corp#27012

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
9 months ago
Tom Proctor a6e19f2881
ipn/ipnlocal: allow cache hits for testing ACME certs (#15023)
PR #14771 added support for getting certs from alternate ACME servers, but the
certStore caching mechanism breaks unless you install the CA in system roots,
because we check the validity of the cert before allowing a cache hit, which
includes checking for a valid chain back to a trusted CA. For ease of testing,
allow cert cache hits when the chain is unknown to avoid re-issuing the cert
on every TLS request served. We will still get a cache miss when the cert has
expired, as enforced by a test, and this makes it much easier to test against
non-prod ACME servers compared to having to manage the installation of non-prod
CAs on clients.

Updates #14771

Change-Id: I74fe6593fe399bd135cc822195155e99985ec08a
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
9 months ago
Naman Sood a4b8c24834
ipn: sort VIP services before hashing (#15035)
We're computing the list of services to hash by iterating over the
values of a map, the ordering of which is not guaranteed. This can cause
the hash to fluctuate depending on the ordering if there's more than one
service hosted by the same host.

Updates tailscale/corp#25733.

Signed-off-by: Naman Sood <mail@nsood.in>
9 months ago
Percy Wegmann ce6ce81311 ipn/ipnlocal: initialize Taildrive shares when starting backend
Previously, it initialized when the backend was created. This caused two problems:

1. It would not properly switch when changing profiles.
2. If the backend was created before the profile had been selected, Taildrive's shares were uninitialized.

Updates #14825

Signed-off-by: Percy Wegmann <percy@tailscale.com>
9 months ago
Irbe Krumina a567f56445
ipn/store/kubestore: sanitize keys loaded to in-memory store (#15178)
Reads use the sanitized form, so unsanitized keys being stored
in memory resulted lookup failures, for example for serve config.

Updates tailscale/tailscale#15134

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
9 months ago
kari-ts dc18091678
ipn: update AddPeer to include TaildropTarget (#15091)
We previously were not merging in the TaildropTarget into the PeerStatus because we did not update AddPeer.

Updates tailscale/tailscale#14393

Signed-off-by: kari-ts <kari@tailscale.com>
9 months ago
Lee Briggs 74d7d8a77b ipn/store/awsstore: allow providing a KMS key
Implements a KMS input for AWS parameter to support encrypting Tailscale
state

Fixes #14765

Change-Id: I39c0fae4bfd60a9aec17c5ea6a61d0b57143d4ba
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Lee Briggs <lee@leebriggs.co.uk>
9 months ago
KevinLiang10 8c2717f96a
ipn/ipnlocal: send vipServices info via c2n even it's incomplete (#15166)
This commit updates the logic of vipServicesFromPrefsLocked, so that it would return the vipServices list
even when service host is only advertising the service but not yet serving anything. This makes control
always get accurate state of service host in terms of serving a service.

Fixes tailscale/corp#26843

Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
9 months ago
Irbe Krumina b85d18d14e
ipn/{ipnlocal,store},kube/kubeclient: store TLS cert and key pair to a Secret in a single operation. (#15147)
To avoid duplicate issuances/slowness while the state Secret
contains a mismatched cert and key.

Updates tailscale/tailscale#15134
Updates tailscale/corp#24795

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
9 months ago
Nick Khyl 8d7033fe7f ipn/ipnlocal,util/syspolicy,docs/windows/policy: implement the ReconnectAfter policy setting
In this PR, we update the LocalBackend so that when the ReconnectAfter policy setting is configured
and a user disconnects Tailscale by setting WantRunning to false in the profile prefs, the LocalBackend
will now start a timer to set WantRunning back to true once the ReconnectAfter timer expires.

We also update the ADMX/ADML policy definitions to allow configuring this policy setting for Windows
via Group Policy and Intune.

Updates #14824

Signed-off-by: Nick Khyl <nickk@tailscale.com>
9 months ago
Nick Khyl 09982e1918 ipn/ipnlocal: reset always-on override and apply policy settings on start
We already reset the always-on override flag when switching profiles and in a few other cases.
In this PR, we update (*LocalBackend).Start() to reset it as well. This is necessary to support
scenarios where Start() is called explicitly, such as when the GUI starts or when tailscale up is used
with additional flags and passes prefs via ipn.Options in a call to Start() rather than via EditPrefs.

Additionally, we update it to apply policy settings to the current prefs, which is necessary
for properly overriding prefs specified in ipn.Options.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Irbe Krumina b21eec7621
ipn/ipnlocal,tailcfg: don't send WireIngress if IngressEnabled already true (#14960)
Hostinfo.WireIngress is used as a hint that the node intends to use
funnel. We now send another field, IngressEnabled, in cases where
funnel is explicitly enabled, and the logic control-side has
been changed to look at IngressEnabled as well as WireIngress in all
cases where previously the hint was used - so we can now stop sending
WireIngress when IngressEnabled is true to save some bandwidth.

Updates tailscale/tailscale#11572
Updates tailscale/corp#25931

Signed-off-by: Irbe Krumina <irbe@tailscale.com>
10 months ago
Nick Khyl 6df5c8f32e various: keep tailscale connected when Always On mode is enabled on Windows
In this PR, we enable the registration of LocalBackend extensions to exclude code specific to certain
platforms or environments. We then introduce desktopSessionsExt, which is included only in Windows builds
and only if the ts_omit_desktop_sessions tag is disabled for the build. This extension tracks desktop sessions
and switches to (or remains on) the appropriate profile when a user signs in or out, locks their screen,
or disconnects a remote session.

As desktopSessionsExt requires an ipn/desktop.SessionManager, we register it with tsd.System
for the tailscaled subprocess on Windows.

We also fix a bug in the sessionWatcher implementation where it attempts to close a nil channel on stop.

Updates #14823
Updates tailscale/corp#26247

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
kari-ts 4c3c04a413
ipn, tailscale/cli: add TaildropTargetStatus and remove race with FileTargets (#15017)
Introduce new TaildropTargetStatus in PeerStatus
Refactor getTargetStableID to solely rely on Status() instead of calling FileTargets(). This removes a possible race condition between the two calls and provides more detailed failure information if a peer can't receive files.

Updates tailscale/tailscale#14393

Signed-off-by: kari-ts <kari@tailscale.com>
10 months ago
James 'zofrex' Sanderson e142571397
ipn/ipnlocal: add GetFilterForTest (#15025)
Needed to test full packet filter in e2e tests. See tailscale/corp#26596

Updates tailscale/corp#20514

Signed-off-by: James Sanderson <jsanderson@tailscale.com>
10 months ago
Nick Khyl 7aef4fd44d ipn/ipn{local,server}: extract logic that determines the "best" Tailscale profile to use
In this PR, we further refactor LocalBackend and Unattended Mode to extract the logic that determines
which profile should be used at the time of the check, such as when a LocalAPI client connects or disconnects.
We then update (*LocalBackend).switchProfileLockedOnEntry to to switch to the profile returned by
(*LocalBackend).resolveBestProfileLocked() rather than to the caller-specified specified profile, and rename it
to switchToBestProfileLockedOnEntry.

This is done in preparation for updating (*LocalBackend).getBackgroundProfileIDLocked to support Always-On
mode by determining which profile to use based on which users, if any, are currently logged in and have an active
foreground desktop session.

Updates #14823
Updates tailscale/corp#26247

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 9b32ba7f54 ipn/ipn{local,server}: move "staying alive in server mode" from ipnserver to LocalBackend
Currently, we disconnect Tailscale and reset LocalBackend on Windows when the last LocalAPI client
disconnects, unless Unattended Mode is enabled for the current profile. And the implementation
is somewhat racy since the current profile could theoretically change after
(*ipnserver.Server).addActiveHTTPRequest checks (*LocalBackend).InServerMode() and before it calls
(*LocalBackend).SetCurrentUser(nil) (or, previously, (*LocalBackend).ResetForClientDisconnect).

Additionally, we might want to keep Tailscale running and connected while a user is logged in
rather than tying it to whether a LocalAPI client is connected (i.e., while the GUI is running),
even when Unattended Mode is disabled for a profile. This includes scenarios where the new
AlwaysOn mode is enabled, as well as when Tailscale is used on headless Windows editions,
such as Windows Server Core, where the GUI is not supported. It may also be desirable to switch
to the "background" profile when a user logs off from their device or implement other similar
features.

To facilitate these improvements, we move the logic from ipnserver.Server to ipnlocal.LocalBackend,
where it determines whether to keep Tailscale running when the current user disconnects.
We also update the logic that determines whether a connection should be allowed to better reflect
the fact that, currently, LocalAPI connections are not allowed unless:
 - the current UID is "", meaning that either we are not on a multi-user system or Tailscale is idle;
 - the LocalAPI client belongs to the current user (their UIDs are the same);
 - the LocalAPI client is Local System (special case; Local System is always allowed).
Whether Unattended Mode is enabled only affects the error message returned to the Local API client
when the connection is denied.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl bc0cd512ee ipn/desktop: add a new package for managing desktop sessions on Windows
This PR adds a new package, ipn/desktop, which provides a platform-agnostic
interface for enumerating desktop sessions and registering session callbacks.
Currently, it is implemented only for Windows.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 5eacf61844 ipn/ipnauth: implement WindowsActor
WindowsActor is an ipnauth.Actor implementation that represents a logged-in
Windows user by wrapping their Windows user token.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl e9e2bc5bd7 ipn/ipn{auth,server}: update ipnauth.Actor to carry a context
The context carries additional information about the actor, such as the
request reason, and is canceled when the actor is done.

Additionally, we implement three new ipn.Actor types that wrap other actors
to modify their behavior:
 - WithRequestReason, which adds a request reason to the actor;
 - WithoutClose, which narrows the actor's interface to prevent it from being
   closed;
 - WithPolicyChecks, which adds policy checks to the actor's CheckProfileAccess
   method.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Brad Fitzpatrick 9706c9f4ff types/netmap,*: pass around UserProfiles as views (pointers) instead
Smaller.

Updates tailscale/corp#26058 (@andrew-d noticed during this)

Change-Id: Id33cddd171aaf8f042073b6d3c183b0a746e9931
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
10 months ago
Nick Khyl 48dd4bbe21 ipn/ipn{local,server}: remove ResetForClientDisconnect in favor of SetCurrentUser(nil)
There’s (*LocalBackend).ResetForClientDisconnect, and there’s also (*LocalBackend).resetForProfileChangeLockedOnEntry.
Both methods essentially did the same thing but in slightly different ways. For example, resetForProfileChangeLockedOnEntry didn’t reset the control client until (*LocalBackend).Start() was called at the very end and didn’t reset the keyExpired flag, while ResetForClientDisconnect didn’t reinitialize TKA.

Since SetCurrentUser can be called with a nil argument to reset the currently connected user and internally calls resetForProfileChangeLockedOnEntry, we can remove ResetForClientDisconnect and let SetCurrentUser and resetForProfileChangeLockedOnEntry handle it.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 122255765a ipn/ipnlocal: fix (*profileManager).DefaultUserProfileID for users other than current
Currently, profileManager filters profiles based on their creator/owner and the "current user"'s UID.
This causes DefaultUserProfileID(uid) to work incorrectly when the UID doesn't match the current user.

While we plan to remove the concept of the "current user" completely, we're not there yet.

In this PR, we fix DefaultUserProfileID by updating profileManager to allow checking profile access
for a given UID and modifying helper methods to accept UID as a parameter when returning
matching profiles.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Jonathan Nobels 1bf4c6481a
safesocket: add ability for Darwin clients to set explicit credentials (#14702)
updates tailscale/corp#25687

The darwin appstore and standalone clients now support XPC and the keychain for passing user credentials securely between the gui process and an NEVPNExtension hosted tailscaled. Clients that can communicate directly with the network extension, via XPC or the keychain, are now expected to call SetCredentials and supply credentials explicitly, fixing issues with the cli breaking if the current user cannot read the contents of /Library/Tailscale due to group membership restrictions. This matches how those clients source and supply credentials to the localAPI http client.

Non-platform-specific code that has traditionally been in the client is moved to safesocket.

/Libraray/Tailscaled/sameuserproof has its permissions changed to that it's readably only by users in the admin group. This restricts standalone CLI access for and direct use of localAPI to admins.

Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
10 months ago
Brad Fitzpatrick 05ac21ebe4 all: use new LocalAPI client package location
It was moved in f57fa3cbc3.

Updates tailscale/corp#22748

Change-Id: I19f965e6bded1d4c919310aa5b864f2de0cd6220
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
10 months ago
Nick Khyl 9726e1f208 ipn/{ipnserver,localapi},tsnet: use ipnauth.Self as the actor in tsnet localapi handlers
With #14843 merged, (*localapi.Handler).servePrefs() now requires a non-nil actor,
and other places may soon require it as well.

In this PR, we update localapi.NewHandler with a new required parameter for the actor.
We then update tsnet to use ipnauth.Self.

We also rearrange the code in (*ipnserver.Server).serveHTTP() to pass the actor via Handler's
constructor instead of the field.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 00fe8845b1 ipn/{ipnauth,ipnlocal,ipnserver}: move the AlwaysOn policy check from ipnserver to ipnauth
In this PR, we move the code that checks the AlwaysOn policy from ipnserver.actor to ipnauth.
It is intended to be used by ipnauth.Actor implementations, and we temporarily make it exported
while these implementations reside in ipnserver and in corp. We'll unexport it later.

We also update [ipnauth.Actor.CheckProfileAccess] to accept an auditLogger, which is called
to write details about the action to the audit log when required by the policy, and update
LocalBackend.EditPrefsAs to use an auditLogger that writes to the regular backend log.

Updates tailscale/corp#26146

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Adrian Dewhurst 97c4c0ecf0 ipn/ipnlocal: add VIP service IPs to localnets
Without adding this, the packet filter rejects traffic to VIP service
addresses before checking the filters sent in the netmap.

Fixes tailscale/corp#26241

Change-Id: Idd54448048e9b786cf4873fd33b3b21e03d3ad4c
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
10 months ago
Adrian Dewhurst 600f25dac9 tailcfg: add JSON unmarshal helper for view of node/peer capabilities
Many places that need to work with node/peer capabilities end up with a
something-View and need to either reimplement the helper code or make an
expensive copy. We have the machinery to easily handle this now.

Updates #cleanup

Change-Id: Ic3f55be329f0fc6c178de26b34359d0e8c6ca5fc
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
10 months ago
James Tucker 10fe10ea10 derp/derphttp,ipn/localapi,net/captivedetection: add cache resistance to captive portal detection
Observed on some airlines (British Airways, WestJet), Squid is
configured to cache and transform these results, which is disruptive.
The server and client should both actively request that this is not done
by setting Cache-Control headers.

Send a timestamp parameter to further work against caches that do not
respect the cache-control headers.

Updates #14856

Signed-off-by: James Tucker <james@tailscale.com>
10 months ago
Nick Khyl d832467461 client/tailscale,ipn/ipn{local,server},util/syspolicy: implement the AlwaysOn.OverrideWithReason policy setting
In this PR, we update client/tailscale.LocalClient to allow sending requests with an optional X-Tailscale-Reason
header. We then update ipn/ipnserver.{actor,Server} to retrieve this reason, if specified, and use it to determine
whether ipnauth.Disconnect is allowed when the AlwaysOn.OverrideWithReason policy setting is enabled.
For now, we log the reason, along with the profile and OS username, to the backend log.

Finally, we update LocalBackend to remember when a disconnect was permitted and do not reconnect automatically
unless the policy changes.

Updates tailscale/corp#26146

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl a0537dc027 ipn/ipnlocal: fix a panic in setPrefsLockedOnEntry when cc is nil
The AlwaysOn policy can be applied by (*LocalBackend).applySysPolicy, flipping WantRunning from false to true
before (*LocalBackend).Start() has been called for the first time and set a control client in b.cc. This results in a nil
pointer dereference and a panic when setPrefsLockedOnEntry applies the change and calls controlclient.Client.Login().

In this PR, we fix it by only doing a login if b.cc has been set.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Percy Wegmann 2e95313b8b ssh,tempfork/gliderlabs/ssh: replace github.com/tailscale/golang-x-crypto/ssh with golang.org/x/crypto/ssh
The upstream crypto package now supports sending banners at any time during
authentication, so the Tailscale fork of crypto/ssh is no longer necessary.

github.com/tailscale/golang-x-crypto is still needed for some custom ACME
autocert functionality.

tempfork/gliderlabs is still necessary because of a few other customizations,
mostly related to TTY handling.

Originally implemented in 46fd4e58a2,
which was reverted in b60f6b849a to
keep the change out of v1.80.

Updates #8593

Signed-off-by: Percy Wegmann <percy@tailscale.com>
10 months ago
Nick Khyl 0a51bbc765 ipn/ipnauth,util/syspolicy: improve comments
Updates #cleanup
Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 02ad21717f ipn/ipn{auth,server,local}: initial support for the always-on mode
In this PR, we update LocalBackend to set WantRunning=true when applying policy settings
to the current profile's prefs, if the "always-on" mode is enabled.

We also implement a new (*LocalBackend).EditPrefsAs() method, which is like EditPrefs
but accepts an actor (e.g., a LocalAPI client's identity) that initiated the change.
If WantRunning is being set to false, the new EditPrefsAs method checks whether the actor
has ipnauth.Disconnect access to the profile and propagates an error if they do not.

Finally, we update (*ipnserver.actor).CheckProfileAccess to allow a disconnect
only if the "always-on" mode is not enabled by the AlwaysOn policy setting.

This is not a comprehensive solution to the "always-on" mode across platforms,
as instead of disconnecting a user could achieve the same effect by creating
a new empty profile, initiating a reauth, or by deleting the profile.
These are the things we should address in future PRs.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 535a3dbebd ipn/ipnauth: implement an Actor representing tailscaled itself
Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 081595de63 ipn/{ipnauth, ipnserver}: extend the ipnauth.Actor interface with a CheckProfileAccess method
The implementations define it to verify whether the actor has the requested access to a login profile.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Nick Khyl 4e7f4086b2 ipn: generate LoginProfileView and use it instead of *LoginProfile where appropriate
Conventionally, we use views (e.g., ipn.PrefsView, tailcfg.NodeView, etc.) when
dealing with structs that shouldn't be mutated. However, ipn.LoginProfile has been
an exception so far, with a mix of passing and returning LoginProfile by reference
(allowing accidental mutations) and by value (which is wasteful, given its
current size of 192 bytes).

In this PR, we generate an ipn.LoginProfileView and use it instead of passing/returning
LoginProfiles by mutable reference or copying them when passing/returning by value.
Now, LoginProfiles can only be mutated by (*profileManager).setProfilePrefs.

Updates #14823

Signed-off-by: Nick Khyl <nickk@tailscale.com>
10 months ago
Percy Wegmann b60f6b849a Revert "ssh,tempfork/gliderlabs/ssh: replace github.com/tailscale/golang-x-crypto/ssh with golang.org/x/crypto/ssh"
This reverts commit 46fd4e58a2.

We don't want to include this in 1.80 yet, but can add it back post 1.80.

Updates #8593

Signed-off-by: Percy Wegmann <percy@tailscale.com>
10 months ago
Percy Wegmann 46fd4e58a2 ssh,tempfork/gliderlabs/ssh: replace github.com/tailscale/golang-x-crypto/ssh with golang.org/x/crypto/ssh
The upstream crypto package now supports sending banners at any time during
authentication, so the Tailscale fork of crypto/ssh is no longer necessary.

github.com/tailscale/golang-x-crypto is still needed for some custom ACME
autocert functionality.

tempfork/gliderlabs is still necessary because of a few other customizations,
mostly related to TTY handling.

Updates #8593

Signed-off-by: Percy Wegmann <percy@tailscale.com>
10 months ago
Brad Fitzpatrick ba1f9a3918 types/persist: remove Persist.LegacyFrontendPrivateMachineKey
It was a temporary migration over four years ago. It's no longer
relevant.

Updates #610

Change-Id: I1f00c9485fab13ede6f77603f7d4235222c2a481
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
10 months ago
Brad Fitzpatrick 2691b9f6be tempfork/acme: add new package for x/crypto package acme fork, move
We've been maintaining temporary dev forks of golang.org/x/crypto/{acme,ssh}
in https://github.com/tailscale/golang-x-crypto instead of using
this repo's tempfork directory as we do with other packages. The reason we were
doing that was because x/crypto/ssh depended on x/crypto/ssh/internal/poly1305
and I hadn't noticed there are forwarding wrappers already available
in x/crypto/poly1305. It also depended internal/bcrypt_pbkdf but we don't use that
so it's easy to just delete that calling code in our tempfork/ssh.

Now that our SSH changes have been upstreamed, we can soon unfork from SSH.

That leaves ACME remaining.

This change copies our tailscale/golang-x-crypto/acme code to
tempfork/acme but adds a test that our vendored copied still matches
our tailscale/golang-x-crypto repo, where we can continue to do
development work and rebases with upstream. A comment on the new test
describes the expected workflow.

While we could continue to just import & use
tailscale/golang-x-crypto/acme, it seems a bit nicer to not have that
entire-fork-of-x-crypto visible at all in our transitive deps and the
questions that invites. Showing just a fork of an ACME client is much
less scary. It does add a step to the process of hacking on the ACME
client code, but we do that approximately never anyway, and the extra
step is very incremental compared to the existing tedious steps.

Updates #8593
Updates #10238

Change-Id: I8af4378c04c1f82e63d31bf4d16dba9f510f9199
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
10 months ago
Brad Fitzpatrick 68a66ee81b feature/capture: move packet capture to feature/*, out of iOS + CLI
We had the debug packet capture code + Lua dissector in the CLI + the
iOS app. Now we don't, with tests to lock it in.

As a bonus, tailscale.com/net/packet and tailscale.com/net/flowtrack
no longer appear in the CLI's binary either.

A new build tag ts_omit_capture disables the packet capture code and
was added to build_dist.sh's --extra-small mode.

Updates #12614

Change-Id: I79b0628c0d59911bd4d510c732284d97b0160f10
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
10 months ago
Tom Proctor 2089f4b603
ipn/ipnlocal: add debug envknob for ACME directory URL (#14771)
Adds an envknob setting for changing the client's ACME directory URL.
This allows testing cert issuing against LE's staging environment, as
well as enabling local-only test environments, which is useful for
avoiding the production rate limits in test and development scenarios.

Fixes #14761

Change-Id: I191c840c0ca143a20e4fa54ea3b2f9b7cbfc889f
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
10 months ago
Tom Proctor 69bc164c62
ipn/ipnlocal: include DNS SAN in cert CSR (#14764)
The CN field is technically deprecated; set the requested name in a DNS SAN
extension in addition to maximise compatibility with RFC 8555.

Fixes #14762

Change-Id: If5d27f1e7abc519ec86489bf034ac98b2e613043

Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
10 months ago
Andrew Lytvynov f1710f4a42
appc,ipn/ipnlocal: log DNS parsing errors in app connectors (#14607)
If we fail to parse the upstream DNS response in an app connector, we
might miss new IPs for the target domain. Log parsing errors to be able
to diagnose that.

Updates #14606

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
10 months ago
Brad Fitzpatrick 1562a6f2f2 feature/*: make Wake-on-LAN conditional, start supporting modular features
This pulls out the Wake-on-LAN (WoL) code out into its own package
(feature/wakeonlan) that registers itself with various new hooks
around tailscaled.

Then a new build tag (ts_omit_wakeonlan) causes the package to not
even be linked in the binary.

Ohter new packages include:

   * feature: to just record which features are loaded. Future:
     dependencies between features.
   * feature/condregister: the package with all the build tags
     that tailscaled, tsnet, and the Tailscale Xcode project
     extension can empty (underscore) import to load features
     as a function of the defined build tags.

Future commits will move of our "ts_omit_foo" build tags into this
style.

Updates #12614

Change-Id: I9c5378dafb1113b62b816aabef02714db3fc9c4a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
10 months ago
Andrew Lytvynov 3fb8a1f6bf
ipn/ipnlocal: re-advertise appc routes on startup, take 2 (#14740)
* Reapply "ipn/ipnlocal: re-advertise appc routes on startup (#14609)"

This reverts commit 51adaec35a.

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>

* ipn/ipnlocal: fix a deadlock in readvertiseAppConnectorRoutes

Don't hold LocalBackend.mu while calling the methods of
appc.AppConnector. Those methods could call back into LocalBackend and
try to acquire it's mutex.

Fixes https://github.com/tailscale/corp/issues/25965
Fixes #14606

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>

---------

Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
10 months ago
Adrian Dewhurst 0fa7b4a236 tailcfg: add ServiceName
Rather than using a string everywhere and needing to clarify that the
string should have the svc: prefix, create a separate type for Service
names.

Updates tailscale/corp#24607

Change-Id: I720e022f61a7221644bb60955b72cacf42f59960
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
11 months ago