This change allows tsnet nodes to act as Service hosts by adding a new
function, tsnet.Server.ListenService. Invoking this function will
advertise the node as a host for the Service and create a listener to
receive traffic for the Service.
Fixes#17697Fixestailscale/corp#27200
Signed-off-by: Harry Harpham <harry@tailscale.com>
This change adds API to ipn.LocalBackend to retrieve the ETag when
querying for the current serve config. This allows consumers of
ipn.LocalBackend.SetServeConfig to utilize the concurrency control
offered by ETags. Previous to this change, utilizing serve config ETags
required copying the local backend's internal ETag calcuation.
The local API server was previously copying the local backend's ETag
calculation as described above. With this change, the local API server
now uses the new ETag retrieval function instead. Serve config ETags are
therefore now opaque to clients, in line with best practices.
Fixestailscale/corp#35857
Signed-off-by: Harry Harpham <harry@tailscale.com>
fixestailscale/tailscale#18418
Both Serve and PeerAPI broke when we moved the TailscaleInterfaceName
into State, which is updated asynchronously and may not be
available when we configure the listeners.
This extracts the explicit interface name property from netmon.State
and adds as a static struct with getters that have proper error
handling.
The bug is only found in sandboxed Darwin clients, where we
need to know the Tailscale interface details in order to set up the
listeners correctly (they must bind to our interface explicitly to escape
the network sandboxing that is applied by NECP).
Currently set only sandboxed macOS and Plan9 set this but it will
also be useful on Windows to simplify interface filtering in netns.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
Policy editors, such as gpedit.msc and gpme.msc, rely on both the presence and the value of the
registry value to determine whether a policy is enabled. Unless an enabledValue is specified
explicitly, it defaults to REG_DWORD 1.
Therefore, we cannot rely on the same registry value to track the policy configuration state when
it is already used by a policy option, such as a dropdown. Otherwise, while the policy setting
will be written and function correctly, it will appear as Not Configured in the policy editor
due to the value mismatch (for example, REG_SZ "always" vs REG_DWORD 1).
In this PR, we update the DNSRegistration policy setting to use the DNSRegistrationConfigured
registry value for tracking. This change has no effect on the client side and exists solely to
satisfy ADMX and policy editor requirements.
Updates #14917
Signed-off-by: Nick Khyl <nickk@tailscale.com>
gocross-wrapper.ps1 is written to use the version of tar that ships with
Windows; we want to avoid conflicts with any other tar on the PATH, such
ones installed by MSYS and/or Cygwin.
Updates https://github.com/tailscale/corp/issues/29940
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Recently, the golangci-lint workflow has been taking longer and longer
to complete, causing it to timeout after the default of 5 minutes.
Running error: context loading failed: failed to load packages: failed to load packages: failed to load with go/packages: context deadline exceeded
Timeout exceeded: try increasing it by passing --timeout option
Although PR #18398 enabled the Go module cache, bootstrapping with a
cold cache still takes too long.
This PR doubles the default 5 minute timeout for golangci-lint to 10
minutes so that golangci-lint can finish downloading all of its
dependencies.
Note that this doesn’t affect the 5 minute timeout configured in
.golangci.yml, since running golangci-lint on your local instance
should still be plenty fast.
Fixes#18366
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Allow for optionally specifying an audience for containerboot. This is
passed to tailscale up to allow for containerboot to use automatic ID
token generation for authentication.
Updates https://github.com/tailscale/corp/issues/34430
Signed-off-by: Mario Minardi <mario@tailscale.com>
Allow for optionally specifiying an audience for tsnet. This is passed
to the underlying identity federation logic to allow for tsnet auth to
use automatic ID token generation for authentication.
Updates https://github.com/tailscale/corp/issues/33316
Signed-off-by: Mario Minardi <mario@tailscale.com>
If local tailscale/tailscale checkout is not available,
pulll cigocacher remotely.
Fall back to ./tool/go if no other Go installation
is present.
Updates tailscale/corp#32493
Signed-off-by: Irbe Krumina <irbekrm@gmail.com>
Adds the ability to detect what provider the client is running on and tries fetch the ID token to use with Workload Identity.
Updates https://github.com/tailscale/corp/issues/33316
Signed-off-by: Danni Popova <danni@tailscale.com>
Recently, the golangci-lint workflow has been taking longer and longer
to complete, causing it to timeout after the default of 5 minutes.
Running error: context loading failed: failed to load packages: failed to load packages: failed to load with go/packages: context deadline exceeded
Timeout exceeded: try increasing it by passing --timeout option
This PR upgrades actions/setup-go to version 6, the latest, and
enables caching for Go modules and build outputs. This should speed up
linting because most packages won’t have to be downloaded over and
over again.
Fixes#18366
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Fixes a bug where, for kube HA proxies, TLS certs for the replica
responsible for cert issuance where loaded in memory on startup,
although the in-memory store was not updated after renewal (to
avoid failing re-issuance for re-created Ingresses).
Now the 'write' replica always reads certs from the kube Secret.
Updates tailscale/tailscale#18394
Signed-off-by: Irbe Krumina <irbekrm@gmail.com>
Previously the funnel listener would leave artifacts in the serve
config. This caused weird out-of-sync effects like the admin panel
showing that funnel was enabled for a node, but the node rejecting
packets because the listener was closed.
This change resolves these synchronization issues by ensuring that
funnel listeners clean up the serve config when closed.
See also:
e109cf9fdd
Updates #cleanup
Signed-off-by: Harry Harpham <harry@tailscale.com>
Prior to this change, we were resetting the tsnet's serve config every
time tsnet.Server.Up was run. This is important to do on startup, to
prevent messy interactions with stale configuration when the code has
changed.
However, Up is frequently run as a just-in-case step (for example, by
Server.ListenTLS/ListenFunnel and possibly by consumers of tsnet). When
the serve config is reset on each of these calls to Up, this creates
situations in which the serve config disappears unexpectedly. The
solution is to reset the serve config only on the first call to Up.
Fixes#8800
Updates tailscale/corp#27200
Signed-off-by: Harry Harpham <harry@tailscale.com>
Add support for authenticating the gitops-pusher using workload identity
federation.
Updates https://github.com/tailscale/corp/issues/34172
Signed-off-by: Mario Minardi <mario@tailscale.com>
QR codes are used by `tailscale up --qr` to provide an easy way to
open a web-page without transcribing a difficult URI. However, there’s
no need for this feature if the client will never be called
interactively. So this PR adds the `ts_omit_qrcodes` build tag.
Updates #18182
Signed-off-by: Simon Law <sfllaw@tailscale.com>
It's not worth adding the v2 client just for these e2e tests. Remove
that dependency for now to keep a clear separation, but we should revive
the v2 client version if we ever decide to take that dependency for the
tailscale/tailscale repo as a whole.
Updates tailscale/corp#32085
Change-Id: Ic51ce233d5f14ce2d25f31a6c4bb9cf545057dd0
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
* cmd/k8s-operator/e2e: run self-contained e2e tests with devcontrol
Adds orchestration for more of the e2e testing setup requirements to
make it easier to run them in CI, but also run them locally in a way
that's consistent with CI. Requires running devcontrol, but otherwise
supports creating all the scaffolding required to exercise the operator
and proxies.
Updates tailscale/corp#32085
Change-Id: Ia7bff38af3801fd141ad17452aa5a68b7e724ca6
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
* cmd/k8s-operator/e2e: being more specific on tmp dir cleanup
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
---------
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
Raw Linux consoles support UTF-8, but we cannot assume that all UTF-8
characters are available. The default Fixed and Terminus fonts don’t
contain half-block characters (`▀` and `▄`), but do contain the
full-block character (`█`).
Sometimes, Linux doesn’t have a framebuffer, so it falls back to VGA.
When this happens, the full-block character could be anywhere in
extended ASCII block, because we don’t know which code page is active.
This PR introduces `--qr-format=auto` which tries to heuristically
detect when Tailscale is printing to a raw Linux console, whether
UTF-8 is enabled, and which block characters have been mapped in the
console font.
If Unicode characters are unavailable, the new `--qr-format=ascii`
formatter uses `#` characters instead of full-block characters.
Fixes#12935
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Moves magicksock.cloudInfo into util/cloudinfo with minimal changes.
Updates #17796
Change-Id: I83f32473b9180074d5cdbf00fa31e5b3f579f189
Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
Bump peter-evans/create-pull-request to 8.0.0 to ensure compatibility
with actions/checkout 6.x.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
The funnel command is sort of an alias for the serve command. This means
that the subcommands added to serve to support Services appear as
subcommands for funnel as well, despite having no meaning for funnel.
This change removes all such Services-specific subcommands from funnel.
Fixestailscale/corp#34167
Signed-off-by: Harry Harpham <harry@tailscale.com>
Ensure that hardware attestation keys are not added to tailscaled
state stores that are Kubernetes Secrets or AWS SSM as those Tailscale
devices should be able to be recreated on different nodes, for example,
when moving Pods between nodes.
Updates tailscale/tailscale#18302
Signed-off-by: Irbe Krumina <irbekrm@gmail.com>
TPM-based features have been incredibly painful due to the heterogeneous
devices in the wild, and many situations in which the TPM "changes" (is
reset or replaced). All of this leads to a lot of customer issues.
We hoped to iron out all the kinks and get all users to benefit from
state encryption and hardware attestation without manually opting in,
but the long tail of kinks is just too long.
This change disables TPM-based features on Windows and Linux by default.
Node state should get auto-decrypted on update, and old attestation keys
will be removed.
There's also tailscaled-on-macOS, but it won't have a TPM or Keychain
bindings anyway.
Updates #18302
Updates #15830
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Soft-fail on initial unmarshal and try again, ignoring the
AttestationKey. This helps in cases where something about the
attestation key storage (usually a TPM) is messed up. The old key will
be lost, but at least the node can start again.
Updates #18302
Updates #15830
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Send LOGIN audit messages to the kernel audit subsystem on Linux
when users successfully authenticate to Tailscale SSH. This provides
administrators with audit trail integration via auditd or journald,
recording details about both the Tailscale user (whois) and the
mapped local user account.
The implementation uses raw netlink sockets to send AUDIT_USER_LOGIN
messages to the kernel audit subsystem. It requires CAP_AUDIT_WRITE
capability, which is checked at runtime. If the capability is not
present, audit logging is silently skipped.
Audit messages are sent to the kernel (pid 0) and consumed by either
auditd (written to /var/log/audit/audit.log) or journald (available
via journalctl _TRANSPORT=audit), depending on system configuration.
Note: This may result in duplicate messages on a system where
auditd/journald audit logs are enabled and the system has and supports
`login -h`. Sadly Linux login code paths are still an inconsistent wild
west so we accept the potential duplication rather than trying to avoid
it.
Fixes#18332
Signed-off-by: James Tucker <james@tailscale.com>
GCP Certificate Manager requires an email contact on ACME accounts.
Add --acme-email flag that is required for --certmode=gcp and
optional for --certmode=letsencrypt.
Fixes#18277
Signed-off-by: Raj Singh <raj@tailscale.com>
An error returned by net.Listener.Accept() causes the owning http.Server to shut down.
With the deprecation of net.Error.Temporary(), there's no way for the http.Server to test
whether the returned error is temporary / retryable or not (see golang/go#66252).
Because of that, errors returned by (*safesocket.winIOPipeListener).Accept() cause the LocalAPI
server (aka ipnserver.Server) to shut down, and tailscaled process to exit.
While this might be acceptable in the case of non-recoverable errors, such as programmer errors,
we shouldn't shut down the entire tailscaled process for client- or connection-specific errors,
such as when we couldn't obtain the client's access token because the client attempts to connect
at the Anonymous impersonation level. Instead, the LocalAPI server should gracefully handle
these errors by denying access and returning a 401 Unauthorized to the client.
In tailscale/tscert#15, we fixed a known bug where Caddy and other apps using tscert would attempt
to connect at the Anonymous impersonation level and fail. However, we should also fix this on the tailscaled
side to prevent a potential DoS, where a local app could deliberately open the Tailscale LocalAPI named pipe
at the Anonymous impersonation level and cause tailscaled to exit.
In this PR, we defer token retrieval until (*WindowsClientConn).Token() is called and propagate the returned token
or error via ipnauth.GetConnIdentity() to ipnserver, which handles it the same way as other ipnauth-related errors.
Fixes#18212Fixestailscale/tscert#13
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This gauge will be reworked to include endpoint state in future.
Updates tailscale/corp#30820
Change-Id: I66f349d89422b46eec4ecbaf1a99ad656c7301f9
Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
In dynamically changing environments where ACME account keys and certs
are stored separately, it can happen that the account key would get
deleted (and recreated) between issuances. If that is the case,
we currently fail renewals and the only way to recover is for users
to delete certs.
This adds a config knob to allow opting out of the replaces extension
and utilizes it in the Kubernetes operator where there are known
user workflows that could end up with this edge case.
Updates #18251
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Adding both user and client metrics for peer relay forwarded bytes and
packets, and the total endpoints gauge.
User metrics:
tailscaled_peer_relay_forwarded_packets_total{transport_in, transport_out}
tailscaled_peer_relay_forwarded_bytes_total{transport_in, transport_out}
tailscaled_peer_relay_endpoints_total{}
Where the transport labels can be of "udp4" or "udp6".
Client metrics:
udprelay_forwarded_(packets|bytes)_udp(4|6)_udp(4|6)
udprelay_endpoints
RELNOTE: Expose tailscaled metrics for peer relay.
Updates tailscale/corp#30820
Change-Id: I1a905d15bdc5ee84e28017e0b93210e2d9660259
Signed-off-by: Alex Valiushko <alexvaliushko@tailscale.com>
Adds support for targeting FQDNs that are a Tailscale Service. Uses the
same method of searching for Services as the tailscale configure
kubeconfig command. This fixes using the tailscale.com/tailnet-fqdn
annotation for Kubernetes Service when the specified FQDN is a Tailscale
Service.
Fixes#16534
Change-Id: I422795de76dc83ae30e7e757bc4fbd8eec21cc64
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Signed-off-by: Becky Pauley <becky@tailscale.com>
IsZero is required by the interface, so we should use that before trying
to serialize the key.
Updates #35412
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
When the TS_DEBUG_DNS_FORWARD_SEND envknob is turned on, also log the
source IP:port of the query that tailscaled is forwarding.
Updates tailscale/corp#35374
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
updates tailscale/corp#33891
Addresses several older the TODO's in netmon. This removes the
Major flag precomputes the ChangeDelta state, rather than making
consumers of ChangeDeltas sort that out themselves. We're also seeing
a lot of ChangeDelta's being flagged as "Major" when they are
not interesting, triggering rebinds in wgengine that are not needed. This
cleans that up and adds a host of additional tests.
The dependencies are cleaned, notably removing dependency on netmon
itself for calculating what is interesting, and what is not. This includes letting
individual platforms set a bespoke global "IsInterestingInterface"
function. This is only used on Darwin.
RebindRequired now roughly follows how "Major" was historically
calculated but includes some additional checks for various
uninteresting events such as changes in interface addresses that
shouldn't trigger a rebind. This significantly reduces thrashing (by
roughly half on Darwin clients which switching between nics). The individual
values that we roll into RebindRequired are also exposed so that
components consuming netmap.ChangeDelta can ask more
targeted questions.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
The existing client metric methods only support incrementing (or
decrementing) a delta value. This new method allows setting the metric
to a specific value.
Updates tailscale/corp#35327
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
This commit also introduces a sync.Mutex for guarding mutatable fields
on serverEndpoint, now that it is no longer guarded by the sync.Mutex
in Server.
These changes reduce lock contention and by effect increase aggregate
throughput under high flow count load. A benchmark on Linux with AWS
c8gn instances showed a ~30% increase in aggregate throughput (37Gb/s
vs 28Gb/s) for 12 tailscaled flows.
Updates tailscale/corp#35264
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Add flags:
* --cigocached-host to support alternative host resolution in other
environments, like the corp repo.
* --stats to reduce the amount of bash script we need.
* --version to support a caching tool/cigocacher script that will
download from GitHub releases.
Updates tailscale/corp#10808
Change-Id: Ib2447bc5f79058669a70f2c49cef6aedd7afc049
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
tcpHandlerForVIPService was missing ProxyProtocol support that
tcpHandlerForServe already had. Extract the shared logic into
forwardTCPWithProxyProtocol helper and use it in both handlers.
Fixes#18172
Signed-off-by: Raj Singh <raj@tailscale.com>
Add metrics about logtail uploading and underlying buffer.
Add metrics to the in-memory buffer implementation.
Updates tailscale/corp#21363
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
PR #18033 skipped tests for the versions of Linux 6.6 and 6.12 that
had a regression in /proc/net/tcp that causes seek operations to fail
with “illegal seek”.
This PR skips tests for Linux 6.14.0, which is the default Ubuntu
kernel, that also contains this regression.
Updates #16966
Signed-off-by: Simon Law <sfllaw@tailscale.com>
The filch implementation is fairly broken:
* When Filch.cur exceeds MaxFileSize, it calls moveContents
to copy the entirety of cur into alt (while holding the write lock).
By nature, this is the movement of a lot of data in a hot path,
meaning that all log calls will be globally blocked!
It also means that log uploads will be blocked during the move.
* The implementation of moveContents is buggy in that
it copies data from cur into the start of alt,
but fails to truncate alt to the number of bytes copied.
Consequently, there are unrelated lines near the end,
leading to out-of-order lines when being read back.
* Data filched via stderr do not directly respect MaxFileSize,
which is only checked every 100 Filch.Write calls.
This means that it is possible that the file grows far beyond
the specified max file size before moveContents is called.
* If both log files have data when New is called,
it also copies the entirety of cur into alt.
This can block the startup of a process copying lots of data
before the process can do any useful work.
* TryReadLine is implemented using bufio.Scanner.
Unfortunately, it will choke on any lines longer than
bufio.MaxScanTokenSize, rather than gracefully skip over them.
The re-implementation avoids a lot of these problems
by fundamentally eliminating the need for moveContent.
We enforce MaxFileSize by simply rotating the log files
whenever the current file exceeds MaxFileSize/2.
This is a constant-time operation regardless of file size.
To more gracefully handle lines longer than bufio.MaxScanTokenSize,
we skip over these lines (without growing the read buffer)
and report an error. This allows subsequent lines to be read.
In order to improve debugging, we add a lot of metrics.
Note that the the mechanism of dup2 with stderr
is inherently racy with a the two file approach.
The order of operations during a rotation is carefully chosen
to reduce the race window to be as short as possible.
Thus, this is slightly less racy than before.
Updates tailscale/corp#21363
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
When receiving a TSMPDiscoAdvertisement from peer, update the discokey
for said peer.
Some parts taken from: https://github.com/tailscale/tailscale/pull/18073/
Updates #12639
Co-authored-by: James Tucker <james@tailscale.com>
Re-instate the linking of iptables installed in Tailscale container
to the legacy iptables version. In environments where the legacy
iptables is not needed, we should be able to run nftables instead,
but this will ensure that Tailscale keeps working in environments
that don't support nftables, such as some Synology NAS hosts.
Updates #17854
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Add --certmode=gcp for using Google Cloud Certificate Manager's
public CA instead of Let's Encrypt. GCP requires External Account
Binding (EAB) credentials for ACME registration, so this adds
--acme-eab-kid and --acme-eab-key flags.
The EAB key accepts both base64url and standard base64 encoding
to support both ACME spec format and gcloud output.
Fixestailscale/corp#34881
Signed-off-by: Raj Singh <raj@tailscale.com>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When using the resolve.conf file for setting DNS, it is possible that
some other services will trample the file and overwrite our set DNS
server. Experiments has shown this to be a racy error depending on how
quickly processes start.
Make an attempt to trample back the file a limited number of times if
the file is changed.
Updates #16635
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
When peers request an IP address mapping to be stored, the connector
stores it in memory.
Fixestailscale/corp#34251
Signed-off-by: Fran Bull <fran@tailscale.com>
To save rebuilding cigocacher on each CI job, build it on-demand, and
publish a release similar to how we publish releases for tool/go to
consume. Once the first release is done, we can add a new
tool/cigocacher script that pins to a specific release for each branch
to download.
Updates tailscale/corp#10808
Change-Id: I7694b2c2240020ba2335eb467522cdd029469b6c
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
It appears (*controlclient.Auto).Shutdown() can still deadlock when called with b.mu held, and therefore the changes in #18127 are unsafe.
This reverts #18127 until we figure out what causes it.
This reverts commit d199ecac80.
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This improves our test coverage of the Bootstrap() method, especially
around catching AUMs that shouldn't pass validation.
Updates #cleanup
Change-Id: Idc61fcbc6daaa98c36d20ec61e45ce48771b85de
Signed-off-by: Alex Chan <alexc@tailscale.com>
Previously, if users attempted to expose a headless Service to tailnet,
this just silently did not work.
This PR makes the operator throw a warning event + update Service's
status with an error message.
Updates #18139
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The event queue gets deleted events, which means that sometimes
the object that should be reconciled no longer exists.
Don't log user facing errors if that is the case.
Updates #18141
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The service was starting after systemd itself, and while this
surprisingly worked for some situations, it broke for others.
Change it to start after a GUI has been initialized.
Updates #17656
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Previously we only set this when it updated, which was fine for the first
call to Start(), but after that point future updates would be skipped if
nothing had changed. If Start() was called again, it would wipe the peer API
endpoints and they wouldn't get added back again, breaking exit nodes (and
anything else requiring peer API to be advertised).
Updates tailscale/corp#27173
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
Based on PR #16700 by @lox, adapted to current codebase.
Adds support for proxying HTTP requests to Unix domain sockets via
tailscale serve unix:/path/to/socket, enabling exposure of services
like Docker, containerd, PHP-FPM over Tailscale without TCP bridging.
The implementation includes reasonable protections against exposure of
tailscaled's own socket.
Adaptations from original PR:
- Use net.Dialer.DialContext instead of net.Dial for context propagation
- Use http.Transport with Protocols API (current h2c approach, not http2.Transport)
- Resolve conflicts with hasScheme variable in ExpandProxyTargetValue
Updates #9771
Signed-off-by: Peter A. <ink.splatters@pm.me>
Co-authored-by: Lachlan Donald <lachlan@ljd.cc>
If a packet arrives while WireGuard is being reconfigured with b.mu held, such as during a profile switch,
calling back into (*LocalBackend).GetPeerAPIPort from (*Wrapper).filterPacketInboundFromWireGuard
may deadlock when it tries to acquire b.mu.
This occurs because a peer cannot be removed while an inbound packet is being processed.
The reconfig and profile switch wait for (*Peer).RoutineSequentialReceiver to return, but it never finishes
because GetPeerAPIPort needs b.mu, which the waiting goroutine already holds.
In this PR, we make peerAPIPorts a new syncs.AtomicValue field that is written with b.mu held
but can be read by GetPeerAPIPort without holding the mutex, which fixes the deadlock.
There might be other long-term ways to address the issue, such as moving peer API listeners
from LocalBackend to nodeBackend so they can be accessed without holding b.mu,
but these changes are too large and risky at this stage in the v1.92 release cycle.
Updates #18124
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Previously, callers of (*LocalBackend).resetControlClientLocked were supposed
to call Shutdown on the returned controlclient.Client after releasing b.mu.
In #17804, we started calling Shutdown while holding b.mu, which caused
deadlocks during profile switches due to the (*ExecQueue).RunSync implementation.
We first patched this in #18053 by calling Shutdown in a new goroutine,
which avoided the deadlocks but made TestStateMachine flaky because
the shutdown order was no longer guaranteed.
In #18070, we updated (*ExecQueue).RunSync to allow shutting down
the queue without waiting for RunSync to return. With that change,
shutting down the control client while holding b.mu became safe.
Therefore, this PR updates (*LocalBackend).resetControlClientLocked
to shut down the old client synchronously during the reset, instead of
returning it and shifting that responsibility to the callers.
This fixes the flaky tests and simplifies the code.
Fixes#18052
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit uses SO_REUSEPORT (when supported) to bind multiple sockets
per address family. Increasing the number of sockets can increase
aggregate throughput when serving many peer relay client flows.
Benchmarks show 3x improvement in max aggregate bitrate in some
environments.
Updates tailscale/corp#34745
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Add support for pinning specific Tailscale versions during installation
via the TAILSCALE_VERSION environment variable.
Example usage:
curl -fsSL https://tailscale.com/install.sh | TAILSCALE_VERSION=1.88.4 sh
Fixes#17776
Signed-off-by: Raj Singh <raj@tailscale.com>
111 is 3 years old, and there have been a lot of speed improvements
since then. We run wasm-opt twice as part of the CI wasm job, and it
currently takes about 3 minutes each time. With 125, it takes ~40
seconds, a 4.5x speed-up.
Updates #cleanup
Change-Id: I671ae6cefa3997a23cdcab6871896b6b03e83a4f
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Implements a new disk put function for cigocacher that does not cause
locking issues on Windows when there are multiple processes reading and
writing the same files concurrently. Integrates cigocacher into test.yml
for Windows where we are running on larger runners that support
connecting to private Azure vnet resources where cigocached is hosted.
Updates tailscale/corp#10808
Change-Id: I0d0e9b670e49e0f9abf01ff3d605cd660dd85ebb
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
The cache artifacts from a full run of test.yml are 14GB. Only save
artifacts from the main branch to ensure we don't thrash too much. Most
branches should get decent performance with a hit from recent main.
Fixestailscale/corp#34739
Change-Id: Ia83269d878e4781e3ddf33f1db2f21d06ea2130f
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Thanks to seamless key renewal, you can now do a force-reauth without
losing your connection in all circumstances. We softened the interactive
warning (see #17262) so let's soften the help text as well.
Updates https://github.com/tailscale/corp/issues/32429
Signed-off-by: Alex Chan <alexc@tailscale.com>
* cmd/k8s-operator: add support for taiscale.com/http-redirect
The k8s-operator now supports a tailscale.com/http-redirect annotation
on Ingress resources. When enabled, this automatically creates port 80
handlers that automatically redirect to the equivalent HTTPS location.
Fixes#11252
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
* Fix for permanent redirect
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
* lint
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
* warn for redirect+endpoint
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
* tests
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
---------
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
Restrict running the golangci-lint workflow to when the workflow file
itself or a .go file, go.mod, or go.sum have actually been modified.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Skip the "request review" workflows for PRs that are in draft to reduce
noise / skip adding reviewers to PRs that are intentionally marked as
not ready to review.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Adds an observation point that may identify potentially abusive traffic
patterns at outlier values.
Updates tailscale/corp#24681
Signed-off-by: James Tucker <james@tailscale.com>
We don't hold q.mu while running normal ExecQueue.Add funcs, so we
shouldn't in RunSync either. Otherwise code it calls can't shut down
the queue, as seen in #18502.
Updates #18052
Co-authored-by: Nick Khyl <nickk@tailscale.com>
Change-Id: Ic5e53440411eca5e9fabac7f4a68a9f6ef026de1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This patch adds an integration test for Tailnet Lock, checking that a node can't
talk to peers in the tailnet until it becomes signed.
This patch also introduces a new package `tstest/tkatest`, which has some helpers
for constructing a mock control server that responds to TKA requests. This allows
us to reduce boilerplate in the IPN tests.
Updates tailscale/corp#33599
Signed-off-by: Alex Chan <alexc@tailscale.com>
In preparation for exposing its configuration via ipn.ConfigVAlpha,
change {Masked}Prefs.RelayServerPort from *int to *uint16. This takes a
defensive stance against invalid inputs at JSON decode time.
'tailscale set --relay-server-port' is currently the only input to this
pref, and has always sanitized input to fit within a uint16.
Updates tailscale/corp#34591
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Adds a new types of TSMP messages for advertising disco keys keys
to/from a peer, and implements the advertising triggered by a TSMP ping.
Needed as part of the effort to cache the netmap and still let clients
connect without control being reachable.
Updates #12639
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Co-authored-by: James Tucker <james@tailscale.com>
In suggestExitNodeLocked, if no exit node candidates have a home DERP or
valid location info, `bestCandidates` is an empty slice. This slice is
passed to `selectNode` (`randomNode` in prod):
```go func randomNode(nodes views.Slice[tailcfg.NodeView], …) tailcfg.NodeView {
…
return nodes.At(rand.IntN(nodes.Len()))
}
```
An empty slice becomes a call to `rand.IntN(0)`, which panics.
This patch changes the behaviour, so if we've filtered out all the
candidates before calling `selectNode`, reset the list and then pick
from any of the available candidates.
This patch also updates our tests to give us more coverage of `randomNode`,
so we can spot other potential issues.
Updates #17661
Change-Id: I63eb5e4494d45a1df5b1f4b1b5c6d5576322aa72
Signed-off-by: Alex Chan <alexc@tailscale.com>
And fix up the TestAutoUpdateDefaults integration tests as they
weren't testing reality: the DefaultAutoUpdate is supposed to only be
relevant on the first MapResponse in the stream, but the tests weren't
testing that. They were instead injecting a 2nd+ MapResponse.
This changes the test control server to add a hook to modify the first
map response, and then makes the test control when the node goes up
and down to make new map responses.
Also, the test now runs on macOS where the auto-update feature being
disabled would've previously t.Skipped the whole test.
Updates #11502
Change-Id: If2319bd1f71e108b57d79fe500b2acedbc76e1a6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In PR tailscale/corp#34401, the `traffic-steering` feature flag does
not automatically enable traffic steering for all nodes. Instead, an
admin must add the `traffic-steering` node attribute to each client
node that they want opted-in.
For backwards compatibility with older clients, tailscale/corp#34401
strips out the `traffic-steering` node attribute if the feature flag
is not enabled, even if it is set in the policy file. This lets us
safely disable the feature flag.
This PR adds a missing test case for suggested exit nodes that have no
priority.
Updates tailscale/corp#34399
Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit fixes a bug in our HA ingress reconciler where ingress resources would
be stuck in a deleting state should their associated VIP service be deleted within
control.
The reconciliation loop would check for the existence of the VIP service and if not
found perform no additional cleanup steps. The code has been modified to continue
onwards even if the VIP service is not found.
Fixes: https://github.com/tailscale/tailscale/issues/18049
Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit replaces crypto/rand challenge generation with a blake2s-256
MAC. This enables the peer relay server to respond to multiple forward
disco.BindUDPRelayEndpoint messages per handshake generation without
sacrificing the proof of IP ownership properties of the handshake.
Responding to multiple forward disco.BindUDPRelayEndpoint messages per
handshake generation improves client address/path selection where
lowest client->server path/addr one-way delay does not necessarily
equate to lowest client<->server round trip delay.
It also improves situations where outbound traffic is filtered
independent of input, and the first reply
disco.BindUDPRelayEndpointChallenge message is dropped on the reply
path, but a later reply using a different source would make it through.
Reduction in serverEndpoint state saves 112 bytes per instance, trading
for slightly more expensive crypto ops: 277ns/op vs 321ns/op on an M1
Macbook Pro.
Updates tailscale/corp#34414
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Adds cmd/cigocacher as the client to cigocached for Go caching over
HTTP. The HTTP cache is best-effort only, and builds will fall back to
disk-only cache if it's not available, much like regular builds.
Not yet used in CI; that will follow in another PR once we have runners
available in this repo with the right network setup for reaching
cigocached.
Updates tailscale/corp#10808
Change-Id: I13ae1a12450eb2a05bd9843f358474243989e967
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
When the underlying transport returns a network error, the RoundTrip
method returns (nil, error). The defer was attempting to access resp
without checking if it was nil first, causing a panic. Fix this by
checking for nil in the defer.
Also changes driveTransport.tr from *http.Transport to http.RoundTripper
and adds a test.
Fixes#17306
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
Change-Id: Icf38a020b45aaa9cfbc1415d55fd8b70b978f54c
SetSubnetRoutes was not sending update notifications to nodes when their
approved routes changed, causing nodes to not fetch updated netmaps with
PrimaryRoutes populated. This resulted in TestUserMetricsRouteGauges
flaking because it waited for PrimaryRoutes to be set, which only happened
if the node happened to poll for other reasons.
Now send updateSelfChanged notification to affected nodes so they fetch
an updated netmap immediately.
Fixes#17962
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
Linux kernel versions 6.6.102-104 and 6.12.42-45 have a regression
in /proc/net/tcp that causes seek operations to fail with "illegal seek".
This breaks portlist tests on these kernels.
Add kernel version detection for Linux systems and a SkipOnKernelVersions
helper to tstest. Use it to skip affected portlist tests on the broken
kernel versions.
Thanks to philiptaron for the list of kernels with the issue and fix.
Updates #16966
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
Bounded DeliveredEvent queues reduce memory usage, but they can deadlock under load.
Two common scenarios trigger deadlocks when the number of events published in a short
period exceeds twice the queue capacity (there's a PublishedEvent queue of the same size):
- a subscriber tries to acquire the same mutex as held by a publisher, or
- a subscriber for A events publishes B events
Avoiding these scenarios is not practical and would limit eventbus usefulness and reduce its adoption,
pushing us back to callbacks and other legacy mechanisms. These deadlocks already occurred in customer
devices, dev machines, and tests. They also make it harder to identify and fix slow subscribers and similar
issues we have been seeing recently.
Choosing an arbitrary large fixed queue capacity would only mask the problem. A client running
on a sufficiently large and complex customer environment can exceed any meaningful constant limit,
since event volume depends on the number of peers and other factors. Behavior also changes
based on scheduling of publishers and subscribers by the Go runtime, OS, and hardware, as the issue
is essentially a race between publishers and subscribers. Additionally, on lower-end devices,
an unreasonably high constant capacity is practically the same as using unbounded queues.
Therefore, this PR changes the event queue implementation to be unbounded by default.
The PublishedEvent queue keeps its existing capacity of 16 items, while subscribers'
DeliveredEvent queues become unbounded.
This change fixes known deadlocks and makes the system stable under load,
at the cost of higher potential memory usage, including cases where a queue grows
during an event burst and does not shrink when load decreases.
Further improvements can be implemented in the future as needed.
Fixes#17973Fixes#18012
Signed-off-by: Nick Khyl <nickk@tailscale.com>
As of 2025-11-20, publishing more events than the eventbus's
internal queues can hold may deadlock if a subscriber tries
to publish events itself.
This commit adds a test that demonstrates this deadlock,
and skips it until the bug is fixed.
Updates #18012
Signed-off-by: Nick Khyl <nickk@tailscale.com>
As of 2025-11-20, publishing more events than the eventbus's
internal queues can hold may deadlock if a subscriber tries
to acquire a mutex that can also be held by a publisher.
This commit adds a test that demonstrates this deadlock,
and skips it until the bug is fixed.
Updates #17973
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This is causing confusing panics in tailscale/corp#34485. We'll keep
using the tka.ChonkMem constructor as much as we can, but don't panic
if you create a tka.Mem directly -- we know what the sensible thing is.
Updates #cleanup
Signed-off-by: Alex Chan <alexc@tailscale.com>
Change-Id: I49309f5f403fc26ce4f9a6cf0edc8eddf6a6f3a4
With the introduction of node sealing, store.New fails in some cases due
to the TPM device being reset or unavailable. Currently it results in
tailscaled crashing at startup, which is not obvious to the user until
they check the logs.
Instead of crashing tailscaled at startup, start with an in-memory store
with a health warning about state initialization and a link to (future)
docs on what to do. When this health message is set, also block any
login attempts to avoid masking the problem with an ephemeral node
registration.
Updates #15830
Updates #17654
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
These validations were previously performed in the CLI frontend. There
are two motivations for moving these to the local backend:
1. The backend controls synchronization around the relevant state, so
only the backend can guarantee many of these validations.
2. Doing these validations in the back-end avoids the need to repeat
them across every frontend (e.g. the CLI and tsnet).
Updates tailscale/corp#27200
Signed-off-by: Harry Harpham <harry@tailscale.com>
This commit adds the `spec.replicas` field to the `Recorder` custom
resource that allows for a highly available deployment of `tsrecorder`
within a kubernetes cluster.
Many changes were required here as the code hard-coded the assumption
of a single replica. This has required a few loops, similar to what we
do for the `Connector` resource to create auth and state secrets. It
was also required to add a check to remove dangling state and auth
secrets should the recorder be scaled down.
Updates: https://github.com/tailscale/tailscale/issues/17965
Signed-off-by: David Bond <davidsbond93@gmail.com>
fixestailscale/tailscale#17990
The logging for the netns caps is spammy. Log only on changes
to the values and don't log Darwin specific stuff on non Darwin
clients.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit modifies the kubernetes operator to use the "stable" version
of `k8s-nameserver` by default.
Updates: https://github.com/tailscale/corp/issues/19028
Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit enables user to set service backend to remote destinations, that can be a partial
URL or a full URL. The commit also prevents user to set remote destinations on linux system
when socket mark is not working. For user on any version of mac extension they can't serve a
service either. The socket mark usability is determined by a new local api.
Fixestailscale/corp#24783
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
Now that we support using an in-memory backend for TKA state (#17946),
this function always returns `nil` – we can always support Network Lock.
We don't need it any more.
Plus, clean up a couple of errant TODOs from that PR.
Updates tailscale/corp#33599
Change-Id: Ief93bb9adebb82b9ad1b3e406d1ae9d2fa234877
Signed-off-by: Alex Chan <alexc@tailscale.com>
Our style guide recommends avoiding Latin abbreviations in technical
documentation, which includes the CLI help text. This is causing linter
issues for the docs site, because this help text is copied into the docs.
See http://go/style-guide/kb/language-and-grammar/abbreviations#latin-abbreviations
Updates #cleanup
Change-Id: I980c28d996466f0503aaaa65127685f4af608039
Signed-off-by: Alex Chan <alexc@tailscale.com>
ArgoCD sends boolean values but the template expects strings, causing
"incompatible types for comparison" errors. Wrap values with toString
so both work.
Fixes#17158
Signed-off-by: Raj Singh <raj@tailscale.com>
Previously a TKA compaction would only run when a node starts, which means a long-running node could use unbounded storage as it accumulates ever-increasing amounts of TKA state. This patch changes TKA so it runs a compaction after every sync.
Updates https://github.com/tailscale/corp/issues/33537
Change-Id: I91df887ea0c5a5b00cb6caced85aeffa2a4b24ee
Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit modifies the helm/static manifest configuration for the
k8s-operator to prefer the stable image tag. This avoids making those
using static manifests seeing unstable behaviour by default if they
do not manually make the change.
This is managed for us when using helm but not when generating the
static manifests.
Updates https://github.com/tailscale/tailscale/issues/10655
Signed-off-by: David Bond <davidsbond93@gmail.com>
(trying to get in smaller obvious chunks ahead of later PRs to make
them smaller)
Updates #17925
Change-Id: I184002001055790484e4792af8ffe2a9a2465b2e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We now embed node information into network flow logs.
By default, netlogfmt still prints out using Tailscale IP addresses.
Support a "--resolve-addrs=TYPE" flag that can be used to specify
resolving IP addresses as node IDs, hostnames, users, or tags.
Updates tailscale/corp#33352
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Adds the ability to rotate discovery keys on running clients, needed for
testing upcoming disco key distribution changes.
Introduces key.DiscoKey, an atomic container for a disco private key,
public key, and the public key's ShortString, replacing the prior
separate atomic fields.
magicsock.Conn has a new RotateDiscoKey method, and access to this is
provided via localapi and a CLI debug command.
Note that this implementation is primarily for testing as it stands, and
regular use should likely introduce an additional mechanism that allows
the old key to be used for some time, to provide a seamless key rotation
rather than one that invalidates all sessions.
Updates tailscale/corp#34037
Signed-off-by: James Tucker <james@tailscale.com>
As part of the conn25 work we will want to be able to keep track of a
pool of IP Addresses and know which have been used and which have not.
Fixestailscale/corp#34247
Signed-off-by: Fran Bull <fran@tailscale.com>
We use `tka.AUMHash` in `netmap.NetworkMap`, and we serialise it as JSON
in the `/debug/netmap` C2N endpoint. If the binary omits Tailnet Lock support,
the debug endpoint returns an error because it's unable to marshal the
AUMHash.
This patch adds a sentinel value so this marshalling works, and we can
use the debug endpoint.
Updates https://github.com/tailscale/tailscale/issues/17115
Signed-off-by: Alex Chan <alexc@tailscale.com>
Change-Id: I51ec1491a74e9b9f49d1766abd89681049e09ce4
Existing compaction logic seems to have had an assumption that
markActiveChain would cover a longer part of the chain than
markYoungAUMs. This prevented long, but fresh, chains, from being
compacted correctly.
Updates tailscale/corp#33537
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
6a73c0bdf5 added a feature tag but didn't re-run go generate on ./feature/buildfeatures.
Updates #9192
Change-Id: I7819450453e6b34c60cad29d2273e3e118291643
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I added a RemoveAll() method on tka.Chonk in #17946, but it's only used
in the node to purge local AUMs. We don't need it in the SQLite storage,
which currently implements tka.Chonk, so move it to CompactableChonk
instead.
Also add some automated tests, as a safety net.
Updates tailscale/corp#33599
Change-Id: I54de9ccf1d6a3d29b36a94eccb0ebd235acd4ebc
Signed-off-by: Alex Chan <alexc@tailscale.com>
The REST API does not return a node name
with a trailing dot, while the internal node name
reported in the netmap does have one.
In order to be consistent with the API,
strip the dot when recording node information.
Updates tailscale/corp#33352
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Perform a path check first before attempting exec of `true`.
Try /usr/bin/true first, as that is now and increasingly so, the more
common and more portable path.
Fixes tests on macOS arm64 where exec was returning a different kind of
path error than previously checked.
Updates #16569
Signed-off-by: James Tucker <james@tailscale.com>
DA protection is not super helpful because we don't set an authorization
password on the key. But if authorization fails for other reasons (like
TPM being reset), we will eventually cause DA lockout with tailscaled
trying to load the key. DA lockout then leads to (1) issues for other
processes using the TPM and (2) the underlying authorization error being
masked in logs.
Updates #17654
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
For manual (human) testing, this lets the user disable control plane
map polls with "tailscale set --sync=false" (which survives restarts)
and "tailscale set --sync" to restore.
A high severity health warning is shown while this is active.
Updates #12639
Updates #17945
Change-Id: I83668fa5de3b5e5e25444df0815ec2a859153a6d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Let's fix all the typos, which lets the code be more readable, lest we
confuse our readers.
Updates #cleanup
Change-Id: I4954601b0592b1fda40269009647bb517a4457be
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This requires making the internals of LocalBackend a bit more generic,
and implementing the `tka.CompactableChonk` interface for `tka.Mem`.
Signed-off-by: Alex Chan <alexc@tailscale.com>
Updates https://github.com/tailscale/corp/issues/33599
Pick up a fix for https://pkg.go.dev/vuln/GO-2025-4116 (even though
we're not affected).
Updates #cleanup
Change-Id: I9f2571b17c1f14db58ece8a5a34785805217d9dd
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Includes adding StartPaused, which will be used in a future change to
enable netmap caching testing.
Updates #12639
Change-Id: Iec39915d33b8d75e9b8315b281b1af2f5d13a44a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This patch changes the behaviour of `tailscale lock log --json` to make
it more useful for users. It also introduces versioning of our JSON output.
## Changes to `tailscale lock log --json`
Previously this command would print the hash and base64-encoded bytes of
each AUM, and users would need their own CBOR decoder to interpret it in
a useful way:
```json
[
{
"Hash": [
80,
136,
151,
…
],
"Change": "checkpoint",
"Raw": "pAEFAvYFpQH2AopYIAkPN+8V3cJpkoC5ZY2+RI2Bcg2q5G7tRAQQd67W3YpnWCDPOo4KGeQBd8hdGsjoEQpSXyiPdlm+NXAlJ5dS1qEbFlggylNJDQM5ZQ2ULNsXxg2ZBFkPl/D93I1M56/rowU+UIlYIPZ/SxT9EA2Idy9kaCbsFzjX/s3Ms7584wWGbWd/f/QAWCBHYZzYiAPpQ+NXN+1Wn2fopQYk4yl7kNQcMXUKNAdt1lggcfjcuVACOH0J9pRNvYZQFOkbiBmLOW1hPKJsbC1D1GdYIKrJ38XMgpVMuTuBxM4YwoLmrK/RgXQw1uVEL3cywl3QWCA0FilVVv8uys8BNhS62cfNvCew1Pw5wIgSe3Prv8d8pFggQrwIt6ldYtyFPQcC5V18qrCnt7VpThACaz5RYzpx7RNYIKskOA7UoNiVtMkOrV2QoXv6EvDpbO26a01lVeh8UCeEA4KjAQECAQNYIORIdNHqSOzz1trIygnP5w3JWK2DtlY5NDIBbD7SKcjWowEBAgEDWCD27LpxiZNiA19k0QZhOWmJRvBdK2mz+dHu7rf0iGTPFwQb69Gt42fKNn0FGwRUiav/k6dDF4GiAVgg5Eh00epI7PPW2sjKCc/nDclYrYO2Vjk0MgFsPtIpyNYCWEDzIAooc+m45ay5PB/OB4AA9Fdki4KJq9Ll+PF6IJHYlOVhpTbc3E0KF7ODu1WURd0f7PXnW72dr89CSfGxIHAF"
}
]
```
Now we print the AUM in an expanded form that can be easily read by scripts,
although we include the raw bytes for verification and auditing.
```json
{
"SchemaVersion": "1",
"Messages": [
{
"Hash": "KCEJPRKNSXJG2TPH3EHQRLJNLIIK2DV53FUNPADWA7BZJWBDRXZQ",
"AUM": {
"MessageKind": "checkpoint",
"PrevAUMHash": null,
"Key": null,
"KeyID": null,
"State": {
…
},
"Votes": null,
"Meta": null,
"Signatures": [
{
"KeyID": "tlpub:e44874d1ea48ecf3d6dac8ca09cfe70dc958ad83b656393432016c3ed229c8d6",
"Signature": "8yAKKHPpuOWsuTwfzgeAAPRXZIuCiavS5fjxeiCR2JTlYaU23NxNChezg7tVlEXdH+z151u9na/PQknxsSBwBQ=="
}
]
},
"Raw": "pAEFAvYFpQH2AopYIAkPN-8V3cJpkoC5ZY2-RI2Bcg2q5G7tRAQQd67W3YpnWCDPOo4KGeQBd8hdGsjoEQpSXyiPdlm-NXAlJ5dS1qEbFlggylNJDQM5ZQ2ULNsXxg2ZBFkPl_D93I1M56_rowU-UIlYIPZ_SxT9EA2Idy9kaCbsFzjX_s3Ms7584wWGbWd_f_QAWCBHYZzYiAPpQ-NXN-1Wn2fopQYk4yl7kNQcMXUKNAdt1lggcfjcuVACOH0J9pRNvYZQFOkbiBmLOW1hPKJsbC1D1GdYIKrJ38XMgpVMuTuBxM4YwoLmrK_RgXQw1uVEL3cywl3QWCA0FilVVv8uys8BNhS62cfNvCew1Pw5wIgSe3Prv8d8pFggQrwIt6ldYtyFPQcC5V18qrCnt7VpThACaz5RYzpx7RNYIKskOA7UoNiVtMkOrV2QoXv6EvDpbO26a01lVeh8UCeEA4KjAQECAQNYIORIdNHqSOzz1trIygnP5w3JWK2DtlY5NDIBbD7SKcjWowEBAgEDWCD27LpxiZNiA19k0QZhOWmJRvBdK2mz-dHu7rf0iGTPFwQb69Gt42fKNn0FGwRUiav_k6dDF4GiAVgg5Eh00epI7PPW2sjKCc_nDclYrYO2Vjk0MgFsPtIpyNYCWEDzIAooc-m45ay5PB_OB4AA9Fdki4KJq9Ll-PF6IJHYlOVhpTbc3E0KF7ODu1WURd0f7PXnW72dr89CSfGxIHAF"
}
]
}
```
This output was previously marked as unstable, and it wasn't very useful,
so changing it should be fine.
## Versioning our JSON output
This patch introduces a way to version our JSON output on the CLI, so we
can make backwards-incompatible changes in future without breaking existing
scripts or integrations.
You can run this command in two ways:
```
tailscale lock log --json
tailscale lock log --json=1
```
Passing an explicit version number allows you to pick a specific JSON schema.
If we ever want to change the schema, we increment the version number and
users must opt-in to the new output.
A bare `--json` flag will always return schema version 1, for compatibility
with existing scripts.
Updates https://github.com/tailscale/tailscale/issues/17613
Updates https://github.com/tailscale/corp/issues/23258
Signed-off-by: Alex Chan <alexc@tailscale.com>
Change-Id: I897f78521cc1a81651f5476228c0882d7b723606
This adds the --proxy-protocol flag to 'tailscale serve' and
'tailscale funnel', which tells the Tailscale client to prepend a PROXY
protocol[1] header when making connections to the proxied-to backend.
I've verified that this works with our existing funnel servers without
additional work, since they pass along source address information via
PeerAPI already.
Updates #7747
[1]: https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
Change-Id: I647c24d319375c1b33e995555a541b7615d2d203
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
It's an unnecessary nuisance having it. We go out of our way to redact
it in so many places when we don't even need it there anyway.
Updates #12639
Change-Id: I5fc72e19e9cf36caeb42cf80ba430873f67167c3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Remove the State enum (StateNew, StateNotAuthenticated, etc.) from
controlclient and replace it with two explicit boolean fields:
- LoginFinished: indicates successful authentication
- Synced: indicates we've received at least one netmap
This makes the state more composable and easier to reason about, as
multiple conditions can be true independently rather than being
encoded in a single enum value.
The State enum was originally intended as the state machine for the
whole client, but that abstraction moved to ipn.Backend long ago.
This change continues moving away from the legacy state machine by
representing state as a combination of independent facts.
Also adds test helpers in ipnlocal that check independent, observable
facts (hasValidNetMap, needsLogin, etc.) rather than relying on
derived state enums, making tests more robust.
Updates #12639
Signed-off-by: James Tucker <james@tailscale.com>
The key.NewEmptyHardwareAttestationKey hook returns a non-nil empty
attestationKey, which means that the nil check in Clone doesn't trigger
and proceeds to try and clone an empty key. Check IsZero instead to
reduce log spam from Clone.
As a drive-by, make tpmAvailable check a sync.Once because the result
won't change.
Updates #17882
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Most /etc/os-release files set the VERSION_ID to a `MAJOR.MINOR`
string, but we were trying to compare this numerically against a major
version number. I can only assume that Linux Mint used switched from a
plain integer, since shells only do integer comparisons.
This patch extracts a VERSION_MAJOR from the VERSION_ID using
parameter expansion and unifies all the other ad-hoc comparisons to
use it.
Fixes#15841
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Co-authored-by: Xavier <xhienne@users.noreply.github.com>
LinkChangeLogLimiter keeps a subscription to track rate limits for log
messages. But when its context ended, it would exit the subscription loop,
leaving the subscriber still alive. Ensure the subscriber gets cleaned up
when the context ends, so we don't stall event processing.
Updates tailscale/corp#34311
Change-Id: I82749e482e9a00dfc47f04afbc69dd0237537cb2
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
On the corp tailnet (using Mullvad exit nodes + bunch of expired
devices + subnet routers), these were generating big ~35 KB blobs of
logging regularly.
This logging shouldn't even exist at this level, and should be rate
limited at a higher level, but for now as a bandaid, make it less
spammy.
Updates #cleanup
Change-Id: I0b5e9e6e859f13df5f982cd71cd5af85b73f0c0a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When TS_LOG_TARGET is set to an invalid URL, url.Parse returns an error
and nil pointer, which caused a panic when accessing u.Host.
Now we check the error from url.Parse and log a helpful message while
falling back to the default log host.
Fixes#17792
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
As a baby step towards eventbus-ifying controlclient, make the
Observer optional.
This also means callers that don't care (like this network lock test,
and some tests in other repos) can omit it, rather than passing in a
no-op one.
Updates #12639
Change-Id: Ibd776b45b4425c08db19405bc3172b238e87da4e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit replaces usage of local.Client in net/udprelay with DERPMap
plumbing over the eventbus. This has been a longstanding TODO. This work
was also accelerated by a memory leak in net/http when using
local.Client over long periods of time. So, this commit also addresses
said leak.
Updates #17801
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Instead of trying to call View() on something that's already a View
type (or trying to Clone the view unnecessarily), we can re-use the
existing View values in a map[T]ViewType.
Fixes#17866
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
They distracted me in some refactoring. They're set but never used.
Updates #17858
Change-Id: I6ec7d6841ab684a55bccca7b7cbf7da9c782694f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
updates tailscale/corp#31571
It appears that on the latest macOS, iOS and tVOS versions, the work
that netns is doing to bind outgoing connections to the default interface (and all
of the trimmings and workarounds in netmon et al that make that work) are
not needed. The kernel is extension-aware and doing nothing, is the right
thing. This is, however, not the case for tailscaled (which is not a
special process).
To allow us to test this assertion (and where it might break things), we add a
new node cap that turns this behaviour off only for network-extension equipped clients,
making it possible to turn this off tailnet-wide, without breaking any tailscaled
macos nodes.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
I noticed a deadlock in a test in a in-development PR where during a
shutdown storm of things (from a tsnet.Server.Close), LocalBackend was
trying to call magicsock.Conn.Synchronize but the magicsock and/or
eventbus was already shut down and no longer processing events.
Updates #16369
Change-Id: I58b1f86c8959303c3fb46e2e3b7f38f6385036f1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Unfortunately I closed the tab and lost it in my sea of CI failures
I'm currently fighting.
Updates #cleanup
Change-Id: I4e3a652d57d52b75238f25d104fc1987add64191
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So they're not all run N times on the sharded oss builders
and are only run one time each.
Updates tailscale/corp#28679
Change-Id: Ie21e84b06731fdc8ec3212eceb136c8fc26b0115
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When systemd notification support was omitted from the build, or on
non-Linux systems, we were unnecessarily emitting code and generating
garbage stringifying addresses upon transition to the Running state.
Updates #12614
Change-Id: If713f47351c7922bb70e9da85bf92725b25954b9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This removes one of the O(n=peers) allocs in getStatus, as
Engine.getStatus happens more often than Reconfig.
Updates #17814
Change-Id: I8a87fbebbecca3aedadba38e46cc418fd163c2b0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously if `chains` was empty, it would be passed to `computeActiveAncestor()`,
which would fail with the misleading error "multiple distinct chains".
Updates tailscale/corp#33846
Signed-off-by: Alex Chan <alexc@tailscale.com>
Change-Id: Ib93a755dbdf4127f81cbf69f3eece5a388db31c8
* lock released early just to call `b.send` when it can call
`b.sendToLocked` instead
* `UnlockEarly` called to release the lock before trivially fast
operations, we can wait for a defer there
Updates #11649
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
It was disabled in May 2024 in #12205 (9eb72bb51).
This removes the unused symbols.
Updates #188
Updates tailscale/corp#19106
Updates tailscale/corp#19116
Change-Id: I5208b7b750b18226ed703532ed58c4ea17195a8e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Use GetGlobalAddrs() to discover all STUN endpoints, handling bad NATs
that create multiple mappings. When MappingVariesByDestIP is true, also
add the first STUN IPv4 address with the relay's local port for static
port mapping scenarios.
Updates #17796
Signed-off-by: Raj Singh <raj@tailscale.com>
The feature is currently in private alpha, so requires a tailnet feature
flag. Initially focuses on supporting the operator's own auth, because the
operator is the only device we maintain that uses static long-lived
credentials. All other operator-created devices use single-use auth keys.
Testing steps:
* Create a cluster with an API server accessible over public internet
* kubectl get --raw /.well-known/openid-configuration | jq '.issuer'
* Create a federated OAuth client in the Tailscale admin console with:
* The issuer from the previous step
* Subject claim `system:serviceaccount:tailscale:operator`
* Write scopes services, devices:core, auth_keys
* Tag tag:k8s-operator
* Allow the Tailscale control plane to get the public portion of
the ServiceAccount token signing key without authentication:
* kubectl create clusterrolebinding oidc-discovery \
--clusterrole=system:service-account-issuer-discovery \
--group=system:unauthenticated
* helm install --set oauth.clientId=... --set oauth.audience=...
Updates #17457
Change-Id: Ib29c85ba97b093c70b002f4f41793ffc02e6c6e9
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Now that the feature is in beta, no one should encounter this error.
Updates #cleanup
Change-Id: I69ed3f460b7f28c44da43ce2f552042f980a0420
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This starts running the jsontags vet checker on the module.
All existing findings are adding to an allowlist.
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The cmd/jsontags is non-idiomatic since it is not a main binary.
Move it to a vet directory, which will eventually contain a vettool binary.
Update tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Include the node's OS with network flow log information.
Refactor the JSON-length computation to be a bit more precise.
Updates tailscale/corp#33352Fixestailscale/corp#34030
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Prior to this change a SubscriberFunc treated the call to the subscriber's
function as the completion of delivery. But that means when we are closing the
subscriber, that callback could continue to execute for some time after the
close returns.
For channel-based subscribers that works OK because the close takes effect
before the subscriber ever sees the event. To make the two subscriber types
symmetric, we should also wait for the callback to finish before returning.
This ensures that a Close of the client means the same thing with both kinds of
subscriber.
Updates #17638
Change-Id: I82fd31bcaa4e92fab07981ac0e57e6e3a7d9d60b
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Add options to the eventbus.Bus to plumb in a logger.
Route that logger in to the subscriber machinery, and trigger a log message to
it when a subscriber fails to respond to its delivered events for 5s or more.
The log message includes the package, filename, and line number of the call
site that created the subscription.
Add tests that verify this works.
Updates #17680
Change-Id: I0546516476b1e13e6a9cf79f19db2fe55e56c698
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
In particular on Windows, the `transport.TPMCloser` we get is not safe
for concurrent use. This is especially noticeable because
`tpm.attestationKey.Clone` uses the same open handle as the original
key. So wrap the operations on ak.tpm with a mutex and make a deep copy
with a new connection in Clone.
Updates #15830
Updates #17662
Updates #17644
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Specify the app apability that failed the test, instead of the
entire comma-separated list.
Fixes #cleanup
Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
In #17639 we moved the subscription into NewLogger to ensure we would not race
subscribing with shutdown of the eventbus client. Doing so fixed that problem,
but exposed another: As we were only servicing events occasionally when waiting
for the network to come up, we could leave the eventbus to stall in cases where
a number of network deltas arrived later and weren't processed.
To address that, let's separate the concerns: As before, we'll Subscribe early
to avoid conflicts with shutdown; but instead of using the subscriber directly
to determine readiness, we'll keep track of the last-known network state in a
selectable condition that the subscriber updates for us. When we want to wait,
we'll wait on that condition (or until our context ends), ensuring all the
events get processed in a timely manner.
Updates #17638
Updates #15160
Change-Id: I28339a372be4ab24be46e2834a218874c33a0d2d
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Adds a new Redirect field to HTTPHandler for serving HTTP redirects
from the Tailscale serve config. The redirect URL supports template
variables ${HOST} and ${REQUEST_URI} that are resolved per request.
By default, it redirects using HTTP Status 302 (Found). For another
redirect status, like 301 - Moved Permanently, pass the HTTP status
code followed by ':' on Redirect, like: "301:https://tailscale.com"
Updates #11252
Updates #11330
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
In 3f5c560fd4 I changed to use std net/http's HTTP/2 support,
instead of pulling in x/net/http2.
But I forgot to update DialTLSContext to DialContext, which meant it
was falling back to using the std net.Dialer for its dials, instead
of the passed-in one.
The tests only passed because they were using localhost addresses, so
the std net.Dialer worked. But in prod, where a tsnet Dialer would be
needed, it didn't work, and would time out for 10 seconds before
resorting to the old protocol.
So this fixes the tests to use an isolated in-memory network to prevent
that class of problem in the future. With the test change, the old code
fails and the new code passes.
Thanks to @jasonodonnell for debugging!
Updates #17304
Updates 3f5c560fd4
Change-Id: I3602bafd07dc6548e2c62985af9ac0afb3a0e967
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Single letter 'l' variables can eventually become confusing when
they're rendered in some fonts that make them similar to 1 or I.
Updates #cleanup
Signed-off-by: Fernando Serboncini <fserb@tailscale.com>
A follow-up to #17411. Put AppConnector events into a task queue, as they may
take some time to process. Ensure that the queue is stopped at shutdown so that
cleanup will remain orderly.
Because events are delivered on a separate goroutine, slow processing of an
event does not cause an immediate problem; however, a subscriber that blocks
for a long time will push back on the bus as a whole. See
https://godoc.org/tailscale.com/util/eventbus#hdr-Expected_subscriber_behavior
for more discussion.
Updates #17192
Updates #15160
Change-Id: Ib313cc68aec273daf2b1ad79538266c81ef063e3
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This migrates an internal tool to open source
so that we can run it on the tailscale.com module as well.
This PR does not yet set up a CI to run this analyzer.
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This rewrites the netlog package to support embedding node information in network flow logs.
Some bit of complexity comes in trying to pre-compute the expected size of the log message
after JSON serialization to ensure that we can respect maximum body limits in log uploading.
We also fix a bug in tstun, where we were recording the IP address after SNAT,
which was resulting in non-sensible connection flows being logged.
Updates tailscale/corp#33352
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This migrates an internal tool to open source
so that we can run it on the tailscale.com module as well.
We add the "util/safediff" also as a dependency of the tool.
This PR does not yet set up a CI to run this analyzer.
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Found by staticcheck, the test was calling derphttp.NewClient but not checking
its error result before doing other things to it.
Updates #cleanup
Change-Id: I4ade35a7de7c473571f176e747866bc0ab5774db
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This reverts commit 4346615d77.
We averted the shutdown race, but will need to service the subscriber even when
we are not waiting for a change so that we do not delay the bus as a whole.
Updates #17638
Change-Id: I5488466ed83f5ad1141c95267f5ae54878a24657
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Drop usage of the branches filter with a single asterisk as this matches
against zero or more characters but not a forward slash, resulting in
PRs to branch names with forwards slashes in them not having these
workflow run against them as expected.
Updates https://github.com/tailscale/corp/issues/33523
Signed-off-by: Mario Minardi <mario@tailscale.com>
Also consolidates variable and header naming and amends the
CLI behavior
* multiple app-caps have to be specified as comma-separated
list
* simple regex-based validation of app capability names is
carried out during flag parsing
Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
Given that we filter based on the usercaps argument now, truncation
should not be necessary anymore.
Updates tailscale/corp/#28372
Signed-off-by: Gesa Stupperich <gesa@tailscale.com>
Temporarily back out the TPM-based hw attestation code while we debug
Windows exceptions.
Updates tailscale/corp#31269
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
When the eventbus is enabled, set up the subscription for change deltas at the
beginning when the client is created, rather than waiting for the first
awaitInternetUp check.
Otherwise, it is possible for a check to race with the client close in
Shutdown, which triggers a panic.
Updates #17638
Change-Id: I461c07939eca46699072b14b1814ecf28eec750c
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This compares the warnings we actually care about and skips the unstable
warnings and the changes with no warnings.
Fixes#17635
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
If you run tailscaled without passing a `--statedir`, Tailnet Lock is
unavailable -- we don't have a folder to store the AUMs in.
This causes a lot of unnecessary requests to bootstrap TKA, because
every time the node receives a NetMap with some TKA state, it tries to
bootstrap, fetches the bootstrap TKA state from the control plane, then
fails with the error:
TKA sync error: bootstrap: network-lock is not supported in this
configuration, try setting --statedir
We can't prevent the error, but we can skip the control plane request
that immediately gets dropped on the floor.
In local testing, a new node joining a tailnet caused *three* control
plane requests which were unused.
Updates tailscale/corp#19441
Signed-off-by: Alex Chan <alexc@tailscale.com>
This fixes a regression from dd615c8fdd that moved the
newIPTablesRunner constructor from a any-Linux-GOARCH file to one that
was only amd64 and arm64, thus breaking iptables on other platforms
(notably 32-bit "arm", as seen on older Pis running Buster with
iptables)
Tested by hand on a Raspberry Pi 2 w/ Buster + iptables for now, for
lack of automated 32-bit arm tests at the moment. But filed #17629.
Fixes#17623
Updates #17629
Change-Id: Iac1a3d78f35d8428821b46f0fed3f3717891c1bd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On some platforms e.g. ChromeOS the owner hierarchy might not always be
available to us. To avoid stale sealing exceptions later we probe to
confirm it's working rather than rely solely on family indicator status.
Updates #17622
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Check that the TPM we have opened is advertised as a 2.0 family device
before using it for state sealing / hardware attestation.
Updates #17622
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
This reformats the existing text to have line breaks at sentences. This
commit contains no textual changes to the code of conduct, but is done
to make any subsequent changes easier to review. (sembr.org)
Also apply prettier formatting for consistency.
Updates #cleanup
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
* When we do the TKA sync, log whether TKA is enabled and whether
we want it to be enabled. This would help us see if a node is
making bootstrap errors.
* When we fail to look up an AUM locally, log the ID of the AUM
rather than a generic "file does not exist" error.
These AUM IDs are cryptographic hashes of the TKA state, which
itself just contains public keys and signatures. These IDs aren't
sensitive and logging them is safe.
Signed-off-by: Alex Chan <alexc@tailscale.com>
Updates https://github.com/tailscale/corp/issues/33594
Service hosts must be tagged nodes, meaning it is only valid to
advertise a Service from a machine which has at least one ACL tag.
Fixestailscale/corp#33197
Signed-off-by: Harry Harpham <harry@tailscale.com>
If users start the application with sudo, DBUS is likely not available
or will not have the correct endpoints. We want to warn users when doing
this.
Closes#17593
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This does not change which subscriptions are made, it only swaps them to use
the SubscribeFunc API instead of Subscribe.
Updates #15160
Updates #17487
Change-Id: Id56027836c96942206200567a118f8bcf9c07f64
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This patch creates a set of tests that should be true for all implementations of Chonk and CompactableChonk, which we can share with the SQLite implementation in corp.
It includes all the existing tests, plus a test for LastActiveAncestor which was in corp but not in oss.
Updates https://github.com/tailscale/corp/issues/33465
Signed-off-by: Alex Chan <alexc@tailscale.com>
Previously, running `tailscale lock log` in a tailnet without Tailnet
Lock enabled would return a potentially confusing error:
$ tailscale lock log
2025/10/20 11:07:09 failed to connect to local Tailscale service; is Tailscale running?
It would return this error even if Tailscale was running.
This patch fixes the error to be:
$ tailscale lock log
Tailnet Lock is not enabled
Fixes#17586
Signed-off-by: Alex Chan <alexc@tailscale.com>
Add new arguments to `tailscale up` so authkeys can be generated dynamically via identity federation.
Updates #9192
Signed-off-by: mcoulombe <max@tailscale.com>
* Remove a couple of single-letter `l` variables
* Use named struct parameters in the test cases for readability
* Delete `wantAfterInactivityForFn` parameter when it returns the
default zero
Updates #cleanup
Signed-off-by: Alex Chan <alexc@tailscale.com>
We soft-delete AUMs when they're purged, but when we call `ChildAUMs()`,
we look up soft-deleted AUMs to find the `Children` field.
This patch changes the behaviour of `ChildAUMs()` so it only looks at
not-deleted AUMs. This means we don't need to record child information
on AUMs any more, which is a minor space saving for any newly-recorded
AUMs.
Updates https://github.com/tailscale/tailscale/issues/17566
Updates https://github.com/tailscale/corp/issues/27166
Signed-off-by: Alex Chan <alexc@tailscale.com>
This method was added in cca25f6 in the initial in-memory implementation
of Chonk, but it's not part of the Chonk interface and isn't implemented
or used anywhere else. Let's get rid of it.
Updates https://github.com/tailscale/corp/issues/33465
Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit modifies the k8s-operator's api proxy implementation to only
enable forwarding of api requests to tsrecorder when an environment
variable is set.
This new environment variable is named `TS_EXPERIMENTAL_KUBE_API_EVENTS`.
Updates https://github.com/tailscale/corp/issues/32448
Signed-off-by: David Bond <davidsbond93@gmail.com>
Merge the connstats package into the netlog package
and unexport all of its declarations.
Remove the buildfeatures.HasConnStats and use HasNetLog instead.
Updates tailscale/corp#33352
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The connstats package was an unnecessary layer of indirection.
It was seperated out of wgengine/netlog so that net/tstun and
wgengine/magicsock wouldn't need a depenedency on the concrete
implementation of network flow logging.
Instead, we simply register a callback for counting connections.
This PR does the bare minimum work to prepare tstun and magicsock
to only care about that callback.
A future PR will delete connstats and merge it into netlog.
Updates tailscale/corp#33352
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Remove CBOR representation since it was never used.
We should support CBOR in the future, but for remove it
for now so that it is less work to add more fields.
Also, rely on just omitzero for JSON now that it is supported in Go 1.24.
Updates tailscale/corp#33352
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
I was debugging a customer issue and saw in their 1.88.3 logs:
TPM: error opening: stat /dev/tpm0: no such file or directory
That's unnecessary output. The lack of TPM will be reported by
them having a nil Hostinfo.TPM, which is plenty elsewhere in logs.
Let's only write out an "error opening" line if it's an interesting
error. (perhaps permissions, or EIO, etc)
Updates #cleanup
Change-Id: I3f987f6bf1d3ada03473ca3eef555e9cfafc7677
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Before synctest, timers was needed to allow the events to flow into the
test bus. There is still a timer, but this one is not derived from the
test deadline and it is mostly arbitrary as synctest will render it
practically non-existent.
With this approach, tests that do not need to test for the absence of
events do not rely on synctest.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
On Windows arm64 we are going to need to ship two different GUI builds;
one for Win10 (GOARCH=386) and one for Win11 (GOARCH=amd64, tags +=
winui). Due to quirks in MSI packaging, they cannot both share the
same filename. This requires some fixes in places where we have
hardcoded "tailscale-ipn" as the GUI filename.
We also do some cleanup in clientupdate to ensure that autoupdates
will continue to work correctly with the temporary "-winui" package
variant.
Fixes#17480
Updates https://github.com/tailscale/corp/issues/29940
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Extend Persist with AttestationKey to record a hardware-backed
attestation key for the node's identity.
Add a flag to tailscaled to allow users to control the use of
hardware-backed keys to bind node identity to individual machines.
Updates tailscale/corp#31269
Change-Id: Idcf40d730a448d85f07f1bebf387f086d4c58be3
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
The default representation of time.Duration has different
JSON representation between v1 and v2.
Apply an explicit format flag that uses the v1 representation
so that this behavior does not change if serialized with v2.
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
updates tailscale/tailscale#16836
Android's altNetInterfaces implementation now returns net.IPAddr
types which netmon wasn't handling.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
With a channel subscriber, the subscription processing always occurs on another
goroutine. The SubscriberFunc (prior to this commit) runs its callbacks on the
client's own goroutine. This changes the semantics, though: In addition to more
directly pushing back on the publisher, a publisher and subscriber can deadlock
in a SubscriberFunc but succeed on a Subscriber. They should behave
equivalently regardless which interface they use.
Arguably the caller should deal with this by creating its own goroutine if it
needs to. However, that loses much of the benefit of the SubscriberFunc API, as
it will need to manage the lifecycle of that goroutine. So, for practical
ergonomics, let's make the SubscriberFunc do this management on the user's
behalf. (We discussed doing this in #17432, but decided not to do it yet). We
can optimize this approach further, if we need to, without changing the API.
Updates #17487
Change-Id: I19ea9e8f246f7b406711f5a16518ef7ff21a1ac9
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit adds the subcommands `get-config` and `set-config` to Serve,
which can be used to read the current Tailscale Services configuration
in a standard syntax and provide a configuration to declaratively apply
with that same syntax.
Both commands must be provided with either `--service=svc:service` for
one service, or `--all` for all services. When writing a config,
`--set-config --all` will overwrite all existing Services configuration,
and `--set-config --service=svc:service` will overwrite all
configuration for that particular Service. Incremental changes are not
supported.
Fixestailscale/corp#30983.
cmd/tailscale/cli: hide serve "get-config"/"set-config" commands for now
tailscale/corp#33152 tracks unhiding them when docs exist.
Signed-off-by: Naman Sood <mail@nsood.in>
when tsrecorder receives events, it populates this field with
information about the node the request was sent to.
Updates #17141
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
The lazy init led to confusion and a belief that was something was
wrong. It's reasonable to expect the daemon to listen on the port at the
time it's configured.
Updates tailscale/corp#33094
Signed-off-by: Jordan Whited <jordan@tailscale.com>
I got sidetracked apparently and never finished writing this Clone
code in 316afe7d02 (#17448). (It really should use views instead.)
And then I missed one of the users of "routerChanged" that was broken up
into "routerChanged" vs "dnsChanged".
This broke integration tests elsewhere.
Fixes#17506
Change-Id: I533bf0fcf3da9ac6eb4a6cdef03b8df2c1fb4c8e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Update Nix flake to use go 1.25.2
Create the hash from the toolchain rev file automatically from
update-flake.sh
Updates tailscale/go#135
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This patch fixes several issues related to printing login and device
approval URLs, especially when `tailscale up` is interrupted:
1. Only print a login URL that will cause `tailscale up` to complete.
Don't print expired URLs or URLs from previous login attempts.
2. Print the device approval URL if you run `tailscale up` after
previously completing a login, but before approving the device.
3. Use the correct control URL for device approval if you run a bare
`tailscale up` after previously completing a login, but before
approving the device.
4. Don't print the device approval URL more than once (or at least,
not consecutively).
Updates tailscale/corp#31476
Updates #17361
## How these fixes work
This patch went through a lot of trial and error, and there may still
be bugs! These notes capture the different scenarios and considerations
as we wrote it, which are also captured by integration tests.
1. We were getting stale login URLs from the initial IPN state
notification.
When the IPN watcher was moved to before Start() in c011369, we
mistakenly continued to request the initial state. This is only
necessary if you start watching after you call Start(), because
you may have missed some notifications.
By getting the initial state before calling Start(), we'd get
a stale login URL. If you clicked that URL, you could complete
the login in the control server (if it wasn't expired), but your
instance of `tailscale up` would hang, because it's listening for
login updates from a different login URL.
In this patch, we no longer request the initial state, and so we
don't print a stale URL.
2. Once you skip the initial state from IPN, the following sequence:
* Run `tailscale up`
* Log into a tailnet with device approval
* ^C after the device approval URL is printed, but without approving
* Run `tailscale up` again
means that nothing would ever be printed.
`tailscale up` would send tailscaled the pref `WantRunning: true`,
but that was already the case so nothing changes. You never get any
IPN notifications, and in particular you never get a state change to
`NeedsMachineAuth`. This means we'd never print the device approval URL.
In this patch, we add a hard-coded rule that if you're doing a simple up
(which won't trigger any other IPN notifications) and you start in the
`NeedsMachineAuth` state, we print the device approval message without
waiting for an IPN notification.
3. Consider the following sequence:
* Run `tailscale up --login-server=<custom server>`
* Log into a tailnet with device approval
* ^C after the device approval URL is printed, but without approving
* Run `tailscale up` again
We'd print the device approval URL for the default control server,
rather than the real control server, because we were using the `prefs`
from the CLI arguments (which are all the defaults) rather than the
`curPrefs` (which contain the custom login server).
In this patch, we use the `prefs` if the user has specified any settings
(and other code will ensure this is a complete set of settings) or
`curPrefs` if it's a simple `tailscale up`.
4. Consider the following sequence: you've logged in, but not completed
device approval, and you run `down` and `up` in quick succession.
* `up`: sees state=NeedsMachineAuth
* `up`: sends `{wantRunning: true}`, prints out the device approval URL
* `down`: changes state to Stopped
* `up`: changes state to Starting
* tailscaled: changes state to NeedsMachineAuth
* `up`: gets an IPN notification with the state change, and prints
a second device approval URL
Either URL works, but this is annoying for the user.
In this patch, we track whether the last printed URL was the device
approval URL, and if so, we skip printing it a second time.
Signed-off-by: Alex Chan <alexc@tailscale.com>
This patch extends the integration tests for `tailscale up` to include tailnets
where new devices need to be approved. It doesn't change the CLI, because it's
mostly working correctly already -- these tests are just to prevent future
regressions.
I've added support for `MachineAuthorized` to mock control, and I've refactored
`TestOneNodeUpAuth` to be more flexible. It now takes a sequence of steps to
run and asserts whether we got a login URL and/or machine approval URL after
each step.
Updates tailscale/corp#31476
Updates #17361
Signed-off-by: Alex Chan <alexc@tailscale.com>
This commit also shuffles the hasPeerRelayServers atomic load
to happen sooner, reducing the cost for clients with no peer relay
servers.
Updates tailscale/corp#33099
Signed-off-by: Jordan Whited <jordan@tailscale.com>
The hijacker on k8s-proxy's reverse proxy is used to stream recordings
to tsrecorder as they pass through the proxy to the kubernetes api
server. The connection to the recorder was using the client's
(e.g., kubectl) context, rather than a dedicated one. This was causing
the recording stream to get cut off in scenarios where the client
cancelled the context before streaming could be completed.
By using a dedicated context, we can continue streaming even if the
client cancels the context (for example if the client request
completes).
Fixes#17404
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Originally proposed by @bradfitz in #17413.
In practice, a lot of subscribers have only one event type of interest, or a
small number of mostly independent ones. In that case, the overhead of running
and maintaining a goroutine to select on multiple channels winds up being more
noisy than we'd like for the user of the API.
For this common case, add a new SubscriberFunc[T] type that delivers events to
a callback owned by the subscriber, directly on the goroutine belonging to the
client itself. This frees the consumer from the need to maintain their own
goroutine to pull events from the channel, and to watch for closure of the
subscriber.
Before:
s := eventbus.Subscribe[T](eventClient)
go func() {
for {
select {
case <-s.Done():
return
case e := <-s.Events():
doSomethingWith(e)
}
}
}()
// ...
s.Close()
After:
func doSomethingWithT(e T) { ... }
s := eventbus.SubscribeFunc(eventClient, doSomethingWithT)
// ...
s.Close()
Moreover, unless the caller wants to explicitly stop the subscriber separately
from its governing client, it need not capture the SubscriberFunc value at all.
One downside of this approach is that a slow or deadlocked callback could block
client's service routine and thus stall all other subscriptions on that client,
However, this can already happen more broadly if a subscriber fails to service
its delivery channel in a timely manner, it just feeds back more immediately.
Updates #17487
Change-Id: I64592d786005177aa9fd445c263178ed415784d5
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Since #17376, containerboot crashes on startup in k8s because state
encryption is enabled by default without first checking that it's
compatible with the selected state store. Make sure we only default
state encryption to enabled if it's not going to immediately clash with
other bits of tailscaled config.
Updates tailscale/corp#32909
Change-Id: I76c586772750d6da188cc97b647c6e0c1a8734f0
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Saves ~94 KB from the min build.
Updates #12614
Change-Id: I3b0b8a47f80b9fd3b1038c2834b60afa55bf02c2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Part of making all netlink monitoring code optional.
Updates #17311 (how I got started down this path)
Updates #12614
Change-Id: Ic80d8a7a44dc261c4b8678b3c2241c3b3778370d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Also pull out interface method only needed in Linux.
Instead of having userspace do the call into the router, just let the
router pick up the change itself.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Before we introduced seamless, the "blocked" state was used to track:
* Whether a login was required for connectivity, and therefore we should
keep the engine deconfigured until that happened
* Whether authentication was in progress
"blocked" would stop authReconfig from running. We want this when a login is
required: if your key has expired we want to deconfigure the engine and keep
it down, so that you don't keep using exit nodes (which won't work because
your key has expired).
Taking the engine down while auth was in progress was undesirable, so we
don't do that with seamless renewal. However, not entering the "blocked"
state meant that we needed to change the logic for when to send
LoginFinished on the IPN bus after seeing StateAuthenticated from the
controlclient. Initially we changed the "if blocked" check to "if blocked or
seamless is enabled" which was correct in other places.
In this place however, it introduced a bug: we are sending LoginFinished
every time we see StateAuthenticated, which happens even on a down & up, or
a profile switch. This in turn made it harder for UI clients to track when
authentication is complete.
Instead we should only send it out if we were blocked (i.e. seamless is
disabled, or our key expired) or an auth was in progress.
Updates tailscale/corp#31476
Updates tailscale/corp#32645
Fixes#17363
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
Saves 45 KB from the min build, no longer pulling in deephash or
util/hashx, both with unsafe code.
It can actually be more efficient to not use deephash, as you don't
have to walk all bytes of all fields recursively to answer that two
things are not equal. Instead, you can just return false at the first
difference you see. And then with views (as we use ~everywhere
nowadays), the cloning the old value isn't expensive, as it's just a
pointer under the hood.
Updates #12614
Change-Id: I7b08616b8a09b3ade454bb5e0ac5672086fe8aec
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Historically, and until recently, --extra-small produced a usable build.
When I recently made osrouter be modular in 39e35379d4 (which is
useful in, say, tsnet builds) after also making netstack modular, that
meant --min now lacked both netstack support for routing and system
support for routing, making no way to get packets into
wireguard. That's not a nice default to users. (we've documented
build_dist.sh in our KB)
Restore --extra-small to making a usable build, and add --min for
benchmarking purposes.
Updates #12614
Change-Id: I649e41e324a36a0ca94953229c9914046b5dc497
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Some of the test cases access fields of the backend that are supposed to be
locked while the test is running, which can trigger the race detector. I fixed
a few of these in #17411, but I missed these two cases.
Updates #15160
Updates #17192
Change-Id: I45664d5e34320ecdccd2844e0f8b228145aaf603
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Saves ~53 KB from the min build.
Updates #12614
Change-Id: I73f9544a9feea06027c6ebdd222d712ada851299
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add subscribers for AppConnector events
Make the RouteAdvertiser interface optional We cannot yet remove it because
the tests still depend on it to verify correctness. We will need to separately
update the test fixtures to remove that dependency.
Publish RouteInfo via the event bus, so we do not need a callback to do that.
Replace it with a flag that indicates whether to treat the route info the connector
has as "definitive" for filtering purposes.
Update the tests to simplify the construction of AppConnector values now that a
store callback is no longer required. Also fix a couple of pre-existing racy tests that
were hidden by not being concurrent in the same way production is.
Updates #15160
Updates #17192
Change-Id: Id39525c0f02184e88feaf0d8a3c05504850e47ee
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
If we received a wg engine status while processing an auth URL, there was a
race condition where the authURL could be reset to "" immediately after we
set it.
To fix this we need to check that we are moving from a non-Running state to
a Running state rather than always resetting the URL when we "move" into a
Running state even if that is the current state.
We also need to make sure that we do not return from stopEngineAndWait until
the engine is stopped: before, we would return as soon as we received any
engine status update, but that might have been an update already in-flight
before we asked the engine to stop. Now we wait until we see an update that
is indicative of a stopped engine, or we see that the engine is unblocked
again, which indicates that the engine stopped and then started again while
we were waiting before we checked the state.
Updates #17388
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
Co-authored-by: Nick Khyl <nickk@tailscale.com>
Saves ~102 KB from the min build.
Updates #12614
Change-Id: Ie1d4f439321267b9f98046593cb289ee3c4d6249
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Due to iOS memory limitations in 2020 (see
https://tailscale.com/blog/go-linker, etc) and wireguard-go using
multiple goroutines per peer, commit 16a9cfe2f4 introduced some
convoluted pathsways through Tailscale to look at packets before
they're delivered to wireguard-go and lazily reconfigure wireguard on
the fly before delivering a packet, only telling wireguard about peers
that are active.
We eventually want to remove that code and integrate wireguard-go's
configuration with Tailscale's existing netmap tracking.
To make it easier to find that code later, this makes it modular. It
saves 12 KB (of disk) to turn it off (at the expense of lots of RAM),
but that's not really the point. The point is rather making it obvious
(via the new constants) where this code even is.
Updates #12614
Change-Id: I113b040f3e35f7d861c457eaa710d35f47cee1cb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Explain that this file stays forked from coder/websocket until we can
depend on an upstream release for the helper.
Updates #cleanup
Signed-off-by: kscooo <kscowork@gmail.com>
Switching to a Geneve-encapsulated (peer relay) path in
endpoint.handlePongConnLocked is expected around port rebinds, which end
up clearing endpoint.bestAddr.
Fixestailscale/corp#33036
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Saves only 12 KB, but notably removes some deps on packages that future
changes can then eliminate entirely.
Updates #12614
Change-Id: Ibf830d3ee08f621d0a2011b1d4cd175427ef50df
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
c2n was already a conditional feature, but it didn't have a
feature/c2n directory before (rather, it was using consts + DCE). This
adds it, and moves some code, which removes the httprec dependency.
Also, remove some unnecessary code from our httprec fork.
Updates #12614
Change-Id: I2fbe538e09794c517038e35a694a363312c426a2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
As found by @cmol in #17423.
Updates #17423
Change-Id: I1492501f74ca7b57a8c5278ea6cb87a56a4086b9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Saves 86 KB.
And stop depending on expvar and usermetrics when disabled,
in prep to removing all the expvar/metrics/tsweb stuff.
Updates #12614
Change-Id: I35d2479ddd1d39b615bab32b1fa940ae8cbf9b11
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This patch removes some code that didn’t get removed before merging
the changes in #16580.
Updates #cleanup
Updates #16551
Signed-off-by: Simon Law <sfllaw@tailscale.com>
kubestore init function has now been moved to a more explicit path of
ipn/store/kubestore meaning we can now avoid the generic import of
feature/condregister.
Updates #12614
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
When running integration tests on macOS, we get a panic from a nil
pointer dereference when calling `ci.creds.PID()`.
This panic occurs because the `ci.creds != nil` check is insufficient
after a recent refactoring (c45f881) that changed `ci.creds` from a
pointer to the `PeerCreds` interface. Now `ci.creds` always compares as
non-nil, so we enter this block even when the underlying value is nil.
The integration tests fail on macOS when `peercred.Get()` returns the
error `unix.GetsockoptInt: socket is not connected`. This error isn't
new, and the previous code was ignoring it correctly.
Since we trust that `peercred` returns either a usable value or an error,
checking for a nil error is a sufficient and correct gate to prevent the
method call and avoid the panic.
Fixes#17421
Signed-off-by: Alex Chan <alexc@tailscale.com>
In the earlier http2 package migration (1d93bdce20, #17394) I had
removed Direct.Close's tracking of the connPool, thinking it wasn't
necessary.
Some tests (in another repo) are strict and like it to tear down the
world and wait, to check for leaked goroutines. And they caught this
letting some goroutines idle past Close, even if they'd eventually
close down on their own.
This restores the connPool accounting and the aggressife close.
Updates #17305
Updates #17394
Change-Id: I5fed283a179ff7c3e2be104836bbe58b05130cc7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The control plane will sometimes determine that a node is not online,
while the node is still able to connect to its peers. This patch
doesn’t solve this problem, but it does mitigate it.
This PR introduces the `client-side-reachability` node attribute that
switches the node to completely ignore the online signal from control.
In the future, the client itself should collect reachability data from
active Wireguard flows and Tailscale pings.
Updates #17366
Updates tailscale/corp#30379
Updates tailscale/corp#32686
Signed-off-by: Simon Law <sfllaw@tailscale.com>
A recent change (009d702adf) introduced a deadlock where the
/machine/update-health network request to report the client's health
status update to the control plane was moved to being synchronous
within the eventbus's pump machinery.
I started to instead make the health reporting be async, but then we
realized in the three years since we added that, it's barely been used
and doesn't pay for itself, for how many HTTP requests it makes.
Instead, delete it all and replace it with a c2n handler, which
provides much more helpful information.
Fixestailscale/corp#32952
Change-Id: I9e8a5458269ebfdda1c752d7bbb8af2780d71b04
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Saves 262 KB so far. I'm sure I missed some places, but shotizam says
these were the low hanging fruit.
Updates #12614
Change-Id: Ia31c01b454f627e6d0470229aae4e19d615e45e3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Maybe it matters? At least globally across all nodes?
Fixes#17343
Change-Id: I3f61758ea37de527e16602ec1a6e453d913b3195
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add and wire up event publishers for these two event types in the AppConnector.
Nothing currently subscribes to them, so this is harmless. Subscribers for
these events will be added in a near-future commit.
As part of this, move the appc.RouteInfo type to the types/appctype package.
It does not contain any package-specific details from appc. Beside it, add
appctype.RouteUpdate to carry route update event state, likewise not specific
to appc. Update all usage of the appc.* types throughout to use appctype.*
instead, and update depaware files to reflect these changes.
Add a Close method to the AppConnector to make sure the client gets cleaned up
when the connector is dropped (we re-create connectors).
Update the unit tests in the appc package to also check the events published
alongside calls to the RouteAdvertiser.
For now the tests still rely on the RouteAdvertiser for correctness; this is OK
for now as the two methods are always performed together. In the near future,
we need to rework the tests so not require that, but that will require building
some more test fixtures that we can handle separately.
Updates #15160
Updates #17192
Change-Id: I184670ba2fb920e0d2cb2be7c6816259bca77afe
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Instead of using separate channels to manage the lifecycle of the eventbus
client, use the recently-added eventbus.Monitor, which handles signaling the
processing loop to stop and waiting for it to complete. This allows us to
simplify some of the setup and cleanup code in the relay server.
Updates #15160
Change-Id: Ia1a47ce2e5a31bc8f546dca4c56c3141a40d67af
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Saves 352 KB, removing one of our two HTTP/2 implementations linked
into the binary.
Fixes#17305
Updates #15015
Change-Id: I53a04b1f2687dca73c8541949465038b69aa6ade
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add a .gitignore for the chart version of the CRDs that we never commit,
because the static manifest CRD files are the canonical version. This
makes it easier to deploy the CRDs via the helm chart in a way that
reflects the production workflow without making the git checkout
"dirty".
Given that the chart CRDs are ignored, we can also now safely generate
them for the kube-generate-all Makefile target without being a nuisance
to the state of the git checkout. Added a slightly more robust repo root
detection to the generation logic to make sure the command works from
the context of both the Makefile and the image builder command we run
for releases in corp.
Updates tailscale/corp#32085
Change-Id: Id44a4707c183bfaf95a160911ec7a42ffb1a1287
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
mkctr already has support for including extra files in the built
container image. Wire up a new optional environment variable to thread
that through to mkctr. The operator e2e tests will use this to bake
additional trusted CAs into the test image without significantly
departing from the normal build or deployment process for our
containers.
Updates tailscale/corp#32085
Change-Id: Ica94ed270da13782c4f5524fdc949f9218f79477
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Using memnet and synctest removes flakiness caused by real networking
and subtle timing differences.
Additionally, remove the `t.Logf` call inside the server's shutdown
goroutine that was causing a false positive data race detection.
The race detector is flagging a double write during this `t.Logf` call.
This is a common pattern, noted in golang/go#40343 and elsehwere in
this file, where using `t.Logf` after a test has finished can interact
poorly with the test runner.
This is a long-standing issue which became more common after rewriting
this test to use memnet and synctest.
Fixed#17355
Signed-off-by: Alex Chan <alexc@tailscale.com>
Whenever running on a platform that has a TPM (and tailscaled can access
it), default to encrypting the state. The user can still explicitly set
this flag to disable encryption.
Updates https://github.com/tailscale/corp/issues/32909
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
A following change will split out the controlclient.NoiseClient type
out, away from the rest of the controlclient package which is
relatively dependency heavy.
A question was where to move it, and whether to make a new (a fifth!)
package in the ts2021 dependency chain.
@creachadair and I brainstormed and decided to merge
internal/noiseconn and controlclient.NoiseClient into one package,
with names ts2021.Conn and ts2021.Client.
For ease of reviewing the subsequent PR, this is the first step that
just renames the internal/noiseconn package to control/ts2021.
Updates #17305
Change-Id: Ib5ea162dc1d336c1d805bdd9548d1702dd6e1468
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
depaware was merging golang.org/x/foo and std's
vendor/golang.org/x/foo packages (which could both be in the binary!),
leading to confusing output, especially when I was working on
eliminating duplicate packages imported under different names.
This makes the depaware output longer and grosser, but doesn't hide
reality from us.
Updates #17305
Change-Id: I21cc3418014e127f6c1a81caf4e84213ce84ab57
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Require the presence of the bus, but do not use it yet. Check for required
fields and update tests and production use to plumb the necessary arguments.
Updates #15160
Updates #17192
Change-Id: I8cefd2fdb314ca9945317d3320bd5ea6a92e8dcb
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
The callback itself is not removed as it is used in other repos, making
it simpler for those to slowly transition to the eventbus.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Replace the positional arguments to NewAppConnector with a Config struct.
Update the existing uses. Other than the API change, there are no functional
changes in this commit.
Updates #15160
Updates #17192
Change-Id: Ibf37f021372155a4db8aaf738f4b4f2c746bf623
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
It never launched and I've lost hope of it launching and it's in my
way now, so I guess it's time to say goodbye.
Updates tailscale/corp#4383
Updates #17305
Change-Id: I2eb551d49f2fb062979cc307f284df4b3dfa5956
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This permits other programs (in other repos) to conditionally
import ipn/store/awsstore and/or ipn/store/kubestore and have them
register themselves, rather than feature/condregister doing it.
Updates tailscale/corp#32922
Change-Id: I2936229ce37fd2acf9be5bf5254d4a262d090ec1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The `put` callback runs on a different goroutine to the test, so calling
t.Fatalf in put had no effect. `drain` is always called when checking what
was put and is called from the test goroutine, so that's a good place to
fail the test if the channel was too full.
Updates #17363
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
https://github.com/tailscale/tailscale/pull/17346 moved the kube and aws
arn store initializations to feature/condregister, under the assumption
that anything using it would use kubestore.New. Unfortunately,
cmd/k8s-proxy makes use of store.New, which compares the `<prefix>:`
supplied in the provided `path string` argument against known stores. If
it doesn't find it, it fallsback to using a FileStore.
Since cmd/k8s-proxy uses store.New to try and initialize a kube store in
some cases (without importing feature/condregister), it silently creates
a FileStore and that leads to misleading errors further along in
execution.
This fixes this issue by importing condregister, and successfully
initializes a kube store.
Updates #12614
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Saves 442 KB. Lock it with a new min test.
Updates #12614
Change-Id: Ia7bf6f797b6cbf08ea65419ade2f359d390f8e91
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We will need this for unmarshaling node prefs: use the zero
HardwareAttestationKey implementation when parsing and later check
`IsZero` to see if anything was loaded.
Updates #15830
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
I'm trying to remove the "regexp" and "regexp/syntax" packages from
our minimal builds. But tsweb pulls in regexp (via net/http/pprof etc)
and util/eventbus was importing the tsweb for no reason.
Updates #12614
Change-Id: Ifa8c371ece348f1dbf80d6b251381f3ed39d5fbd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Even with ts_omit_drive, the drive package is currently still imported
for some types. So it should be light. But it was depending on the
"regexp" packge, which I'd like to remove from our minimal builds.
Updates #12614
Change-Id: I5bf85d8eb15a739793723b1da11c370d3fcd2f32
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The Tailscale CLI is the primary configuration interface and as such it
is used in scripts, container setups, and many other places that do not
have a terminal available and should not be made to respond to prompts.
The default is set to false where the "risky" API is being used by the
CLI and true otherwise, this means that the `--yes` flags are only
required under interactive runs and scripts do not need to be concerned
with prompts or extra flags.
Updates #19445
Signed-off-by: James Tucker <james@tailscale.com>
Saves 139 KB.
Also Synology support, which I saw had its own large-ish proxy parsing
support on Linux, but support for proxies without Synology proxy
support is reasonable, so I pulled that out as its own thing.
Updates #12614
Change-Id: I22de285a3def7be77fdcf23e2bec7c83c9655593
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In Dec 2021 in d3d503d997 I had grand plans to make exit node DNS
cheaper by using HTTP/2 over PeerAPI, at least on some platforms. I
only did server-side support though and never made it to the client.
In the ~4 years since, some things have happened:
* Go 1.24 got support for http.Protocols (https://pkg.go.dev/net/http#Protocols)
and doing UnencryptedHTTP2 ("HTTP2 with prior knowledge")
* The old h2c upgrade mechanism was deprecated; see https://github.com/golang/go/issues/63565
and https://github.com/golang/go/issues/67816
* Go plans to deprecate x/net/http2 and move everything to the standard library.
So this drops our use of the x/net/http2/h2c package and instead
enables h2c (on all platforms now) using the standard library.
This does mean we lose the deprecated h2c Upgrade support, but that's
fine.
If/when we do the h2c client support for ExitDNS, we'll have to probe
the peer to see whether it supports it. Or have it reply with a header
saying that future requests can us h2c. (It's tempting to use capver,
but maybe people will disable that support anyway, so we should
discover it at runtime instead.)
Also do the same in the sessionrecording package.
Updates #17305
Change-Id: If323f5ef32486effb18ed836888aa05c0efb701e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Saves 328 KB (2.5%) off the minimal binary.
For IoT devices that don't need MagicDNS (e.g. they don't make
outbound connections), this provides a knob to disable all the DNS
functionality.
Rather than a massive refactor today, this uses constant false values
as a deadcode sledgehammer, guided by shotizam to find the largest DNS
functions which survived deadcode.
A future refactor could make it so that the net/dns/resolver and
publicdns packages don't even show up in the import graph (along with
their imports) but really it's already pretty good looking with just
these consts, so it's not at the top of my list to refactor it more
soon.
Also do the same in a few places with the ACME (cert) functionality,
as I saw those while searching for DNS stuff.
Updates #12614
Change-Id: I8e459f595c2fde68ca16503ff61c8ab339871f97
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
DNS configuration support to ProxyClass, allowing users to customize DNS resolution for Tailscale proxy pods.
Fixes#16886
Signed-off-by: Raj Singh <raj@tailscale.com>
When I added dependency support to featuretag, I broke the handling of
the non-omit build tags (as used by the "box" support for bundling the
CLI into tailscaled). That then affected depaware. The
depaware-minbox.txt this whole time recently has not included the CLI.
So fix that, and also add a new depaware variant that's only the
daemon, without the CLI.
Updates #12614
Updates #17139
Change-Id: I4a4591942aa8c66ad8e3242052e3d9baa42902ca
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Otherwise they're uselessly imported by tsnet applications, even
though they do nothing. tsnet applications wanting to use these
already had to explicitly import them and use kubestore.New or
awsstore.New and assign those to their tsnet.Server.Store fields.
Updates #12614
Change-Id: I358e3923686ddf43a85e6923c3828ba2198991d4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Listen address reuse is allowed as soon as the previous listener is
closed. There is no attempt made to emulate more complex address reuse
logic.
Updates tailscale/corp#28078
Change-Id: I56be1c4848e7b3f9fc97fd4ef13a2de9dcfab0f2
Signed-off-by: Brian Palmer <brianp@tailscale.com>
So wgengine/router is just the docs + entrypoint + types, and then
underscore importing wgengine/router/osrouter registers the constructors
with the wgengine/router package.
Then tsnet can not pull those in.
Updates #17313
Change-Id: If313226f6987d709ea9193c8f16a909326ceefe7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Allow the user to access information about routes an app connector has
learned, such as how many routes for each domain.
Fixestailscale/corp#32624
Signed-off-by: Fran Bull <fran@tailscale.com>
Removes 434 KB from the minimal Linux binary, or ~3%.
Primarily this comes from not linking in the zstd encoding code.
Fixes#17323
Change-Id: I0a90de307dfa1ad7422db7aa8b1b46c782bfaaf7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit modifies the `DNSConfig` custom resource to allow specifying
a replica count when deploying a nameserver. This allows deploying
nameservers in a HA configuration.
Updates https://github.com/tailscale/corp/issues/32589
Signed-off-by: David Bond <davidsbond93@gmail.com>
As of the earlier 85febda86d, our new preferred zstd API of choice
is zstdframe.
Updates #cleanup
Updates tailscale/corp#18514
Change-Id: I5a6164d3162bf2513c3673b6d1e34cfae84cb104
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It has nothing to do with logtail and is confusing named like that.
Updates #cleanup
Updates #17323
Change-Id: Idd34587ba186a2416725f72ffc4c5778b0b9db4a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Now cmd/derper doesn't depend on iptables, nftables, and netlink code :)
But this is really just a cleanup step I noticed on the way to making
tsnet applications able to not link all the OS router code which they
don't use.
Updates #17313
Change-Id: Ic7b4e04e3a9639fd198e9dbeb0f7bae22a4a47a9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This PR cleans up a bunch of things in ./tstest/integration/vms:
- Bumps version of Ubuntu that's actually run from CI 20.04 -> 24.04
- Removes Ubuntu 18.04 test
- Bumps NixOS 21.05 -> 25.05
Updates#cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The dnstype package is used by tailcfg, which tries to be light and
leafy. But it brings in dnstype. So dnstype shouldn't bring in
x/net/dns/dnsmessage.
Updates #12614
Change-Id: I043637a7ce7fed097e648001f13ca1927a781def
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I noticed this while modularizing clientupdate. With this in first,
moving clientupdate to be modular removes a bunch more stuff from
the minimal build + tsnet.
Updates #17115
Change-Id: I44bd055fca65808633fd3a848b0bbc09b00ad4fa
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
As part of making Tailscale's gvisor dependency optional for small builds,
this was one of the last places left that depended on gvisor. Just copy
the couple functions were were using.
Updates #17283
Change-Id: Id2bc07ba12039afe4c8a3f0b68f4d76d1863bbfe
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Baby steps. This permits building without much of gvisor, but not all of it.
Updates #17283
Change-Id: I8433146e259918cc901fe86b4ea29be22075b32c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This only saves ~32KB in the minimal linux/amd64 binary, but it's a
step towards permitting not depending on gvisor for small builds.
Updates #17283
Change-Id: Iae8da5e9465127de354dbcaf25e794a6832d891b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We can only register one key implementation per process. When running on
macOS or Android, trying to register a separate key implementation from
feature/tpm causes a panic.
Updates #15830
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
On platforms that are causing EPIPE at a high frequency this is
resulting in non-working connections, for example when Apple decides to
forcefully close UDP sockets due to an unsoliced packet rejection in the
firewall.
Too frequent rebinds cause a failure to solicit the endpoints triggering
the rebinds, that would normally happen via CallMeMaybe.
Updates #14551
Updates tailscale/corp#25648
Signed-off-by: James Tucker <james@tailscale.com>
This commit fixes a race condition where `tailscale up --force-reauth` would
exit prematurely on an already-logged in device.
Previously, the CLI would wait for IPN to report the "Running" state and then
exit. However, this could happen before the new auth URL was printed, leading
to two distinct issues:
* **Without seamless key renewal:** The CLI could exit immediately after
the `StartLoginInteractive` call, before IPN has time to switch into
the "Starting" state or send a new auth URL back to the CLI.
* **With seamless key renewal:** IPN stays in the "Running" state
throughout the process, so the CLI exits immediately without performing
any reauthentication.
The fix is to change the CLI's exit condition.
Instead of waiting for the "Running" state, if we're doing a `--force-reauth`
we now wait to see the node key change, which is a more reliable indicator
that a successful authentication has occurred.
Updates tailscale/corp#31476
Updates tailscale/tailscale#17108
Signed-off-by: Alex Chan <alexc@tailscale.com>
This partially reverts f3d2fd2.
When that patch was written, the goroutine that responds to IPN notifications
could call `StartLoginInteractive`, creating a race condition that led to
flaky integration tests. We no longer call `StartLoginInteractive` in that
goroutine, so the race is now impossible.
Moving the `WatchIPNBus` call earlier ensures the CLI gets all necessary
IPN notifications, preventing a reauth from hanging.
Updates tailscale/corp#31476
Signed-off-by: Alex Chan <alexc@tailscale.com>
A customer wants to allow their employees to restart tailscaled at will, when access rights and MDM policy allow it,
as a way to fully reset client state and re-create the tunnel in case of connectivity issues.
On Windows, the main tailscaled process runs as a child of a service process. The service restarts the child
when it exits (or crashes) until the service itself is stopped. Regular (non-admin) users can't stop the service,
and allowing them to do so isn't ideal, especially in managed or multi-user environments.
In this PR, we add a LocalAPI endpoint that instructs ipnserver.Server, and by extension the tailscaled process,
to shut down. The service then restarts the child tailscaled. Shutting down tailscaled requires LocalAPI write access
and an enabled policy setting.
Updates tailscale/corp#32674
Updates tailscale/corp#32675
Signed-off-by: Nick Khyl <nickk@tailscale.com>
And yay: tsnet (and thus k8s-operator etc) no longer depends on
portlist! And LocalBackend is smaller.
Removes 50 KB from the minimal binary.
Updates #12614
Change-Id: Iee04057053dc39305303e8bd1d9599db8368d926
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We made changes to ipnext callback registration/unregistration/invocation in #15780
that made resetting b.exthost to a nil, no-op host in (*LocalBackend).Shutdown() unnecessary.
But resetting it is also racy: b.exthost must be safe for concurrent use with or without b.mu held,
so it shouldn't be written after NewLocalBackend returns. This PR removes it.
Fixes#17279
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This change adds full IPv6 support to the Kubernetes operator's DNS functionality,
enabling dual-stack and IPv6-only cluster support.
Fixes#16633
Signed-off-by: Raj Singh <raj@tailscale.com>
Expand the integration tests to cover a wider range of scenarios, including:
* Before and after a successful initial login
* Auth URLs and auth keys
* With and without the `--force-reauth` flag
* With and without seamless key renewal
These tests expose a race condition when using `--force-reauth` on an
already-logged in device. The command completes too quickly, preventing
the auth URL from being displayed. This issue is identified and will be
fixed in a separate commit.
Updates #17108
Signed-off-by: Alex Chan <alexc@tailscale.com>
Ideally we would remove this warning entirely, as it is now possible to
reauthenticate without losing connectivty. However, it is still possible to
lose SSH connectivity if the user changes the ownership of the machine when
they do a force-reauth, and we have no way of knowing if they are going to
do that before they do it.
For now, let's just reduce the strength of the warning to warn them that
they "may" lose their connection, rather than they "will".
Updates tailscale/corp#32429
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
I think this was originally a brain-o in 9380e2dfc6. It's
disabling the port _poller_, listing what open ports (i.e. services)
are open, not PMP/PCP/UPnP port mapping.
While there, drop in some more testenv.AssertInTest() in a few places.
Updates #cleanup
Change-Id: Ia6f755ad3544f855883b8a7bdcfc066e8649547b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
PR #17258 extracted `derp.Server` into `derp/derpserver.Server`.
This followup patch adds the following cleanups:
1. Rename `derp_server*.go` files to `derpserver*.go` to match
the package name.
2. Rename the `derpserver.NewServer` constructor to `derpserver.New`
to reduce stuttering.
3. Remove the unnecessary `derpserver.Conn` type alias.
Updates #17257
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Sidestep cmd/viewer incompatibility hiccups with
HardwareAttestationPublic type due to its *ecdsa.PublicKey inner member
by serializing the key to a byte slice instead.
Updates tailscale/corp#31269
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
This exports a number of things from the derp (generic + client) package
to be used by the new derpserver package, as now used by cmd/derper.
And then enough other misc changes to lock in that cmd/tailscaled can
be configured to not bring in tailscale.com/client/local. (The webclient
in particular, even when disabled, was bringing it in, so that's now fixed)
Fixes#17257
Change-Id: I88b6c7958643fb54f386dd900bddf73d2d4d96d5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Some systems need to tell whether the monitored goroutine has finished
alongside other channel operations (notably in this case the relay server, but
there seem likely to be others similarly situated).
Updates #15160
Change-Id: I5f0f3fae827b07f9b7102a3b08f60cda9737fe28
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Help out the linker's dead code elimination.
Updates #12614
Change-Id: I6c13cb44d3250bf1e3a01ad393c637da4613affb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This doesn't yet fully pull it out into a feature/captiveportal package.
This is the usual first step, moving the code to its own files within
the same packages.
Updates #17254
Change-Id: Idfaec839debf7c96f51ca6520ce36ccf2f8eec92
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
updates tailscale/corp#32600
A localAPI/cli call to reload-config can end up leaving magicsock's mutex
locked. We were missing an unlock for the early exit where there's no change in
the static endpoints when the disk-based config is loaded. This is not likely
the root cause of the linked issue - just noted during investigation.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
In MacOS GUI apps, users have to select folders to share via the GUI. This is both because
the GUI app keeps its own record of shares, and because the sandboxed version of the GUI
app needs to gain access to the shared folders by having the user pick them in a file
selector.
The new build tag `ts_mac_gui` allows the MacOS GUI app build to signal that this
is a MacOS GUI app, which causes the `drive` subcommand to be omitted so that people
do not mistakenly attempt to use it.
Updates tailscale/tailscale#17210
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Also update to use the new DisplayNameOrDefault.
Updates tailscale/corp#30456
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
This commit does not change the order or meaning of any eventbus activity, it
only updates the way the plumbing is set up.
Updates #15160
Change-Id: I61b863f9c05459d530a4c34063a8bad9046c0e27
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Add a last seen time on the cli's status command, similar to the web
portal.
Before:
```
100.xxx.xxx.xxx tailscale-operator tagged-devices linux offline
```
After:
```
100.xxx.xxx.xxx tailscale-operator tagged-devices linux offline, last seen 20d ago
```
Fixes#16584
Signed-off-by: Mahyar Mirrashed <mah.mirr@gmail.com>
This commit does not change the order or meaning of any eventbus activity, it
only updates the way the plumbing is set up.
Updates #15160
Change-Id: I06860ac4e43952a9bb4d85366138c9d9a17fd9cd
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
It is a programming error to Publish or Subscribe on a closed Client, but now
the way you discover that is by getting a panic from down in the machinery of
the bus after the client state has been cleaned up.
To provide a more helpful error, let's panic explicitly when that happens and
say what went wrong ("the client is closed"), by preventing subscriptions from
interleaving with closure of the client. With this change, either an attachment
fails outright (because the client is already closed) or completes and then
shuts down in good order in the normal course.
This does not change the semantics of the client, publishers, or subscribers,
it's just making the failure more eager so we can attach explanatory text.
Updates #15160
Change-Id: Ia492f4c1dea7535aec2cdcc2e5ea5410ed5218d2
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Only changes how the go routine consuming the events starts and stops,
not what it does.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit modifies the k8s operator to wrap its logger using the logtail
logger provided via the tsnet server. This causes any logs written by
the operator to make their way to Tailscale in the same fashion as
wireguard logs to be used by support.
This functionality can also be opted-out of entirely using the
"TS_NO_LOGS_NO_SUPPORT" environment variable.
Updates https://github.com/tailscale/corp/issues/32037
Signed-off-by: David Bond <davidsbond93@gmail.com>
We never implemented the peercred package on OpenBSD (and I just tried
again and failed), but we've always documented that the creds pointer
can be nil for operating systems where we can't map the unix socket
back to its UID. On those platforms, we set the default unix socket
permissions such that only the admin can open it anyway and we don't
have a read-only vs read-write distinction. OpenBSD was always in that
camp, where any access to Tailscale's unix socket meant full access.
But during some refactoring, we broke OpenBSD in that we started
assuming during one logging path (during login) that Creds was non-nil
when looking up an ipnauth.Actor's username, which wasn't relevant (it
was called from a function "maybeUsernameOf" anyway, which threw away
errors).
Verified on an OpenBSD VM. We don't have any OpenBSD integration tests yet.
Fixes#17209
Updates #17221
Change-Id: I473c5903dfaa645694bcc75e7f5d484f3dd6044d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
controlhttp has the responsibility of dialing a set of candidate control
endpoints in a way that minimizes user facing latency. If one control
endpoint is unavailable we promptly dial another, racing across the
dimensions of: IPv6, IPv4, port 80, and port 443, over multiple server
endpoints.
In the case that the top priority endpoint was not available, the prior
implementation would hang waiting for other results, so as to try to
return the highest priority successful connection to the rest of the
client code. This hang would take too long with a large dialplan and
sufficient client to endpoint latency as to cause the server to timeout
the connection due to inactivity in the intermediate state.
Instead of trying to prioritize non-ideal candidate connections, the
first successful connection is now used unconditionally, improving user
facing latency and avoiding any delays that would encroach on the
server-side timeout.
The tests are converted to memnet and synctest, running on all
platforms.
Fixes#8442Fixestailscale/corp#32534
Co-authored-by: James Tucker <james@tailscale.com>
Change-Id: I4eb57f046d8b40403220e40eb67a31c41adb3a38
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: James Tucker <james@tailscale.com>
The controlhttp dialer with a ControlDialPlan IPv6 entry was hitting a
case where the dnscache Resolver was returning an netip.Addr zero
value, where it should've been returning the IPv6 address.
We then tried to dial "invalid IP:80", which would immediately fail,
at least locally.
Mostly this was causing spammy logs when debugging other stuff.
Updates tailscale/corp#32534
Change-Id: If8b9a20f10c1a6aa8a662c324151d987fe9bd2f8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
tsnet apps in particular never use the Linux DNS OSManagers, so they don't need
DBus, etc. I started to pull that all out into separate features so tsnet doesn't
need to bring in DBus, but hit this first.
Here you can see that tsnet (and the k8s-operator) no longer pulls in inotify.
Updates #17206
Change-Id: I7af0f391f60c5e7dbeed7a080346f83262346591
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit does not change the order or meaning of any eventbus activity, it
only updates the way the plumbing is set up.
Updates #15160
Change-Id: I0a175e67e867459daaedba0731bf68bd331e5ebc
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit does not change the order or meaning of any eventbus activity, it
only updates the way the plumbing is set up.
Updates #15160
Change-Id: I40c23b183c2a6a6ea3feec7767c8e5417019fc07
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
A common pattern in event bus usage is to run a goroutine to service a
collection of subscribers on a single bus client. To have an orderly shutdown,
however, we need a way to wait for such a goroutine to be finished.
This commit adds a Monitor type that makes this pattern easier to wire up:
rather than having to track all the subscribers and an extra channel, the
component need only track the client and the monitor. For example:
cli := bus.Client("example")
m := cli.Monitor(func(c *eventbus.Client) {
s1 := eventbus.Subscribe[T](cli)
s2 := eventbus.Subscribe[U](cli)
for {
select {
case <-c.Done():
return
case t := <-s1.Events():
processT(t)
case u := <-s2.Events():
processU(u)
}
}
})
To shut down the client and wait for the goroutine, the caller can write:
m.Close()
which closes cli and waits for the goroutine to finish. Or, separately:
cli.Close()
// do other stuff
m.Wait()
While the goroutine management is not explicitly tied to subscriptions, it is a
common enough pattern that this seems like a useful simplification in use.
Updates #15160
Change-Id: I657afda1cfaf03465a9dce1336e9fd518a968bca
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Pulls out the last callback logic and ensures timers are still running.
The eventbustest package is updated support the absence of events.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
And another case of the same typo in a comment elsewhere.
Updates #cleanup
Change-Id: Iaa9d865a1cf83318d4a30263c691451b5d708c9c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* tsnet,internal/client/tailscale: resolve OAuth into authkeys in tsnet
Updates #8403.
* internal/client/tailscale: omit OAuth library via build tag
Updates #12614.
Signed-off-by: Naman Sood <mail@nsood.in>
Expand TestRedactNetmapPrivateKeys to cover all sub-structs of
NetworkMap and confirm that a) all fields are annotated as private or
public, and b) all private fields are getting redacted.
Updates tailscale/corp#32095
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
For debugging purposes, add a new C2N endpoint returning the current
netmap. Optionally, coordination server can send a new "candidate" map
response, which the client will generate a separate netmap for.
Coordination server can later compare two netmaps, detecting unexpected
changes to the client state.
Updates tailscale/corp#32095
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Instead of a single hard-coded C2N handler, add support for calling
arbitrary C2N endpoints via a node roundtripper.
Updates tailscale/corp#32095
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
When tests run in parallel, events from multiple tests on the same bus can
intercede with each other. This is working as intended, but for the test cases
we want to control exactly what goes through the bus.
To fix that, allocate a fresh bus for each subtest.
Fixes#17197
Change-Id: I53f285ebed8da82e72a2ed136a61884667ef9a5e
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
When developing (and debugging) tests, it is useful to be able to see all the
traffic that transits the event bus during the execution of a test.
Updates #15160
Change-Id: I929aee62ccf13bdd4bd07d786924ce9a74acd17a
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Previously, seamless key renewal was an opt-in feature. Customers had
to set a `seamless-key-renewal` node attribute in their policy file.
This patch enables seamless key renewal by default for all clients.
It includes a `disable-seamless-key-renewal` node attribute we can set
in Control, so we can manage the rollout and disable the feature for
clients with known bugs. This new attribute makes the feature opt-out.
Updates tailscale/corp#31479
Signed-off-by: Alex Chan <alexc@tailscale.com>
This makes the `switch` command use the helper `matchProfile` function
that was introduced in the `remove` sub command.
Signed-off-by: Esteban-Bermudez <esteban@bermudezaguirre.com>
Fixes#12255
Add a new subcommand to `switch` for removing a profile from the local
client. This does not delete the profile from the Tailscale account, but
removes it from the local machine. This functionality is available on
the GUI's, but not yet on the CLI.
Signed-off-by: Esteban-Bermudez <esteban@bermudezaguirre.com>
It doesn't really pull its weight: it adds 577 KB to the binary and
is rarely useful.
Also, we now have static IPs and other connectivity paths coming
soon enough.
Updates #5853
Updates #1278
Updates tailscale/corp#32168
Change-Id: If336fed00a9c9ae9745419e6d81f7de6da6f7275
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For a common case of events being simple struct types with some exported
fields, add a helper to check (reflectively) for equal values using cmp.Diff so
that a failed comparison gives a useful diff in the test output.
More complex uses will still want to provide their own comparisons; this
(intentionally) does not export diff options or other hooks from the cmp
package.
Updates #15160
Change-Id: I86bee1771cad7debd9e3491aa6713afe6fd577a6
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This makes things work slightly better over the eventbus.
Also switches ipnlocal to use the event over the eventbus instead of the
direct callback.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Extend the Expect method of a Watcher to allow filter functions that report
only an error value, and which "pass" when the reported error is nil.
Updates #15160
Change-Id: I582d804554bd1066a9e499c1f3992d068c9e8148
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This fixes a flaky test which has been occasionally timing out in CI.
In particular, this test times out if `watchFile` receives multiple
notifications from inotify before we cancel the test context. We block
processing the second notification, because we've stopped listening to
the `callbackDone` channel.
This patch changes the test so we only send on the first notification.
Testing this locally with `stress` confirms that the test is no longer
flaky.
Fixes#17172
Updates #14699
Signed-off-by: Alex Chan <alexc@tailscale.com>
I'd started to do this in the earlier ts_omit_server PR but
decided to split it into this separate PR.
Updates #17128
Change-Id: Ief8823a78d1f7bbb79e64a5cab30a7d0a5d6ff4b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Instead of waiting for a designated subscription to close as a canary for the
bus being stopped, use the bus Client's own signal for closure added in #17118.
Updates #cleanup
Change-Id: I384ea39f3f1f6a030a6282356f7b5bdcdf8d7102
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
The Tracker was using direct callbacks to ipnlocal. This PR moves those
to be triggered via the eventbus.
Additionally, the eventbus is now closed on exit from tailscaled
explicitly, and health is now a SubSystem in tsd.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Subscribers already have a Done channel that the caller can use to detect when
the subscriber has been closed. Typically this happens when the governing
Client closes, which in turn is typically because the Bus closed.
But clients and subscribers can stop at other times too, and a caller has no
good way to tell the difference between "this subscriber closed but the rest
are OK" and "the client closed and all these subscribers are finished".
We've worked around this in practice by knowing the closure of one subscriber
implies the fate of the rest, but we can do better: Add a Done method to the
Client that allows us to tell when that has been closed explicitly, after all
the publishers and subscribers associated with that client have been closed.
This allows the caller to be sure that, by the time that occurs, no further
pending events are forthcoming on that client.
Updates #15160
Change-Id: Id601a79ba043365ecdb47dd035f1fdadd984f303
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Remove the need for the caller to hold on to and call an unregister
function. Both two callers (one real, one test) already have a context
they can use. Use context.AfterFunc instead. There are no observable
side effects from scheduling too late if the goroutine doesn't run sync.
Updates #17148
Change-Id: Ie697dae0e797494fa8ef27fbafa193bfe5ceb307
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This test ostensibly checks whether we record an error metric if a packet
is dropped because the network is down, but the network connectivity is
irrelevant -- the send error is actually because the arguments to Send()
are invalid:
RebindingUDPConn.WriteWireGuardBatchTo:
[unexpected] offset (0) != Geneve header length (8)
This patch changes the test so we try to send a valid packet, and we
verify this by sending it once before taking the network down. The new
error is:
magicsock: network down
which is what we're trying to test.
We then test sending an invalid payload as a separate test case.
Updates tailscale/corp#22075
Signed-off-by: Alex Chan <alexc@tailscale.com>
endpointState is used for tracking UDP direct connection candidate
addresses. If it contains a DERP addr, then direct connection path
discovery will always send a wasteful disco ping over it. Additionally,
CLI "tailscale ping" via peer relay will race over DERP, leading to a
misleading result if pong arrives via DERP first.
Disco pongs arriving via DERP never influence path selection. Disco
ping/pong via DERP only serves "tailscale ping" reporting.
Updates #17121
Signed-off-by: Jordan Whited <jordan@tailscale.com>
When you say --features=foo,bar, that was supposed to mean
to only show features "foo" and "bar" in the table.
But it was also being used as the set of all features that are
omittable, which was wrong, leading to misleading numbers
when --features was non-empty.
Updates #12614
Change-Id: Idad2fa67fb49c39454032e84a3dede967890fdf5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The Unix implementation of doExec propagates error codes by virtue of
the fact that it does an execve; the replacement binary will return the
exit code.
On non-Unix, we need to simulate these semantics by checking for an
ExitError and, when present, passing that value on to os.Exit.
We also add error handling to the doExec call for the benefit of
handling any errors where doExec fails before being able to execute
the desired binary.
Updates https://github.com/tailscale/corp/issues/29940
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This renames the package+symbols in the earlier 17ffa80138 to be
in their own package ("buildfeatures") and start with the word "Has"
like "if buildfeatures.HasFoo {".
Updates #12614
Change-Id: I510e5f65993e5b76a0e163e3aa4543755213cbf6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Extend the client state management to generate a hardware attestation
key if none exists.
Extend MapRequest with HardwareAttestationKey{,Signature} fields that
optionally contain the public component of the hardware attestation key
and a signature of the node's node key using it. This will be used by
control to associate hardware attesation keys with node identities on a
TOFU basis.
Updates tailscale/corp#31269
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
So code (in upcoming PRs) can test for the build tags with consts and
get dead code elimination from the compiler+linker.
Updates #12614
Change-Id: If6160453ffd01b798f09894141e7631a93385941
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is a small introduction of the eventbus into controlclient that
communicates with mainly ipnlocal. While ipnlocal is a complicated part
of the codebase, the subscribers here are from the perspective of
ipnlocal already called async.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit fixes an issue within the service reconciler where we end
up in a constant reconciliation loop. When reconciling, the loadbalancer
status is appended to but not reset between each reconciliation, leading
to an ever growing slice of duplicate statuses.
Fixes https://github.com/tailscale/tailscale/issues/17105
Fixes https://github.com/tailscale/tailscale/issues/17107
Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit adds a new method to the tsnet.Server type named `Logger`
that returns the underlying logtail instance's Logf method.
This is intended to be used within the Kubernetes operator to wrap its
existing logger in a way such that operator specific logs can also be
sent to control for support & debugging purposes.
Updates https://github.com/tailscale/corp/issues/32037
Signed-off-by: David Bond <davidsbond93@gmail.com>
As of this commit (per the issue), the Taildrive code remains where it
was, but in new files that are protected by the new ts_omit_drive
build tag. Future commits will move it.
Updates #17058
Change-Id: Idf0a51db59e41ae8da6ea2b11d238aefc48b219e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Its doc said its signature matched a std signature, but it used
Tailscale-specific types.
Nowadays it's the caller (func control) that curries the logf/netmon
and returns the std-matching signature.
Updates #cleanup (while answering a question on Slack)
Change-Id: Ic99de41fc6a1c720575a7f33c564d0bcfd9a2c30
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
To support integration testing of client features that rely on it, e.g.
peer relay.
Updates tailscale/corp#30903
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Removes ACL edits from e2e tests in favour of trying to simplify the
tests and separate the actual test logic from the environment setup
logic as much as possible. Also aims to fit in with the requirements
that will generally be filled anyway for most devs working on the
operator; in particular using tags that fit in with our documentation.
Updates tailscale/corp#32085
Change-Id: I7659246e39ec0b7bcc4ec0a00c6310f25fe6fac2
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This adds a file that's not compiled by default that exists just to
make it easier to do binary size checks, probing what a binary would
be like if it included reflect methods (as used by html/template, etc).
As an example, once tailscaled uses reflect.Type.MethodByName(non-const-string) anywhere,
the build jumps up by 14.5 MB:
$ GOOS=linux GOARCH=amd64 ./tool/go build -tags=ts_include_cli,ts_omit_webclient,ts_omit_systray,ts_omit_debugeventbus -o before ./cmd/tailscaled
$ GOOS=linux GOARCH=amd64 ./tool/go build -tags=ts_include_cli,ts_omit_webclient,ts_omit_systray,ts_omit_debugeventbus,ts_debug_forcereflect -o after ./cmd/tailscaled
$ ls -l before after
-rwxr-xr-x@ 1 bradfitz staff 41011861 Sep 9 07:28 before
-rwxr-xr-x@ 1 bradfitz staff 55610948 Sep 9 07:29 after
This is particularly pronounced with large deps like the AWS SDK. If you compare using ts_omit_aws:
-rwxr-xr-x@ 1 bradfitz staff 38284771 Sep 9 07:40 no-aws-no-reflect
-rwxr-xr-x@ 1 bradfitz staff 45546491 Sep 9 07:41 no-aws-with-reflect
That means adding AWS to a non-reflect binary adds 2.7 MB but adding
AWS to a reflect binary adds 10 MB.
Updates #17063
Updates #12614
Change-Id: I18e9b77c9cf33565ce5bba65ac5584fa9433f7fb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* cmd/tailscale/cli: use client/local instead of deprecated client/tailscale
Updates tailscale/corp#22748
Signed-off-by: Alex Chan <alexc@tailscale.com>
* derp: use client/local instead of deprecated client/tailscale
Updates tailscale/corp#22748
Signed-off-by: Alex Chan <alexc@tailscale.com>
---------
Signed-off-by: Alex Chan <alexc@tailscale.com>
I probably could've deflaked this without synctest, but might as well use
it now that Go 1.25 has it.
Fixes#15348
Change-Id: I81c9253fcb7eada079f3e943ab5f1e29ba8e8e31
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* utils/expvarx: mark TestSafeFuncHappyPath as known flaky
Updates #15348
Signed-off-by: Alex Chan <alexc@tailscale.com>
* tstest/integration: mark TestCollectPanic as known flaky
Updates #15865
Signed-off-by: Alex Chan <alexc@tailscale.com>
---------
Signed-off-by: Alex Chan <alexc@tailscale.com>
It was a bit confusing that provided history did not include the
current probe results.
Updates tailscale/corp#20583
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
We should never use the real syspolicy implementation in tests by
default. (the machine's configuration shouldn't affect tests)
You either specify a test policy, or you get a no-op one.
Updates #16998
Change-Id: I3350d392aad11573a5ad7caab919bb3bbaecb225
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit modifies containerboot's state reset process to handle the
state secret not existing. During other parts of the boot process we
gracefully handle the state secret not being created yet, but missed
that check within `resetContainerbootState`
Fixes https://github.com/tailscale/tailscale/issues/16804
Signed-off-by: David Bond <davidsbond93@gmail.com>
Fix "file not found" errors when WebDAV clients access files/dirs inside
directories with spaces.
The issue occurred because StatCache was mixing URL-escaped and
unescaped paths, causing cache key mismatches.
Specifically, StatCache.set() parsed WebDAV responses containing
URL-escaped paths (ex. "Dir%20Space/file1.txt") and stored them
alongside unescaped cache keys (ex. "Dir Space/file1.txt").
This mismatch prevented StatCache.get() from correctly determining whether
a child file existed.
See https://github.com/tailscale/tailscale/issues/13632#issuecomment-3243522449
for the full explanation of the issue.
The decision to keep all paths references unescaped inside the StatCache
is consistent with net/http.Request.URL.Path and rewrite.go (sole consumer)
Update unit test to detect this directory space mishandling.
Fixes tailscale#13632
Signed-off-by: Craig Hesling <craig@hesling.com>
There's a TODO to delete all of handler.go, but part of it's
still used in another repo.
But this deletes some.
Updates #17022
Change-Id: Ic5a8a5a694ca258440307436731cd92b45ee2d21
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Before:
$ tailscale ip -4
1.2.3.4
$ tailscale set --exit-node=1.2.3.4
no node found in netmap with IP 1.2.3.4
After:
$ tailscale set --exit-node=1.2.3.4
cannot use 1.2.3.4 as an exit node as it is a local IP address to this machine; did you mean --advertise-exit-node?
The new error message already existed in the code, but would only be
triggered if the backend wasn't running -- which means, in practice,
it would almost never be triggered.
The old error message is technically true, but could be confusing if you
don't know the distinction between "netmap" and "tailnet" -- it could
sound like the exit node isn't part of your tailnet. A node is never in
its own netmap, but it is part of your tailnet.
This error confused me when I was doing some local dev work, and it's
confused customers before (e.g. #7513). Using the more specific error
message should reduce confusion.
Updates #7513
Updates https://github.com/tailscale/corp/issues/23596
Signed-off-by: Alex Chan <alexc@tailscale.com>
Now that we have policytest and the policyclient.Client interface, we
can de-global-ify many of the tests, letting them run concurrently
with each other, and just removing global variable complexity.
This does ~half of the LocalBackend ones.
Updates #16998
Change-Id: Iece754e1ef4e49744ccd967fa83629d0dca6f66a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is step 4 of making syspolicy a build-time feature.
This adds a policyclient.Get() accessor to return the correct
implementation to use: either the real one, or the no-op one. (A third
type, a static one for testing, also exists, so in general a
policyclient.Client should be plumbed around and not always fetched
via policyclient.Get whenever possible, especially if tests need to use
alternate syspolicy)
Updates #16998
Updates #12614
Change-Id: Iaf19670744a596d5918acfa744f5db4564272978
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Step 4 of N. See earlier commits in the series (via the issue) for the
plan.
This adds the missing methods to policyclient.Client and then uses it
everywhere in ipn/ipnlocal and locks it in with a new dep test.
Still plenty of users of the global syspolicy elsewhere in the tree,
but this is a lot of them.
Updates #16998
Updates #12614
Change-Id: I25b136539ae1eedbcba80124de842970db0ca314
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Step 3 in the series. See earlier cc532efc20 and d05e6dc09e.
This step moves some types into a new leaf "ptype" package out of the
big "settings" package. The policyclient.Client will later get new
methods to return those things (as well as Duration and Uint64, which
weren't done at the time of the earlier prototype).
Updates #16998
Updates #12614
Change-Id: I4d72d8079de3b5351ed602eaa72863372bd474a2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously, when attempting a risky action, the CLI printed a 5 second countdown saying
"Continuing in 5 seconds...". When the countdown finished, the CLI aborted rather than
continuing.
To avoid confusion, but also avoid accidentally continuing if someone (or an automated
process) fails to manually abort within the countdown, we now explicitly prompt for a
y/n response on whether or not to continue.
Updates #15445
Co-authored-by: Kot C <kot@kot.pink>
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This commit adds a `replicas` field to the `Connector` custom resource that
allows users to specify the number of desired replicas deployed for their
connectors.
This allows users to deploy exit nodes, subnet routers and app connectors
in a highly available fashion.
Fixes#14020
Signed-off-by: David Bond <davidsbond93@gmail.com>
This is step 2 of ~4, breaking up #14720 into reviewable chunks, with
the aim to make syspolicy be a build-time configurable feature.
Step 1 was #16984.
In this second step, the util/syspolicy/policyclient package is added
with the policyclient.Client interface. This is the interface that's
always present (regardless of build tags), and is what code around the
tree uses to ask syspolicy/MDM questions.
There are two implementations of policyclient.Client for now:
1) NoPolicyClient, which only returns default values.
2) the unexported, temporary 'globalSyspolicy', which is implemented
in terms of the global functions we wish to later eliminate.
This then starts to plumb around the policyclient.Client to most callers.
Future changes will plumb it more. When the last of the global func
callers are gone, then we can unexport the global functions and make a
proper policyclient.Client type and constructor in the syspolicy
package, removing the globalSyspolicy impl out of tsd.
The final change will sprinkle build tags in a few more places and
lock it in with dependency tests to make sure the dependencies don't
later creep back in.
Updates #16998
Updates #12614
Change-Id: Ib2c93d15c15c1f2b981464099177cd492d50391c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is step 1 of ~3, breaking up #14720 into reviewable chunks, with
the aim to make syspolicy be a build-time configurable feature.
In this first (very noisy) step, all the syspolicy string key
constants move to a new constant-only (code-free) package. This will
make future steps more reviewable, without this movement noise.
There are no code or behavior changes here.
The future steps of this series can be seen in #14720: removing global
funcs from syspolicy resolution and using an interface that's plumbed
around instead. Then adding build tags.
Updates #12614
Change-Id: If73bf2c28b9c9b1a408fe868b0b6a25b03eeabd1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Apparently, #16989 introduced a bug in request-dataplane-review.yml:
> you may only define one of `paths` and `paths-ignore` for a single event
Related #16372
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
@tailscale/dataplane almost never needs to review depaware.txt, when
it is the only change to the DERP implementation.
Related #16372
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
If the DERP queue is full, drop the oldest item first, rather than the
youngest, on the assumption that older data is more likely to be
unanswerable.
Updates tailscale/corp#31762
Signed-off-by: James Tucker <james@tailscale.com>
Add a ternary flag that unless set explicitly to false keeps the
insecure behavior of TSIDP.
If the flag is false, add functionality on startup to migrate
oidc-funnel-clients.json to oauth-clients.json if it doesn’t exist.
If the flag is false, modify endpoints to behave similarly regardless
of funnel, tailnet, or localhost. They will all verify client ID & secret
when appropriate per RFC 6749. The authorize endpoint will no longer change
based on funnel status or nodeID.
Add extra tests verifying TSIDP endpoints behave as expected
with the new flag.
Safely create the redirect URL from what's passed into the
authorize endpoint.
Fixes #16880
Signed-off-by: Remy Guercio <remy@tailscale.com>
Doesn't look to affect us, but pacifies security scanners.
See 88ddf1d0d9
It's for decoding. We only use this package for encoding (via
github.com/google/rpmpack / github.com/goreleaser/nfpm/v2).
Updates #8043
Change-Id: I87631aa5048f9514bb83baf1424f6abb34329c46
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Our own WaitGroup wrapper type was a prototype implementation
for the Go method on the standard sync.WaitGroup type.
Now that there is first-class support for Go,
we should migrate over to using it and delete syncs.WaitGroup.
Updates #cleanup
Updates tailscale/tailscale#16330
Change-Id: Ib52b10f9847341ce29b4ca0da927dc9321691235
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
DERP writes go via TCP and the host OS will have plenty of buffer space.
We've observed in the wild with a backed up TCP socket kernel side
buffers of >2.4MB. The DERP internal queue being larger causes an
increase in the probability that the contents of the backbuffer are
"dead letters" - packets that were assumed to be lost.
A first step to improvement is to size this queue only large enough to
avoid some of the initial connect stall problem, but not large enough
that it is contributing in a substantial way to buffer bloat /
dead-letter retention.
Updates tailscale/corp#31762
Signed-off-by: James Tucker <james@tailscale.com>
I need a ringbuffer in the more traditional sense, one that has a notion
of item removal as well as tail loss on overrun. This implementation is
really a clearable log window, and is used as such where it is used.
Updates #cleanup
Updates tailscale/corp#31762
Signed-off-by: James Tucker <james@tailscale.com>
Bump Go 1.25 release to include a go/types patch and resolve govulncheck
CI exceptions.
Updates tailscale/corp#31755
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Extract field comments from AST and include them in generated view
methods. Comments are preserved from the original struct fields to
provide documentation for the view accessors.
Fixes#16958
Signed-off-by: Maisem Ali <3953239+maisem@users.noreply.github.com>
fixestailscale/corp#26369
The suggested exit node is currently only calculated during a localAPI request.
For older UIs, this wasn't a bad choice - we could just fetch it on-demand when a menu
presented itself. For newer incarnations however, this is an always-visible field
that needs to react to changes in the suggested exit node's value.
This change recalculates the suggested exit node ID on netmap updates and
broadcasts it on the IPN bus. The localAPI version of this remains intact for the
time being.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
updates tailscale/corp#29841
Adds a node cap macOS UIs can query to determine
whether then should enable the new windowed UI.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
Pull the lock-bearing code into a closure, and use a clone rather than a
shallow copy of the hostinfo record.
Updates #11649
Change-Id: I4f1d42c42ce45e493b204baae0d50b1cbf82b102
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
The early unlock on this branch was required because the "send" method goes on
to acquire the mutex itself. Rather than release the lock just to acquire it
again, call the underlying locked helper directly.
Updates #11649
Change-Id: I50d81864a00150fc41460b7486a9c65655f282f5
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
In places where we are locking the LocakBackend and immediately deferring an
unlock, and where there is no shortcut path in the control flow below the
deferral, we do not need the unlockOnce helper. Replace all these with use of
the lock directly.
Updates #11649
Change-Id: I3e6a7110dfc9ec6c1d38d2585c5367a0d4e76514
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Instead of referring to groups, which is a term of art for a different entity,
update the doc comments to more accurately describe what tags are in reference
to the policy document.
Updates #cleanup
Change-Id: Iefff6f84981985f834bae7c6a6c34044f53f2ea2
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
There are several methods within the LocalBackend that used an unusual and
error-prone lock discipline whereby they require the caller to hold the backend
mutex on entry, but release it on the way out.
In #11650 we added some support code to make this pattern more visible.
Now it is time to eliminate the pattern (at least within this package).
This is intended to produce no semantic changes, though I am relying on
integration tests and careful inspection to achieve that.
To the extent possible I preserved the existing control flow. In a few places,
however, I replaced this with an unlock/lock closure. This means we will
sometimes reacquire a lock only to release it again one frame up the stack, but
these operations are not performance sensitive and the legibility gain seems
worthwhile.
We can probably also pull some of these out into separate methods, but I did
not do that here so as to avoid other variable scope changes that might be hard
to see. I would like to do some more cleanup separately.
As a follow-up, we could also remove the unlockOnce helper, but I did not do
that here either.
Updates #11649
Change-Id: I4c92d4536eca629cfcd6187528381c33f4d64e20
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
The serve code leaves it up to the system's DNS resolver and netstack to
figure out how to reach the proxy destination. Combined with k8s-proxy
running in userspace mode, this means we can't rely on MagicDNS being
available or tailnet IPs being routable. I'd like to implement that as a
feature for serve in userspace mode, but for now the safer fix to get
kube-apiserver ProxyGroups consistently working in all environments is to
switch to using localhost as the proxy target instead.
This has a small knock-on in the code that does WhoIs lookups, which now
needs to check the X-Forwarded-For header that serve populates to get
the correct tailnet IP to look up, because the request's remote address
will be loopback.
Fixes#16920
Change-Id: I869ddcaf93102da50e66071bb00114cc1acc1288
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This increases throughput over long fat networks, and in the presence
of crypto/syscall-induced delay.
Updates tailscale/corp#31164
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Update odic-funnel-clients.json to take a path, this
allows setting the location of the file and prevents
it from landing in the root directory or users home directory.
Move setting of rootPath until after tsnet has started.
Previously this was added for the lazy creation of the
oidc-key.json. It's now needed earlier in the flow.
Updates #16734Fixes#16844
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Add the ability for operators of natc in consensus mode to remove
servers from the raft cluster config, without losing other state.
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
Currently consensus has a bootstrap routine where a tsnet node tries to
join each other node with the cluster tag, and if it is not able to join
any other node it starts its own cluster.
That algorithm is racy, and can result in split brain (more than one
leader/cluster) if all the nodes for a cluster are started at the same
time.
Add a FollowOnly argument to the bootstrap function. If provided this
tsnet node will never lead, it will try (and retry with exponential back
off) to follow any node it can contact.
Add a --follow-only flag to cmd/natc that uses this new tsconsensus
functionality.
Also slightly reorganize some arguments into opts structs.
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
This significantly improves throughput of a peer relay server on Linux.
Server.packetReadLoop no longer passes sockets down the stack. Instead,
packet handling methods return a netip.AddrPort and []byte, which
packetReadLoop gathers together for eventual batched writes on the
appropriate socket(s).
Updates tailscale/corp#31164
Signed-off-by: Jordan Whited <jordan@tailscale.com>
We have been unintentionally ignoring errors from calling bootstrap.
bootstrap sometimes calls raft.BootstrapCluster which sometimes returns
a safe to ignore error, handle that case appropriately.
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
This has come up in a few situations recently and adding these helpers
is much better than copying the slice (calling AsSlice()) in order to
use slices.Max and friends.
Updates #cleanup
Change-Id: Ib289a07d23c3687220c72c4ce341b9695cd875bf
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
Update the runall handler to be more generic with an
exclude param to exclude multiple probes as the requesters
definition.
Updates tailscale/corp#27370
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Cleanup nix support, make flake easier to read with nix-systems.
This also harmonizes with golinks flake setup and reduces an input
dependency by 1.
Update deps test to ensure the vendor hash stays harmonized
with go.mod.
Update make tidy to ensure vendor hash stays current.
Overlay the current version of golang, tailscale runs
recent releases faster than nixpkgs can update them into
the unstable branch.
Updates #16637
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
The -Environment argument to Start-Process is essentially being treated
as a delta; removing a particular variable from the argument's hash
table does not indicate to delete. Instead we must set the value of each
unwanted variable to $null.
Updates https://github.com/tailscale/corp/issues/29940
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Some of the operations of the local API need an event bus to correctly
instantiate other components (notably including the portmapper).
This commit adds that, and as the parameter list is starting to get a bit long
and hard to read, I took the opportunity to move the arguments to a config
type. Only a few call sites needed to be updated and this API is not intended
for general use, so I did not bother to stage the change.
Updates #15160
Updates #16842
Change-Id: I7b057d71161bd859f5acb96e2f878a34c85be0ef
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
gocross-wrapper.ps1 is a PowerShell core script that is essentially a
straight port of gocross-wrapper.sh. It requires PowerShell 7.4, which
is the latest LTS release of PSCore.
Why use PowerShell Core instead of Windows PowerShell? Essentially
because the former is much better to script with and is the edition
that is currently maintained.
Because we're using PowerShell Core, but many people will be running
scripts from a machine that only has Windows PowerShell, go.cmd has
been updated to prompt the user for PowerShell core installation if
necessary.
gocross-wrapper.sh has also been updated to utilize the PSCore script
when running under cygwin or msys.
gocross itself required a couple of updates:
We update gocross to output the PowerShell Core wrapper alongside the
bash wrapper, which will propagate the revised scripts to other repos
as necessary.
We also fix a couple of things in gocross that didn't work on Windows:
we change the toolchain resolution code to use os.UserHomeDir instead
of directly referencing the HOME environment variable, and we fix a
bug in the way arguments were being passed into exec.Command on
non-Unix systems.
Updates https://github.com/tailscale/corp/issues/29940
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Add a Run all probes handler that executes all
probes except those that are continuous or the derpmap
probe.
This is leveraged by other tooling to confirm DERP
stability after a deploy.
Updates tailscale/corp#27370
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
fixestailscale/corp#31299
Fixes two issues:
getInterfaceIndex would occasionally race with netmon's state, returning
the cached default interface index after it had be changed by NWNetworkMonitor.
This had the potential to cause connections to bind to the prior default. The fix
here is to preferentially use the interface index provided by NWNetworkMonitor
preferentially.
When no interfaces are available, macOS will set the tunnel as the default
interface when an exit node is enabled, potentially causing getInterfaceIndex
to return utun's index. We now guard against this when taking the
defaultIdx path.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This pulls in a change from github.com/tailscale/QDK to verify code signing
when using QNAP_SIGNING_SCRIPT.
It also upgrades to the latest Google Cloud PKCS#11 library, and reorders
the Dockerfile to allow for more efficient future upgrades to the included QDK.
Updates tailscale/corp#23528
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Define the HardwareAttestionKey interface describing a platform-specific
hardware backed node identity attestation key. Clients will register the
key type implementations for their platform.
Updates tailscale/corp#31269
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
dnstype.Resolver adds a boolean UseWithExitNode that controls
whether the resolver should be used in tailscale exit node contexts
(not wireguard exit nodes). If UseWithExitNode resolvers are found,
they are installed as the global resolvers. If no UseWithExitNode resolvers
are found, the exit node resolver continues to be installed as the global
resolver. Split DNS Routes referencing UseWithExitNode resolvers are also
installed.
Updates #8237Fixestailscale/corp#30906Fixestailscale/corp#30907
Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
We already show a message in the menu itself, this just adds it to the
CLI output as well.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
This adds support for having every viewer type implement
jsonv2.MarshalerTo and jsonv2.UnmarshalerFrom.
This provides a significant boost in performance
as the json package no longer needs to validate
the entirety of the JSON value outputted by MarshalJSON,
nor does it need to identify the boundaries of a JSON value
in order to call UnmarshalJSON.
For deeply nested and recursive MarshalJSON or UnmarshalJSON calls,
this can improve runtime from O(N²) to O(N).
This still references "github.com/go-json-experiment/json"
instead of the experimental "encoding/json/v2" package
now available in Go 1.25 under goexperiment.jsonv2
so that code still builds without the experiment tag.
Of note, the "github.com/go-json-experiment/json" package
aliases the standard library under the right build conditions.
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Adds a setter for proxyFunc to allow macOS to pull defined
system proxies. Disallows overriding if proxyFunc is set via config.
Updates tailscale/corp#30668
Signed-off-by: Will Hannah <willh@tailscale.com>
This affects the 1.87.33 unstable release.
Updates #16842
Updates #15160
Change-Id: Ie6d1b2c094d1a6059fbd1023760567900f06e0ad
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Expected when Peer Relay'ing via self. These disco messages never get
sealed, and never leave the process.
Updates tailscale/corp#30527
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Update some logging to help future failures.
Improve test shutdown concurrency issues.
Fixes#16722
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Peer Relay is dependent on crypto routing, therefore crypto routing is
now mandatory.
Updates tailscale/corp#20732
Updates tailscale/corp#31083
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit also extends the updateRelayServersSet unit tests to cover
onNodeViewsUpdate.
Fixestailscale/corp#31080
Signed-off-by: Jordan Whited <jordan@tailscale.com>
One of these tests highlighted a Geneve encap bug, which is also fixed
in this commit.
looksLikeInitMsg was passed a packet post Geneve header stripping with
slice offsets that had not been updated to account for the stripping.
Updates tailscale/corp#30903
Signed-off-by: Jordan Whited <jordan@tailscale.com>
* Update installer.sh add FreeBSD ver 15
this should fix the issue on https://github.com/tailscale/tailscale/issues/16740
Signed-off-by: TheBigBear <471105+TheBigBear@users.noreply.github.com>
* scripts/installer.sh: small indentation change
Signed-off-by: Erisa A <erisa@tailscale.com>
Fixes#16740
---------
Signed-off-by: TheBigBear <471105+TheBigBear@users.noreply.github.com>
Signed-off-by: Erisa A <erisa@tailscale.com>
Co-authored-by: Erisa A <erisa@tailscale.com>
Pass a local.Client to systray.Run, so we can use the existing global
localClient in the cmd/tailscale CLI. Add socket flag to cmd/systray.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
Adds the eventbus to the router subsystem.
The event is currently only used on linux.
Also includes facilities to inject events into the bus.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This will start including the sytray app in unstable builds for Linux,
unless the `ts_omit_systray` build flag is specified.
If we decide not to include it in the v1.88 release, we can pull it
back out or restrict it to unstable builds.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
In Android, we are prompting the user to select a Taildrop directory when they first receive a Taildrop: we block writes on Taildrop dir selection. This means that we cannot use Dir inside managerOptions, since the http request would not get the new Taildrop extension. This PR removes, in the Android case, the reliance on m.opts.Dir, and instead has FileOps hold the correct directory.
This expands FileOps to be the Taildrop interface for all file system operations.
Updates tailscale/corp#29211
Signed-off-by: kari-ts <kari@tailscale.com>
restore tstest
* cmd/k8s-operator,k8s-operator: allow setting a `priorityClassName`
Fixes#16682
Signed-off-by: Lee Briggs <lee@leebriggs.co.uk>
* Update k8s-operator/apis/v1alpha1/types_proxyclass.go
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
Signed-off-by: Lee Briggs <jaxxstorm@users.noreply.github.com>
* run make kube-generate-all
Change-Id: I5f8f16694fdc181b048217b9f05ec2ee2aa04def
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
---------
Signed-off-by: Lee Briggs <lee@leebriggs.co.uk>
Signed-off-by: Lee Briggs <jaxxstorm@users.noreply.github.com>
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
The tsidp oidc-key.json ended up in the root directory
or home dir of the user process running it.
Update this to store it in a known location respecting
the TS_STATE_DIR and flagDir options.
Fixes#16734
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Also adds a test to kube/kubeclient to defend against the error type
returned by the client changing in future.
Fixestailscale/corp#30855
Change-Id: Id11d4295003e66ad5c29a687f1239333c21226a4
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Some systems have `sudo`, some have `su`. This tries both, increasing
the chance that we can run the file server as an unprivileged user.
Updates #14629
Signed-off-by: Percy Wegmann <percy@tailscale.com>
If a conn.Close call raced conn.ReadFromUDPAddrPort before it could
"register" itself as an active read, the conn.ReadFromUDPAddrPort would
never return.
This commit replaces all the activeRead and breakActiveReads machinery
with a channel. These constructs were only depended upon by
SetReadDeadline, and SetReadDeadline was unused.
Updates #16707
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit update the message for recommanding clear command after running serve for service.
Instead of a flag, we pass the service name as a parameter.
Fixestailscale/corp#30846
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
In the components where an event bus is already plumbed through, remove the
exceptions that allow it to be omitted, and update all the tests that relied on
those workarounds execute properly.
This change applies only to the places where we're already using the bus; it
does not enforce the existence of a bus in other components (yet),
Updates #15160
Change-Id: Iebb92243caba82b5eb420c49fc3e089a77454f65
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
jsonv2 now returns an error when you marshal or unmarshal a time.Duration
without an explicit format flag. This is an intentional, temporary choice until
the default [time.Duration] representation is decided (see golang/go#71631).
setting.Snapshot can hold time.Duration values inside a map[string]any,
so the jsonv2 update breaks marshaling. In this PR, we start using
a custom marshaler until that decision is made or golang/go#71664
lets us specify the format explicitly.
This fixes `tailscale syspolicy list` failing when KeyExpirationNotice
or any other time.Duration policy setting is configured.
Fixes#16683
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Ideally when we attempt to create a new port mapping, we should not return
without error when no mapping is available. We already log these cases as
unexpected, so this change is just to avoiding panicking dispatch on the
invalid result in those cases. We still separately need to fix the underlying
control flow.
Updates #16662
Change-Id: I51e8a116b922b49eda45e31cd27f6b89dd51abc8
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This occasionally panics waiting on a nil ctx, but was missed in the
previous PR because it's quite a rare flake as it needs to progress to a
specific point in the parser.
Updates #16678
Change-Id: Ifd36dfc915b153aede36b8ee39eff83750031f95
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
When kubectl starts an interactive attach session, it sends 2 resize
messages in quick succession. It seems that particularly in HTTP mode,
we often receive both of these WebSocket frames from the underlying
connection in a single read. However, our parser currently assumes 0-1
frames per read, and leaves the second frame in the read buffer until
the next read from the underlying connection. It doesn't take long after
that before we end up failing to skip a control message as we normally
should, and then we parse a control message as though it will have a
stream ID (part of the Kubernetes protocol) and error out.
Instead, we should keep parsing frames from the read buffer for as long
as we're able to parse complete frames, so this commit refactors the
messages parsing logic into a loop based on the contents of the read
buffer being non-empty.
k/k staging/src/k8s.io/kubectl/pkg/cmd/attach/attach.go for full
details of the resize messages.
There are at least a couple more multiple-frame read edge cases we
should handle, but this commit is very conservatively fixing a single
observed issue to make it a low-risk candidate for cherry picking.
Updates #13358
Change-Id: Iafb91ad1cbeed9c5231a1525d4563164fc1f002f
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This update introduces support for DNS records associated with ProxyGroup egress services, ensuring that the ClusterIP Service IP is used instead of Pod IPs.
Fixes#15945
Signed-off-by: Raj Singh <raj@tailscale.com>
Previously, we used a non-nil Location as an indicator that a peer is a Mullvad exit node.
However, this is not, or no longer, reliable, since regular exit nodes may also have a non-nil Location,
such as when traffic steering is enabled for a tailnet.
In this PR, we update the plaintext `tailscale status` output to omit only Mullvad exit nodes, rather than all
exit nodes with a non-nil Location. The JSON output remains unchanged and continues to include all peers.
Updates tailscale/corp#30614
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In #16625, I introduced a mechanism for sending the selected exit node
to Control via tailcfg.Hostinfo.ExitNodeID as part of the MapRequest.
@nickkhyl pointed out that LocalBackend.doSetHostinfoFilterServices
needs to be triggered in order to actually send this update. This
patch adds that command. It also prevents the client from sending
"auto:any" in that field, because that’s not a real exit node ID.
This patch also fills in some missing checks in TestConfigureExitNode.
Updates tailscale/corp#30536
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Update nixpkgs-unstable to include newer golang
to satisfy go.mod requirement of 1.24.4
Update vendor hash to current.
Updates #15015
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This commit adds a advertise subcommand for tailscale serve, that would declare the node
as a service proxy for a service. This command only adds the service to node's list of
advertised service, but doesn't modify the list of services currently advertised.
Fixestailscale/corp#28016
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
When a client selects a particular exit node, Control may use that as
a signal for deciding other routes.
This patch causes the client to report whenever the current exit node
changes, through tailcfg.Hostinfo.ExitNodeID. It relies on a properly
set ipn.Prefs.ExitNodeID, which should already be resolved by
`tailscale set`.
Updates tailscale/corp#30536
Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit reverts the key of Web field in ipn.ServiceConfig to use FQDN instead of service
name for the host part of HostPort. This change is because k8s operator already build base on
the assumption of the part being FQDN. We don't want to break the code with dependency.
Fixestailscale/corp#30695
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* Modifies the k8s-proxy to expose health check and metrics
endpoints on the Pod's IP.
* Moves cmd/containerboot/healthz.go and cmd/containerboot/metrics.go to
/kube to be shared with /k8s-proxy.
Updates #13358
Signed-off-by: David Bond <davidsbond93@gmail.com>
Updates k8s-proxy's config so its auth mode config matches that we set
in kube-apiserver ProxyGroups for consistency.
Updates #13358
Change-Id: I95e29cec6ded2dc7c6d2d03f968a25c822bc0e01
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
The Kubernetes API server proxy is getting the ability to serve on a
Tailscale Service instead of individual node names. Update the configure
kubeconfig sub-command to accept arguments that look like a Tailscale
Service. Note, we can't know for sure whether a peer is advertising a
Tailscale Service, we can only guess based on the ExtraRecords in the
netmap and that IP showing up in a peer's AllowedIPs.
Also adds an --http flag to allow targeting individual proxies that can
be adverting on http for their node name, and makes the command a bit
more forgiving on the range of inputs it accepts and how eager it is to
print the help text when the input is obviously wrong.
Updates #13358
Change-Id: Ica0509c6b2c707252a43d7c18b530ec1acf7508f
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This commit modifies the kubernetes operator's `DNSConfig` resource
with the addition of a new field at `nameserver.service.clusterIP`.
This field allows users to specify a static in-cluster IP address of
the nameserver when deployed.
Fixes#14305
Signed-off-by: David Bond <davidsbond93@gmail.com>
This function is behind a sync.Once so we should only see errors at
startup. In particular the error from `open` is useful to diagnose why
TPM might not be accessible.
Updates #15830
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Adds a new reconciler for ProxyGroups of type kube-apiserver that will
provision a Tailscale Service for each replica to advertise. Adds two
new condition types to the ProxyGroup, TailscaleServiceValid and
TailscaleServiceConfigured, to post updates on the state of that
reconciler in a way that's consistent with the service-pg reconciler.
The created Tailscale Service name is configurable via a new ProxyGroup
field spec.kubeAPISserver.ServiceName, which expects a string of the
form "svc:<dns-label>".
Lots of supporting changes were needed to implement this in a way that's
consistent with other operator workflows, including:
* Pulled containerboot's ensureServicesUnadvertised and certManager into
kube/ libraries to be shared with k8s-proxy. Use those in k8s-proxy to
aid Service cert sharing between replicas and graceful Service shutdown.
* For certManager, add an initial wait to the cert loop to wait until
the domain appears in the devices's netmap to avoid a guaranteed error
on the first issue attempt when it's quick to start.
* Made several methods in ingress-for-pg.go and svc-for-pg.go into
functions to share with the new reconciler
* Added a Resource struct to the owner refs stored in Tailscale Service
annotations to be able to distinguish between Ingress- and ProxyGroup-
based Services that need cleaning up in the Tailscale API.
* Added a ListVIPServices method to the internal tailscale client to aid
cleaning up orphaned Services
* Support for reading config from a kube Secret, and partial support for
config reloading, to prevent us having to force Pod restarts when
config changes.
* Fixed up the zap logger so it's possible to set debug log level.
Updates #13358
Change-Id: Ia9607441157dd91fb9b6ecbc318eecbef446e116
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This commit removes the advertise command for service. The advertising is now embedded into
serve command and unadvertising is moved to drain subcommand
Fixestailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: add clear subcommand for serve services
This commit adds a clear subcommand for serve command, to remove all config for a passed service.
This is a short cut for user to remove services after they drain a service. As an indipendent command
it would avoid accidently remove a service on typo.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* update regarding comments
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* log when clearing a non-existing service but not error
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
---------
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
The tpmrm0 is a kernel-managed version of tpm0 that multiplexes multiple
concurrent connections. The basic tpm0 can only be accessed by one
application at a time, which can be pretty unreliable.
Updates #15830
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
* cmd/tailscale/cli: add drain subCommand for serve
This commit adds the drain subcommand for serving services. After we merge advertise and serve service as one step,
we now need a way to unadvertise service and this is it.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* move runServeDrain and some update regarding pr comments
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* some code structure change
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
---------
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
Make it possible to dump the eventbus graph as JSON or DOT to both debug
and document what is communicated via the bus.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Package geo provides functionality to represent and process
geographical locations on a sphere. The main type, geo.Point,
represents a pair of latitude and longitude coordinates.
Updates tailscale/corp#29968
Signed-off-by: Simon Law <sfllaw@tailscale.com>
* cmd/tailscale/cli: Add service flag to serve command
This commit adds the service flag to serve command which allows serving a service and add the service
to the advertisedServices field in prefs (What advertise command does that will be removed later).
When adding proxies, TCP proxies and WEB proxies work the same way as normal serve, just under a
different DNSname. There is a services specific L3 serving mode called Tun, can be set via --tun flag.
Serving a service is always in --bg mode. If --bg is explicitly set t o false, an error message will
be sent out. The restriction on proxy target being localhost or 127.0.0.1 also applies to services.
When removing proxies, TCP proxies can be removed with type and port flag and off argument. Web proxies
can be removed with type, port, setPath flag and off argument. To align with normal serve, when setPath
is not set, all handler under the hostport will be removed. When flags are not set but off argument was
passed by user, it will be a noop. Removing all config for a service will be available later with a new
subcommand clear.
Updates tailscale/corp#22954
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: fix ai comments and fix a test
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: Add a test for addServiceToPrefs
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: fix comment
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* add dnsName in error message
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* change the cli input flag variable type
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* replace FindServiceConfig with map lookup
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* some code simplification and add asServiceName
This commit cotains code simplification for IsServingHTTPS, SetWebHandler, SetTCPForwarding
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* replace IsServiceName with tailcfg.AsServiceName
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* replace all assemble of host name for service with strings.Join
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: adjust parameter order and update output message
This commit updates the parameter order for IsTCPForwardingOnPort and SetWebHandler.
Also updated the message msgServiceIPNotAssigned to msgServiceWaitingApproval to adapt to
latest terminologies around services.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: flip bool condition
This commit fixes a previous bug added that throws error when serve funnel without service.
It should've been the opposite, which throws error when serve funnel with service.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: change parameter of IsTCPForwardingOnPort
This commit changes the dnsName string parameter for IsTCPForwardingOnPort to
svcName tailcfg.ServiceName. This change is made to reduce ambiguity when
a single service might have different dnsNames
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* ipn/ipnlocal: replace the key to webHandler for services
This commit changes the way we get the webhandler for vipServices. It used to use the host name
from request to find the webHandler, now everything targeting the vipService IP have the same
set of handlers. This commit also stores service:port instead of FQDN:port as the key in serviceConfig
for Web map.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: Updated use of service name.
This commit removes serviceName.IsEmpty and use direct comparison to instead. In legacy code, when an empty service
name needs to be passed, a new constant noService is passed. Removed redundant code for checking service name validity
and string method for serviceNameFlag.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: Update bgBoolFlag
This commit update field name, set and string method of bgBoolFlag to make code cleaner.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: remove isDefaultService output from srvTypeAndPortFromFlags
This commit removes the isDefaultService out put as it's no longer needed. Also deleted redundant code.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: remove unnessesary variable declare in messageForPort
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* replace bool output for AsServiceName with err
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: Replace DNSName with NoService if DNSname only used to identify service
This commit moves noService constant to tailcfg, updates AsServiceName to return tailcfg.NoService if the input
is not a valid service name. This commit also removes using the local DNSName as scvName parameter. When a function
is only using DNSName to identify if it's working with a service, the input in replaced with svcName and expect
caller to pass tailcfg.NoService if it's a local serve. This commit also replaces some use of Sprintf with
net.JoinHostPort for ipn.HostPort creation.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: Remove the returned error for AsServiceName
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* apply suggested code and comment
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* replace local dnsName in test with tailcfg.NoService
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/tailscale/cli: move noService back and use else where
The constant serves the purpose of provide readability for passing as a function parameter. It's
more meaningful comparing to a . It can just be an empty string in other places.
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* ipn: Make WebHandlerExists and RemoveTCPForwarding accept svcName
This commit replaces two functions' string input with svcName input since they only use the dnsName to
identify service. Also did some minor cleanups
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
---------
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
With auto exit nodes enabled, the client picks exit nodes from the
ones advertised in the network map. Usually, it picks the one with the
highest priority score, but when the top spot is tied, it used to pick
randomly. Then, once it made a selection, it would strongly prefer to
stick with that exit node. It wouldn’t even consider another exit node
unless the client was shutdown or the exit node went offline. This is
to prevent flapping, where a client constantly chooses a different
random exit node.
The major problem with this algorithm is that new exit nodes don’t get
selected as often as they should. In fact, they wouldn’t even move
over if a higher scoring exit node appeared.
Let’s say that you have an exit node and it’s overloaded. So you spin
up a new exit node, right beside your existing one, in the hopes that
the traffic will be split across them. But since the client had this
strong affinity, they stick with the exit node they know and love.
Using rendezvous hashing, we can have different clients spread
their selections equally across their top scoring exit nodes. When an
exit node shuts down, its clients will spread themselves evenly to
their other equal options. When an exit node starts, a proportional
number of clients will migrate to their new best option.
Read more: https://en.wikipedia.org/wiki/Rendezvous_hashing
The trade-off is that starting up a new exit node may cause some
clients to move over, interrupting their existing network connections.
So this change is only enabled for tailnets with `traffic-steering`
enabled.
Updates tailscale/corp#29966
Fixes#16551
Signed-off-by: Simon Law <sfllaw@tailscale.com>
So that conn.PeerAwareEndpoint is always evaluated per-packet, rather
than at least once per packet batch.
Updates tailscale/corp#30042
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This is a follow-up to #15351, which fixed the test for Linux but not for
Darwin, which stores its "true" executable in /usr/bin instead of /bin.
Try both paths when not running on Windows.
In addition, disable CGo in the integration test build, which was causing the
linker to fail. These tests do not need CGo, and it appears we had some version
skew with the base image on the runners.
In addition, in error cases the recover step of the permissions check was
spuriously panicking and masking the "real" failure reason. Don't do that check
when a command was not produced.
Updates #15350
Change-Id: Icd91517f45c90f7554310ebf1c888cdfd109f43a
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Socket read errors currently close the server, so we need to understand
when and why they occur.
Updates tailscale/corp#27502
Updates tailscale/corp#30118
Signed-off-by: Jordan Whited <jordan@tailscale.com>
@nickkyl added an peer.Online check to suggestExitNodeUsingDERP, so it
should also check when running suggestExitNodeUsingTrafficSteering.
Updates tailscale/corp#29966
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Thanks to @nickkhyl for pointing out that NetMap.Peers doesn’t get
incremental updates since the last full NetMap update. Instead, he
recommends using ipn/ipnlocal.nodeBackend.AppendMatchingPeers.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
A trusted peer relay path is always better than an untrusted direct or
peer relay path.
Updates tailscale/corp#30412
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This package promises more performance, but was never used.
The intent of the package is somewhat moot as "encoding/json"
in Go 1.25 (while under GOEXPERIMENT=jsonv2) has been
completely re-implemented using "encoding/json/v2"
such that unmarshal is dramatically faster.
Updates #cleanup
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
udpRelayEndpointReady used to write into the peerMap, which required
holding Conn.mu, but this changed in f9e7131.
Updates #cleanup
Signed-off-by: Jordan Whited <jordan@tailscale.com>
To write the init script.
And fix the JetKVM detection to work during early boot while the filesystem
and modules are still being loaded; it wasn't being detected on early boot
and then tailscaled was failing to start because it didn't know it was on JetKVM
and didn't modprobe tun.
Updates #16524
Change-Id: I0524ca3abd7ace68a69af96aab4175d32c07e116
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When `tailscale exit-node suggest` contacts the LocalAPI for a
suggested exit node, the client consults its netmap for peers that
contain the `suggest-exit-node` peercap. It currently uses a series of
heuristics to determine the exit node to suggest.
When the `traffic-steering` feature flag is enabled on its tailnet,
the client will defer to Control’s priority scores for a particular
peer. These scores, in `tailcfg.Hostinfo.Location.Priority`, were
historically only used for Mullvad exit nodes, but they have now been
extended to score any peer that could host a redundant resource.
Client capability version 119 is the earliest client that understands
these traffic steering scores. Control tells the client to switch to
rely on these scores by adding `tailcfg.NodeAttrTrafficSteering` to
its `AllCaps`.
Updates tailscale/corp#29966
Signed-off-by: Simon Law <sfllaw@tailscale.com>
In this PR, we make ExitNode.AllowOverride configurable as part of the Exit Node ADMX policy setting,
similarly to Always On w/ "Disconnect with reason" option.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Updates the output for "tailscale ping" to indicate if a peer relay was traversed, just like the output for DERP or direct connections.
Fixestailscale/corp#30034
Signed-off-by: Dylan Bargatze <dylan@tailscale.com>
To signal when a tailnet has the `traffic-steering` feature flag,
Control will send a `traffic-steering` NodeCapability in netmap’s
AllCaps.
This patch adds `tailcfg.NodeAttrTrafficSteering` so that it can be
used in the control plane. Future patches will implement the actual
steering mechanisms.
Updates tailscale/corp#29966
Signed-off-by: Simon Law <sfllaw@tailscale.com>
This commit modifies the k8s-operator and k8s-proxy to support passing down
the accept-routes configuration from the proxy class as a configuration value
read and used by the k8s-proxy when ran as a distinct container managed by
the operator.
Updates #13358
Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit modifies the k8s proxy application configuration to include a
new field named `ServerURL` which, when set, modifies
the tailscale coordination server used by the proxy. This works in the same
way as the operator and the proxies it deploys.
If unset, the default coordination server is used.
Updates https://github.com/tailscale/tailscale/issues/13358
Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit modifies the operator to detect the usage of k8s-apiserver
type proxy groups that wish to use the letsencrypt staging directory and
apply the appropriate environment variable to the statefulset it
produces.
Updates #13358
Signed-off-by: David Bond <davidsbond93@gmail.com>
Errors were mashalled without the correct newlines. Also, they could
generally be mashalled with more data, so an intermediate was introduced
to make them slightly nicer to look at.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
If the NodeAttrDisableRelayClient node attribute is set, ensures that a node cannot allocate endpoints on a UDP relay server itself, and cannot use newly-discovered paths (via disco/CallMeMaybeVia) that traverse a UDP relay server.
Fixestailscale/corp#30180
Signed-off-by: Dylan Bargatze <dylan@tailscale.com>
If the GUI receives a new exit node ID before the new netmap, it may treat the node as offline or invalid
if the previous netmap didn't include the peer at all, or if the peer was offline or not advertised as an exit node.
This may result in briefly issuing and dismissing a warning, or a similar issue, which isn't ideal.
In this PR, we change the operation order to send the new netmap to clients first before selecting the new exit node
and notifying them of the Exit Node change.
Updates tailscale/corp#30252 (an old issue discovered during testing this)
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We already check this for cases where ipn.Prefs.AutoExitNode is configured via syspolicy.
Configuring it directly through EditPrefs should behave the same, so we add a test for that as well.
Additionally, we clarify the implementation and future extensibility in (*LocalBackend).resolveAutoExitNodeLocked,
where the AutoExitNode is actually enforced.
Updates tailscale/corp#29969
Updates #cleanup
Signed-off-by: Nick Khyl <nickk@tailscale.com>
If the specified exit node string starts with "auto:" (i.e., can be parsed as an ipn.ExitNodeExpression),
we update ipn.Prefs.AutoExitNode instead of ipn.Prefs.ExitNodeID.
Fixes#16459
Signed-off-by: Nick Khyl <nickk@tailscale.com>
So it can be used from the CLI without importing ipnlocal.
While there, also remove isAutoExitNodeID, a wrapper around parseAutoExitNodeID
that's no longer used.
Updates tailscale/corp#29969
Updates #cleanup
Signed-off-by: Nick Khyl <nickk@tailscale.com>
The observed generation was set to always 0 in #16429, but this had the
knock-on effect of other controllers considering ProxyGroups never ready
because the observed generation is never up to date in
proxyGroupCondition. Make sure the ProxyGroupAvailable function does not
requires the observed generation to be up to date, and add testing
coverage to catch regressions.
Updates #16327
Change-Id: I42f50ad47dd81cc2d3c3ce2cd7b252160bb58e40
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Adds a new k8s-proxy command to convert operator's in-process proxy to
a separately deployable type of ProxyGroup: kube-apiserver. k8s-proxy
reads in a new config file written by the operator, modelled on tailscaled's
conffile but with some modifications to ensure multiple versions of the
config can co-exist within a file. This should make it much easier to
support reading that config file from a Kube Secret with a stable file name.
To avoid needing to give the operator ClusterRole{,Binding} permissions,
the helm chart now optionally deploys a new static ServiceAccount for
the API Server proxy to use if in auth mode.
Proxies deployed by kube-apiserver ProxyGroups currently work the same as
the operator's in-process proxy. They do not yet leverage Tailscale Services
for presenting a single HA DNS name.
Updates #13358
Change-Id: Ib6ead69b2173c5e1929f3c13fb48a9a5362195d8
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Based on feedback that it wasn't clear what the user is meant to do with
the output of the last command, clarify that it's an optional command to
explore what got created.
Updates #13427
Change-Id: Iff64ec6d02dc04bf4bbebf415d7ed1a44e7dd658
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
When running `tailscale exit-node list`, an empty city or country name
should be displayed as a hyphen "-". However, this only happened when
there was no location at all. If a node provides a Hostinfo.Location,
then the list would display exactly what was provided.
This patch changes the listing so that empty cities and countries will
either render the provided name or "-".
Fixes#16500
Signed-off-by: Simon Law <sfllaw@tailscale.com>
When the policy setting is enabled, it allows users to override the exit node enforced by the ExitNodeID
or ExitNodeIP policy. It's primarily intended for use when ExitNodeID is set to auto:any, but it can also
be used with specific exit nodes. It does not allow disabling exit node usage entirely.
Once the exit node policy is overridden, it will not be enforced again until the policy changes,
the user connects or disconnects Tailscale, switches profiles, or disables the override.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Now that applySysPolicy is only called by (*LocalBackend).reconcilePrefsLocked,
we can make it a method to avoid passing state via parameters and to support
future extensibility.
Also factor out exit node-specific logic into applyExitNodeSysPolicyLocked.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Now that resolveExitNodeInPrefsLocked is the only caller of setExitNodeID,
and setExitNodeID is the only caller of resolveExitNodeIP, we can restructure
the code with resolveExitNodeInPrefsLocked now calling both
resolveAutoExitNodeLocked and resolveExitNodeIPLocked directly.
This prepares for factoring out resolveAutoExitNodeLocked and related
auto-exit-node logic into an ipnext extension in a future commit.
While there, we also update exit node by IP lookup to use (*nodeBackend).NodeByAddr
and (*nodeBackend).NodeByID instead of iterating over all peers in the most recent netmap.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this PR, we start passing a LocalAPI actor to (*LocalBackend).Logout to make it subject
to the same access check as disconnects made via tailscale down or the GUI.
We then update the CLI to allow `tailscale logout` to accept a reason, similar to `tailscale down`.
Updates tailscale/corp#26249
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Since a [*lazyEndpoint] makes wireguard-go responsible for peer ID, but
wireguard-go may not yet be configured for said peer, we need a JIT hook
around initiation message reception to call what is usually called from
an [*endpoint].
Updates tailscale/corp#30042
Signed-off-by: Jordan Whited <jordan@tailscale.com>
We can't relay a packet received over the IPv4 socket back out the same
socket if destined to an IPv6 address, and vice versa.
Updates tailscale/corp#30206
Signed-off-by: Jordan Whited <jordan@tailscale.com>
We extract checkEditPrefsAccessLocked, adjustEditPrefsLocked, and onEditPrefsLocked from the EditPrefs
execution path, defining when each step is performed and what behavior is allowed at each stage.
Currently, this is primarily used to support Always On mode, to handle the Exit Node enablement toggle,
and to report prefs edit metrics.
We then use it to enforce Exit Node policy settings by preventing users from setting an exit node
and making EditPrefs return an error when an exit node is restricted by policy. This enforcement is also
extended to the Exit Node toggle.
These changes prepare for supporting Exit Node overrides when permitted by policy and preventing logout
while Always On mode is enabled.
In the future, implementation of these methods can be delegated to ipnext extensions via the feature hooks.
Updates tailscale/corp#29969
Updates tailscale/corp#26249
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We have several places where we call applySysPolicy, suggestExitNodeLocked, and setExitNodeID.
While there are cases where we want to resolve the exit node specifically, such as when network
conditions change or a new netmap is received, we typically need to perform all three steps.
For example, enforcing policy settings may enable auto exit nodes or set an ExitNodeIP,
which in turn requires picking a suggested exit node or resolving the IP to an ID, respectively.
In this PR, we introduce (*LocalBackend).resolveExitNodeInPrefsLocked and (*LocalBackend).reconcilePrefsLocked,
with the latter calling both applySysPolicy and resolveExitNodeInPrefsLocked.
Consolidating these steps into a single extensibility point would also make it easier to support
future hooks registered by ipnext extensions.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this PR, we update setExitNodeID to retain the existing exit node if auto exit node is enabled,
the current exit node is allowed by policy, and no suggested exit node is available yet.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Now that (*LocalBackend).suggestExitNodeLocked is never called with a non-current netmap
(the netMap parameter is always nil, indicating that the current netmap should be used),
we can remove the unused parameter.
Additionally, instead of suggestExitNodeLocked passing the most recent full netmap to suggestExitNode,
we now pass the current nodeBackend so it can access peers with delta updates applied.
Finally, with that fixed, we no longer need to skip TestUpdateNetmapDeltaAutoExitNode.
Updates tailscale/corp#29969
Fixes#16455
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this PR, we add (*LocalBackend).RefreshExitNode which determines which exit node
to use based on the current prefs and netmap and switches to it if needed. It supports
both scenarios when an exit node is specified by IP (rather than ID) and needs to be resolved
once the netmap is ready as well as auto exit nodes.
We then use it in (*LocalBackend).SetControlClientStatus when the netmap changes,
and wherever (*LocalBackend).pickNewAutoExitNode was previously used.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
TCP connections are two unidirectional data streams, and if one of these
streams closes, we should not assume the other half is closed as well.
For example, if an HTTP client closes its write half of the connection
early, it may still be expecting to receive data on its read half, so we
should keep the server -> client half of the connection open, while
terminating the client -> server half.
Fixestailscale/corp#29837.
Signed-off-by: Naman Sood <mail@nsood.in>
These were flipped. DstIP() and DstIPBytes() are used internally by
wireguard-go as part of a handshake DoS mitigation strategy.
Updates tailscale/corp#20732
Updates tailscale/corp#30042
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Just make [relayManager] always handle it, there's no benefit to
checking bestAddr's.
Also, remove passing of disco.Pong to [relayManager] in
endpoint.handlePongConnLocked(), which is redundant with the callsite in
Conn.handleDiscoMessage(). Conn.handleDiscoMessage() already passes to
[relayManager] if the txID us not known to any [*endpoint].
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
A lazyEndpoint may end up on this TX codepath when wireguard-go is
deemed "under load" and ends up transmitting a cookie reply using the
received conn.Endpoint.
Updates tailscale/corp#20732
Updates tailscale/corp#30042
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit modifies the k8s operator to allow for customisation of the ingress class name
via a new `OPERATOR_INGRESS_CLASS_NAME` environment variable. For backwards compatibility,
this defaults to `tailscale`.
When using helm, a new `ingress.name` value is provided that will set this environment variable
and modify the name of the deployed `IngressClass` resource.
Fixes https://github.com/tailscale/tailscale/issues/16248
Signed-off-by: David Bond <davidsbond93@gmail.com>
Refactors setting status into its own top-level function to make it
easier to ensure we _always_ set the status if it's changed on every
reconcile. Previously, it was possible to have stale status if some
earlier part of the provision logic failed.
Updates #16327
Change-Id: Idab0cfc15ae426cf6914a82f0d37a5cc7845236b
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Inverts the nodeAttrs related to UDP relay client/server enablement to disablement, and fixes up the corresponding logic that uses them. Also updates the doc comments on both nodeAttrs.
Fixestailscale/corp#30024
Signed-off-by: Dylan Bargatze <dylan@tailscale.com>
This commit modifies the operator helm chart values to bring the newly
added `loginServer` field to the top level. We felt as though it was a bit
confusing to be at the `operatorConfig` level as this value modifies the
behaviour or the operator, api server & all resources that the operator
manages.
Updates https://github.com/tailscale/corp/issues/29847
Signed-off-by: David Bond <davidsbond93@gmail.com>
With this change, policy enforcement and exit node resolution can happen in separate steps,
since enforcement no longer depends on resolving the suggested exit node. This keeps policy
enforcement synchronous (e.g., when switching profiles), while allowing exit node resolution
to be asynchronous on netmap updates, link changes, etc.
Additionally, the new preference will be used to let GUIs and CLIs switch back to "auto" mode
after a manual exit node override, which is necessary for tailscale/corp#29969.
Updates tailscale/corp#29969
Updates #16459
Signed-off-by: Nick Khyl <nickk@tailscale.com>
TestSetControlClientStatusAutoExitNode is broken similarly to TestUpdateNetmapDeltaAutoExitNode
as suggestExitNode didn't previously check the online status of exit nodes, and similarly to the other test
it succeeded because the test itself is also broken.
However, it is easier to fix as it sends out a full netmap update rather than a delta peer update,
so it doesn't depend on the same refactoring as TestSetControlClientStatusAutoExitNode.
Updates #16455
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
suggestExitNode never checks whether an exit node candidate is online.
It also accepts a full netmap, which doesn't include changes from delta updates.
The test can't work correctly until both issues are fixed.
Previously, it passed only because the test itself is flawed.
It doesn't succeed because the currently selected node goes offline and a new one is chosen.
Instead, it succeeds because lastSuggestedExitNode is incorrect, and suggestExitNode picks
the correct node the first time it runs, based on the DERP map and the netcheck report.
The node in exitNodeIDWant just happens to be the optimal choice.
Fixing SuggestExitNode requires refactoring its callers first, which in turn reveals the flawed test,
as suggestExitNode ends up being called slightly earlier.
In this PR, we update the test to correctly fail due to existing bugs in SuggestExitNode,
and temporarily skip it until those issues are addressed in a future commit.
Updates #16455
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
(*profileManager).CurrentPrefs() is always valid. Additionally, there's no value in cloning
and passing the full ipn.Prefs when editing preferences. Instead, ipn.MaskedPrefs should
only have ExitNodeID set.
Updates tailscale/corp#29969
Signed-off-by: Nick Khyl <nickk@tailscale.com>
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>
When dialed with just an URL and no node, the recent proxy fixes caused
a regression where there was no TLS server name being included.
Updates #16222
Updates #16223
Signed-off-by: James Tucker <james@tailscale.com>
Co-Authored-by: Jordan Whited <jwhited@tailscale.com>
This commit modifies the kubernetes operator to allow for customisation of the tailscale
login url. This provides some data locality for people that want to configure it.
This value is set in the `loginServer` helm value and is propagated down to all resources
managed by the operator. The only exception to this is recorder nodes, where additional
changes are required to support modifying the url.
Updates https://github.com/tailscale/corp/issues/29847
Signed-off-by: David Bond <davidsbond93@gmail.com>
Cryptokey Routing identification is now required to set an [epAddr] into
the peerMap for Geneve-encapsulated [epAddr]s.
Updates tailscale/corp#27502
Updates tailscale/corp#29422
Updates tailscale/corp#30042
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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>
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>
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>
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>
Changes to our src/address family can trigger blackholes.
This commit also adds a missing set of trustBestAddrUntil when setting
a UDP relay path as bestAddr.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
* cmd/k8s-operator: ProxyClass annotation for Services and Ingresses
Previously, the ProxyClass could only be configured for Services and
Ingresses via a Label. This adds the ability to set it via an
Annotation, but prioritizes the Label if both a Label and Annotation are
set.
Updates #14323
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
* Update cmd/k8s-operator/operator.go
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
Signed-off-by: Tom Meadows <tom@tmlabs.co.uk>
* Update cmd/k8s-operator/operator.go
Signed-off-by: Tom Meadows <tom@tmlabs.co.uk>
* cmd/k8s-operator: ProxyClass annotation for Services and Ingresses
Previously, the ProxyClass could only be configured for Services and
Ingresses via a Label. This adds the ability to set it via an
Annotation, but prioritizes the Label if both a Label and Annotation are
set.
Updates #14323
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
---------
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Signed-off-by: Tom Meadows <tom@tmlabs.co.uk>
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
Replace the existing systray_start counter metrics with a
systray_running gauge metrics.
This also adds an IncrementGauge method to local client to parallel
IncrementCounter. The LocalAPI handler supports both, we've just never
added a client method for gauges.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
The server-side code already does e.g. "nodeid:%d" instead of "%x"
and as a result we have to second guess a lot of identifiers that could
be hex or decimal.
This stops the bleeding and means in a year and change we'll stop
seeing the hex forms.
Updates tailscale/corp#29827
Change-Id: Ie5785a07fc32631f7c949348d3453538ab170e6d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Otherwise we can end up mirroring packets to them forever. We may
eventually want to relax this to direct paths as well, but start with
UDP relay paths, which have a higher chance of becoming untrusted and
never working again, to be conservative.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
We dropped the idea of the Experimental release stage in
tailscale/tailscale-www#7697, in favour of Community Projects.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
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>
This was previously hooked around direct UDP path discovery /
CallMeMaybe transmission, and related conditions. Now it is subject to
relay-specific considerations.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Previously, the operator checked the ProxyGroup status fields for
information on how many of the proxies had successfully authed. Use
their state Secrets instead as a more reliable source of truth.
containerboot has written device_fqdn and device_ips keys to the
state Secret since inception, and pod_uid since 1.78.0, so there's
no need to use the API for that data. Read it from the state Secret
for consistency. However, to ensure we don't read data from a
previous run of containerboot, make sure we reset containerboot's
state keys on startup.
One other knock-on effect of that is ProxyGroups can briefly be
marked not Ready while a Pod is restarting. Introduce a new
ProxyGroupAvailable condition to more accurately reflect
when downstream controllers can implement flows that rely on a
ProxyGroup having at least 1 proxy Pod running.
Fixes#16327
Change-Id: I026c18e9d23e87109a471a87b8e4fb6271716a66
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Relay handshakes may now occur multiple times over the lifetime of a
relay server endpoint. Handshake messages now include a handshake
generation, which is client specified, as a means to trigger safe
challenge reset server-side.
Relay servers continue to enforce challenge values as single use. They
will only send a given value once, in reply to the first arriving bind
message for a handshake generation.
VNI has been added to the handshake messages, and we expect the outer
Geneve header value to match the sealed value upon reception.
Remote peer disco pub key is now also included in handshake messages,
and it must match the receiver's expectation for the remote,
participating party.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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>
GitHub used to recommend the tibdex/github-app-token GitHub Action
until they wrote their own actions/create-github-app-token.
This patch replaces the use of the third-party action with the
official one.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
go(1) repsects GOROOT if set, but tool/go / gocross-wrapper.sh are explicitly intending to use our toolchain. We don't need to set GOROOT, just unset it, and then go(1) handles the rest.
Updates tailscale/corp#26717
Signed-off-by: James Tucker <james@tailscale.com>
For any changes that involve DERP, automatically add the
@tailscale/dataplane team as a reviewer.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
Premature cancellation was preventing the work from ever being cleaned
up in runLoop().
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
SSH was disabled in #10538
Exit node was disabled in #13726
This enables ssh and exit-node options in case of Home Assistant.
Fixes#15552
Signed-off-by: Laszlo Magyar <lmagyar1973@gmail.com>
This commit adds a NOTES.txt to the operator helm chart that will be written to the
terminal upon successful installation of the operator.
It includes a small list of knowledgebase articles with possible next steps for
the actor that installed the operator to the cluster. It also provides possible
commands to use for explaining the custom resources.
Fixes#13427
Signed-off-by: David Bond <davidsbond93@gmail.com>
Instead of every module having to come up with a set of test methods for
the event bus, this handful of test helpers hides a lot of the needed
setup for the testing of the event bus.
The tests in portmapper is also ported over to the new helpers.
Updates #15160
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
20.04 is no longer supported.
This pulls in changes to the QDK package that were required to make build succeed on 24.04.
Updates https://github.com/tailscale/corp/issues/29849
Signed-off-by: Percy Wegmann <percy@tailscale.com>
After the switch to 24.04, unsigned packages did not build correctly (came out as only a few KBs).
Fixestailscale/tailscale-qpkg#148
Signed-off-by: Percy Wegmann <percy@tailscale.com>
If we acted as the allocator we are responsible for signaling it to the
remote peer in a CallMeMaybeVia message over DERP.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
udprelay.Server is lazily initialized when the first request is received
over peerAPI. These early requests have a high chance of failure until
the first address discovery cycle has completed.
Return an ErrServerNotReady error until the first address discovery
cycle has completed, and plumb retry handling for this error all the
way back to the client in relayManager.
relayManager can now retry after a few seconds instead of waiting for
the next path discovery cycle, which could take another minute or
longer.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Any return underneath this select case must belong to a type switch case.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This tweaks the just-added ./tool/go.{cmd,ps1} port of ./tool/go for
Windows.
Otherwise in Windows Terminal in Powershell, running just ".\tool\go"
picks up go.ps1 before go.cmd, which means execution gets denied
without the cmd script's -ExecutionPolicy Bypass part letting it work.
This makes it work in both cmd.exe and in Powershell.
Updates tailscale/corp#28679
Change-Id: Iaf628a9fd6cb95670633b2dbdb635dfb8afaa006
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
go.cmd lets you run just "./tool/go" on Windows the same as Linux/Darwin.
The batch script (go.md) then just invokes PowerShell which is more
powerful than batch.
I wanted this while debugging Windows CI performance by reproducing slow
tests on my local Windows laptop.
Updates tailscale/corp#28679
Change-Id: I6e520968da3cef3032091c1c4f4237f663cefcab
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It's one of the slower ones, so split it up into chunks.
Updates tailscale/corp#28679
Change-Id: I16a5ba667678bf238c84417a51dda61baefbecf7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Proxies know how to reload configfile on changes since 1.80, which
is going to be the earliest supported proxy version with 1.84 operator,
so remove the mechanism that was updating configfile hash to force
proxy Pod restarts on config changes.
Updates #13032
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
I earlier thought this saved a second of CPU even on a fast machine,
but I think when I was previously measuring, I still had a 4096 bit
RSA key being generated in the code I was measuring.
Measuring again for this, it's plenty fast.
Prep for using this package more, for derp, etc.
Updates #16315
Change-Id: I4c9008efa9aa88a3d65409d6ffd7b3807f4d75e9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This reverts commit 6a93b17c8c.
The reverted commit added more complexity than it was worth at the
current stage. Handling delta CapVer changes requires extensive changes
to relayManager datastructures in order to also support delta updates of
relay servers.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
If you had HTTPS_PROXY=https://some-valid-cert.example.com running a
CONNECT proxy, we should've been able to do a TLS CONNECT request to
e.g. controlplane.tailscale.com:443 through that, and I'm pretty sure
it used to work, but refactorings and lack of integration tests made
it regress.
It probably regressed when we added the baked-in LetsEncrypt root cert
validation fallback code, which was testing against the wrong hostname
(the ultimate one, not the one which we were being asked to validate)
Fixes#16222
Change-Id: If014e395f830e2f87f056f588edacad5c15e91bc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Resolver.PreferGo didn't used to work on Windows.
It was fixed in 2022, though. (https://github.com/golang/go/issues/33097)
Updates #5161
Change-Id: I4e1aeff220ebd6adc8a14f781664fa6a2068b48c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This patch contains the following cleanups:
1. Simplify `ffcli.Command` definitions;
2. Word-wrap help text, consistent with other commands;
3. `tailscale dns --help` usage makes subcommand usage more obvious;
4. `tailscale dns query --help` describes DNS record types.
Updates #cleanup
Signed-off-by: Simon Law <sfllaw@tailscale.com>
We aim to make the tsgo directories be read-only mounts on builders.
But gocross was previously writing within the ~/.cache/tsgo/$HASH/
directories to make the synthetic GOROOT directories.
This moves them to ~/.cache/tsgoroot/$HASH/ instead.
Updates tailscale/corp#28679
Updates tailscale/corp#26717
Change-Id: I0d17730bbdce3d6374e79d49486826575d4690af
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The caller of client.RunWatchConnectionLoop may need to be
aware of errors that occur within loop. Add a channel
that notifies of errors to the caller to allow for
decisions to be make as to the state of the client.
Updates tailscale/corp#25756
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Make the OS-specific staticcheck jobs only test stuff that's specialized
for that OS. Do that using a new ./tool/listpkgs program that's a fancy
'go list' with more filtering flags.
Updates tailscale/corp#28679
Change-Id: I790be2e3a0b42b105bd39f68c4b20e217a26de60
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Tests that go mod version matches ./tool/go version.
Mismatched versions result in incosistent Go versions being used i.e.
in CI jobs as the version in go.mod is used to determine what Go version
Github actions pull in.
Updates #16283
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
gocross is not needed like it used to be, now that Go does
version stamping itself.
We keep it for the xcode and Windows builds for now.
This simplifies things in the build, especially with upcoming build
system updates.
Updates tailscale/corp#28679
Updates tailscale/corp#26717
Change-Id: Ib4bebe6f50f3b9c3d6cd27323fca603e3dfb43cc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If natc is running on a host with tailscale using `--accept-dns=true`
then a DNS loop can occur. Provide a flag for some specific DNS
upstreams for natc to use instead, to overcome such situations.
Updates #14667
Signed-off-by: James Tucker <james@tailscale.com>
eventbus.Publish() calls newPublisher(), which in turn invokes (*Client).addPublisher().
That method adds the new publisher to c.pub, so we don’t need to add it again in eventbus.Publish.
Updates #cleanup
Signed-off-by: Nick Khyl <nickk@tailscale.com>
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>
Ensure that if the ProxyGroup for HA Ingress changes, the TLS Secret
and Role and RoleBinding that allow proxies to read/write to it are
updated.
Fixes#16259
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
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>
This means the caller does not have to remember to close the reader, and avoids
having to duplicate the logic to decode JSON into events.
Updates #15160
Change-Id: I20186fabb02f72522f61d5908c4cc80b86b8936b
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Record dropped packets as soon as they time out, rather than after tx
record queues spill over, this will more accurately capture small
amounts of packet loss in a timely fashion.
Updates tailscale/corp#24522
Signed-off-by: James Tucker <james@tailscale.com>
The first packet fragment guard had an additional guard clause that was
incorrectly comparing a length in bytes to a length in octets, and was
also comparing what should have been an entire IPv4 through transport
header length to a subprotocol payload length. The subprotocol header
size guards were otherwise protecting against short transport headers,
as is the conservative non-first fragment minimum offset size. Add an
explicit disallowing of fragmentation for TSMP for the avoidance of
doubt.
Updates #cleanup
Updates #5727
Signed-off-by: James Tucker <james@tailscale.com>
During a short period of packet loss, a TCP connection to the home DERP
may be maintained. If no other regions emerge as winners, such as when
all regions but one are avoided/disallowed as candidates, ensure that
the current home region, if still active, is not dropped as the
preferred region until it has failed two keepalives.
Relatedly apply avoid and no measure no home to ICMP and HTTP checks as
intended.
Updates tailscale/corp#12894
Updates tailscale/corp#29491
Signed-off-by: James Tucker <james@tailscale.com>
The relay server now fetches IPs from local interfaces and external
perspective IP:port's via netcheck (STUN).
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Which can make operating the service more convenient.
It makes sense to put the cluster state with this if specified, so
rearrange the logic to handle that.
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
This enables us to mark nodes as relay capable or not. We don't actually
do that yet, as we haven't established a relay CapVer.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Add mesh key support to derpprobe for
probing derpers with verify set to true.
Move MeshKey checking to central point for code reuse.
Fix a bad error fmt msg.
Fixestailscale/corp#27294Fixestailscale/corp#25756
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
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>
It might complete, interrupting it reduces the chances of establishing a
relay path.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This is simply for consistency with relayManagerInputEvent(), which
should be the sole launcher of runLoop().
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
relayManager can now hand endpoint a relay epAddr for it to consider
as bestAddr.
endpoint and Conn disco ping/pong handling are now VNI-aware.
Updates tailscale/corp#27502
Updates tailscale/corp#29422
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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.
Fixestailscale/corp#29219
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
This commit adds a new type to magicsock, epAddr, which largely ends up
replacing netip.AddrPort in packet I/O paths throughout, enabling
Geneve encapsulation over UDP awareness.
The conn.ReceiveFunc for UDP has been revamped to fix and more clearly
distinguish the different classes of packets we expect to receive: naked
STUN binding messages, naked disco, naked WireGuard, Geneve-encapsulated
disco, and Geneve-encapsulated WireGuard.
Prior to this commit, STUN matching logic in the RX path could swallow
a naked WireGuard packet if the keypair index, which is randomly
generated, happened to overlap with a subset of the STUN magic cookie.
Updates tailscale/corp#27502
Updates tailscale/corp#29326
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Fragmented datagrams would be processed instead of being dumped right
away. In reality, thse datagrams would be dropped anyway later so there
should functionally not be any change. Additionally, the feature is off
by default.
Closes#16203
Signed-off-by: Claus Lensbøl <claus@tailscale.com>
Also add a trailing newline to error banners so that SSH client messages don't print on the same line.
Updates tailscale/corp#29138
Signed-off-by: Percy Wegmann <percy@tailscale.com>
- Add tsidp target to build_docker.sh for standard Tailscale image builds
- Add publishdevtsidp Makefile target for development image publishing
- Remove Dockerfile, using standard build process
- Include tsidp in depaware dependency tracking
- Update README with comprehensive Docker usage examples
This enables tsidp to be built and published like other Tailscale components
(tailscale/tailscale, tailscale/k8s-operator, tailscale/k8s-nameserver).
Fixes#16077
Signed-off-by: Raj Singh <raj@tailscale.com>
Our conn.Bind implementation is updated to make Send() offset-aware for
future VXLAN/Geneve encapsulation support.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Fix CompareAndSwap in the edge-case where
the underlying sync.AtomicValue is uninitialized
(i.e., Store was never called) and
the oldV is the zero value,
then perform CompareAndSwap with any(nil).
Also, document that T must be comparable.
This is a pre-existing restriction.
Fixes#16135
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
In 1.84 we made 'tailscale set'/'tailscale up' error out if duplicate
command line flags are passed.
This broke some container configurations as we have two env vars that
can be used to set --accept-dns flag:
- TS_ACCEPT_DNS- specifically for --accept-dns
- TS_EXTRA_ARGS- accepts any arbitrary 'tailscale up'/'tailscale set'
flag.
We default TS_ACCEPT_DNS to false (to make the container behaviour more
declarative), which with the new restrictive CLI behaviour resulted in
failure for users who had set --accept-dns via TS_EXTRA_ARGS as the flag would be
provided twice.
This PR re-instates the previous behaviour by checking if TS_EXTRA_ARGS
contains --accept-dns flag and if so using its value to override TS_ACCEPT_DNS.
Updates tailscale/tailscale#16108
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This adds SmallSet.SoleElement, which I need in another repo for
efficiency. I added tests, but those tests failed because Add(1) +
Add(1) was promoting the first Add's sole element to a map of one
item. So fix that, and add more tests.
Updates tailscale/corp#29093
Change-Id: Iadd5ad08afe39721ee5449343095e389214d8389
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Using WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG on Windows versions older than Windows 10 1703 (build 15063)
is not supported and causes WinHttpGetProxyForUrl to fail with ERROR_INVALID_PARAMETER. This results in failures
reaching the control on environments where a proxy is required.
We use wingoes version detection to conditionally set the WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG flag
on Windows builds greater than 15063.
While there, we also update proxy detection to use WINHTTP_AUTO_DETECT_TYPE_DNS_A, as DNS-based proxy discovery
might be required with Active Directory and in certain other environments.
Updates tailscale/corp#29168
Fixes#879
Signed-off-by: Nick Khyl <nickk@tailscale.com>
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>
As note in the comment, it now being more than six months since this was
deprecated and there being no (further) uses of the old pattern in our internal
services, let's drop the migrator.
Updates #cleanup
Change-Id: Ie4fb9518b2ca04a9b361e09c51cbbacf1e2633a8
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
fixestailscale/corp#25612
We now keep track of any dns configurations which we could not
compile. This gives RecompileDNSConfig a configuration to
attempt to recompile and apply when the OS pokes us to indicate
that the interface dns servers have changed/updated. The manager config
will remain unset until we have the required information to compile
it correctly which should eliminate the problematic SERVFAIL
responses (especially on macOS 15).
This also removes the missingUpstreamRecovery func in the forwarder
which is no longer required now that we have proper error handling
and recovery manager and the client.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
relayManager is responsible for disco ping/pong probing of relay
endpoints once a handshake is complete.
Future work will enable relayManager to set a relay endpoint as the best
UDP path on an endpoint if appropriate.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Fix the wireshark lua dissector to support 0 bit position
and not throw modulo div by 0 errors.
Add new disco frame types to the decoder.
Updates tailscale/corp#29036
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Add comprehensive web interface at ui for managing OIDC clients, similar to tsrecorder's design. Features include list view, create/edit forms with validation, client secret management, delete functionality with confirmation dialogs, responsive design, and restricted tailnet access only.
Fixes#16067
Signed-off-by: Raj Singh <raj@tailscale.com>
In accordance with the OIDC/OAuth 2.0 protocol, do not send an empty
refresh_token and instead omit the field when empty.
Fixes https://github.com/tailscale/tailscale/issues/16073
Signed-off-by: Tim Klocke <taaem@mailbox.org>
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>
Validate that any tags that users have specified via tailscale.com/tags
annotation are valid Tailscale ACL tags.
Validate that no more than one HA Tailscale Kubernetes Services in a single cluster refer
to the same Tailscale Service.
Updates tailscale/tailscale#16054
Updates tailscale/tailscale#16035
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
As noted in #16048, the ./ssh/tailssh package failed to build on
Android, because GOOS=android also matches the "linux" build
tag. Exclude Android like iOS is excluded from macOS (darwin).
This now works:
$ GOOS=android go install ./ipn/ipnlocal ./ssh/tailssh
The original PR at #16048 is also fine, but this stops the problem
earlier.
Updates #16048
Change-Id: Ie4a6f6966a012e510c9cb11dd0d1fa88c48fac37
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
RELNOTE=Fix CSRF errors in the client Web UI
Replace gorilla/csrf with a Sec-Fetch-Site based CSRF protection
middleware that falls back to comparing the Host & Origin headers if no
SFS value is passed by the client.
Add an -origin override to the web CLI that allows callers to specify
the origin at which the web UI will be available if it is hosted behind
a reverse proxy or within another application via CGI.
Updates #14872
Updates #15065
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
To authenticate mesh keys, the DERP servers used a simple == comparison,
which is susceptible to a side channel timing attack.
By extracting the mesh key for a DERP server, an attacker could DoS it
by forcing disconnects using derp.Client.ClosePeer. They could also
enumerate the public Wireguard keys, IP addresses and ports for nodes
connected to that DERP server.
DERP servers configured without mesh keys deny all such requests.
This patch also extracts the mesh key logic into key.DERPMesh, to
prevent this from happening again.
Security bulletin: https://tailscale.com/security-bulletins#ts-2025-003Fixestailscale/corp#28720
Signed-off-by: Simon Law <sfllaw@tailscale.com>
* 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>
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>
Create FileOps for calling platform-specific file operations such as SAF APIs in Taildrop
Update taildrop.PutFile to support both traditional and SAF modes
Updates tailscale/tailscale#15263
Signed-off-by: kari-ts <kari@tailscale.com>
Use of the httptest client doesn't render header ordering
as expected.
Use http.DefaultClient for the test to ensure that
the header ordering test is valid.
Updates tailscale/corp#27370
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
This type improves code clarity and reduces the chance of heap alloc as
we pass it as a non-pointer. VNI being a 3-byte value enables us to
track set vs unset via the reserved/unused byte.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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>
The same message was used for "up" and "down" permission failures, but
"set" works better for both. Suggesting "up --operator" for a "down"
permission failure was confusing.
It's not like the latter command works in one shot anyway.
Fixes#16008
Change-Id: I6e4225ef06ce2d8e19c40bece8104e254c2aa525
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This fixes the implementation and test from #15208 which apparently
never worked.
Ignore the metacert when counting the number of expected certs
presented.
And fix the test, pulling out the TLSConfig setup code into something
shared between the real cmd/derper and the test.
Fixes#15579
Change-Id: I90526e38e59f89b480629b415f00587b107de10a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This reconciler allows users to make applications highly available at L3 by
leveraging Tailscale Virtual Services. Many Kubernetes Service's
(irrespective of the cluster they reside in) can be mapped to a
Tailscale Virtual Service, allowing access to these Services at L3.
Updates #15895
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Adds Recorder fields to configure the name and annotations of the ServiceAccount
created for and used by its associated StatefulSet. This allows the created Pod
to authenticate with AWS without requiring a Secret with static credentials,
using AWS' IAM Roles for Service Accounts feature, documented here:
https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.htmlFixes#15875
Change-Id: Ib0e15c0dbc357efa4be260e9ae5077bacdcb264f
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
cmd/containerboot,kube/ingressservices: proxy VIPService TCP/UDP traffic to cluster Services
This PR is part of the work to implement HA for Kubernetes Operator's
network layer proxy.
Adds logic to containerboot to monitor mounted ingress firewall configuration rules
and update iptables/nftables rules as the config changes.
Also adds new shared types for the ingress configuration.
The implementation is intentionally similar to that for HA for egress proxy.
Updates tailscale/tailscale#15895
Signed-off-by: chaosinthecrd <tom@tmlabs.co.uk>
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
CallMeMaybeVia reception and endpoint allocation have been collapsed to
a single event channel. discoInfo caching for active relay handshakes
is now implemented.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Content-type was responding as test/plain for probes
accepting application/json. Set content type header
before setting the response code to correct this.
Updates tailscale/corp#27370
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Update proxy-to-grafana to strip any X-Webauth prefixed headers passed
by the client in *every* request, not just those to /login.
/api/ routes will also accept these headers to authenticate users,
necessitating their removal to prevent forgery.
Updates tailscale/corp#28687
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
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>
`cmd/derpprobe --once` didn’t respect the convention of non-zero exit
status for a failed run. It would always exit zero (i.e. success),
even. This patch fixes that, but only for `--once` mode.
Fixes: #15925
Signed-off-by: Simon Law <sfllaw@tailscale.com>
In this PR, we make DNS registration behavior configurable via the EnableDNSRegistration policy setting.
We keep the default behavior unchanged, but allow admins to either enforce DNS registration and dynamic
DNS updates for the Tailscale interface, or prevent Tailscale from modifying the settings configured in
the network adapter's properties or by other means.
Updates #14917
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Add new rules to update DNAT rules for Kubernetes operator's
HA ingress where it's expected that rules will be added/removed
frequently (so we don't want to keep old rules around or rewrite
existing rules unnecessarily):
- allow deleting DNAT rules using metadata lookup
- allow inserting DNAT rules if they don't already
exist (using metadata lookup)
Updates tailscale/tailscale#15895
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: chaosinthecrd <tom@tmlabs.co.uk>
Commit 0841477 moved ServerEndpoint to an independent package. Move its
tests over as well.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
OCSP has been removed from the LE certs.
Use CRL verification instead.
If a cert provides a CRL, check its revocation
status, if no CRL is provided and otherwise
is valid, pass the check.
Fixes#15912
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Co-authored-by: Simon Law <sfllaw@tailscale.com>
In tailssh.go:1284, (*sshSession).startNewRecording starts a fire-and-forget goroutine that can
outlive the test that triggered its creation. Among other things, it uses ss.logf, and may call it
after the test has already returned. Since we typically use (*testing.T).Logf as the logger,
this results in a data race and causes flaky tests.
Ideally, we should fix the root cause and/or use a goroutines.Tracker to wait for the goroutine
to complete. But with the release approaching, it's too risky to make such changes now.
As a workaround, we update the tests to use tstest.WhileTestRunningLogger, which logs to t.Logf
while the test is running and disables logging once the test finishes, avoiding the race.
While there, we also fix TestSSHAuthFlow not to use log.Printf.
Updates #15568
Updates #7707 (probably related)
Signed-off-by: Nick Khyl <nickk@tailscale.com>
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>
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>
The event loop removes the need for growing locking complexities and
synchronization. Now we simply use channels. The event loop only runs
while there is active work to do.
relayManager remains no-op inside magicsock for the time being.
endpoints are never 'relayCapable' and therefore endpoint & Conn will
not feed CallMeMaybeVia or allocation events into it.
A number of relayManager events remain unimplemented, e.g.
CallMeMaybeVia reception and relay handshaking.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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>
Set Cross-Origin-Opener-Policy: same-origin for all browser requests to
prevent window.location manipulation by malicious origins.
Updates tailscale/corp#28480
Thank you to Triet H.M. Pham for the report.
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Commit 4b525fdda (ssh/tailssh: only chdir incubator process to user's
homedir when necessary and possible, 2024-08-16) defers changing the
working directory until the incubator process drops its privileges.
However, it didn't account for the case where there is no incubator
process, because no tailscaled was found on the PATH. In that case, it
only intended to run `tailscaled be-child` in the root directory but
accidentally ran everything there.
Fixes: #15350
Signed-off-by: Simon Law <sfllaw@sfllaw.ca>
ServerEndpoint will be used within magicsock and potentially elsewhere,
which should be possible without needing to import the server
implementation itself.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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>
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>
Android is Linux, but doesn't use Linux DNS managers (or D-Bus).
Updates #12614
Change-Id: I487802ac74a259cd5d2480ac26f7faa17ca8d1c3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This handle can be used in tests and debugging to identify the specific
client connection.
Updates tailscale/corp#28368
Change-Id: I48cc573fc0bcf018c66a18e67ad6c4f248fb760c
Signed-off-by: Brian Palmer <brianp@tailscale.com>
Android is Linux, but that not much Linux.
Updates #12614
Change-Id: Ice80bd3e3d173511c30d05a43d25a31e18928db7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
None of them are applicable to the common tsnet use cases.
If somebody wants one of them, they can empty import it.
Updates #12614
Change-Id: I3d7f74b555eed22e05a09ad667e4572a5bc452d8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For consistency with other flags, per Slack chat.
Updates #5902
Change-Id: I7ae1e4c97b37185573926f5fafda82cf8b46f071
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The defaultEnv and defaultBool functions are copied over temporarily
to minimise diff. This lays the ground work for having both the operator
and the new k8s-proxy binary implement the API proxy
Updates #13358
Change-Id: Ieacc79af64df2f13b27a18135517bb31c80a5a02
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
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>
This is a hack, but should suffice and be fast enough.
I really want to figure out what's keeping that writable fd open.
Fixes#15868
Change-Id: I285d836029355b11b7467841d31432cc5890a67e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
As just discussed on Slack with @nickkhyl.
Updates #12614
Change-Id: I138dd7eaffb274494297567375d969b4122f3f50
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
relayManager will eventually be responsible for handling the allocation
and handshaking of UDP relay server endpoints.
relay servers are endpoint-independent, and Conn must already maintain
handshake state for all endpoints. This justifies a new data structure
to fill these roles.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Previously all tests shared their tailscale+tailscaled binaries in
system /tmp directories, which often leaked, and required TestMain to
clean up (which feature/taildrop didn't use).
This makes it use testing.T.TempDir for the binaries, but still only
builds them once and efficiently as possible depending on the OS
copies them around between each test's temp dir.
Updates #15812
Change-Id: I0e2585613f272c3d798a423b8ad1737f8916f527
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Conn.handleDiscoMessage() now makes a distinction between relay
handshake disco messages and peer disco messages.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Taildrop has never had an end-to-end test since it was introduced.
This adds a basic one.
It caught two recent refactoring bugs & one from 2022 (0f7da5c7dc).
This is prep for moving the rest of Taildrop out of LocalBackend, so
we can do more refactorings with some confidence.
Updates #15812
Change-Id: I6182e49c5641238af0bfdd9fea1ef0420c112738
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
* util/linuxfw: fix delete snat rule
This pr is fixing the bug that in nftables mode setting snat-subnet-routes=false doesn't
delete the masq rule in nat table.
Updates #15661
Signed-off-by: Kevin Liang <kevinliang@tailscale.com>
* change index arithmetic in test to chunk
Signed-off-by: Kevin Liang <kevinliang@tailscale.com>
* reuse rule creation function in rule delete
Signed-off-by: Kevin Liang <kevinliang@tailscale.com>
* add test for deleting the masq rule
Signed-off-by: Kevin Liang <kevinliang@tailscale.com>
---------
Signed-off-by: Kevin Liang <kevinliang@tailscale.com>
This fixes the Taildrop deadlock from 8b72dd7873.
Fixes#15824
Change-Id: I5ca583de20dd0d0b513ce546439dc632408ca1f1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Conn.sendDiscoMessage() now verifies if the destination disco key is
associated with any known peer(s) in a thread-safe manner.
Updates #15844
Signed-off-by: Jordan Whited <jordan@tailscale.com>
And also validate opts for unknown types, before other side effects.
Fixes#15833
Change-Id: I4cabe16c49c5b7566dcafbec59f2cd1e0c8b4b3c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Instead of using the version package (which depends on
tailcfg.CurrentCapabilityVersion) to get the git commit hash, do it
directly using debug.BuildInfo. This way, when changing struct fields in
tailcfg, we can successfully `go generate` it without compiler errors.
Updates #9634
Updates https://github.com/tailscale/corp/issues/26717
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
TS_CONTROL_IS_PLAINTEXT_HTTP no longer does anything as of
8fd471ce57
Updates #13597
Change-Id: I32ae7f8c5f2a2632e80323b1302a36295ee00736
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for Taildrop integration tests using them from another package.
Updates #15812
Change-Id: I6a995de4e7400658229d99c90349ad5bd1f503ae
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So it can be exported & used by other packages in future changes.
Updates #15812
Change-Id: I319000989ebc294e29c92be7f44a0e11ae6f7761
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We were missing this metric, but it can be important for some workloads.
Varz memstats output allocation cost reduced from 30 allocs per
invocation to 1 alloc per invocation.
Updates tailscale/corp#28033
Signed-off-by: James Tucker <james@tailscale.com>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
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>
The previous strategy assumed clients maintained adequate state to
understand the relationship between endpoint allocation and the server
it was allocated on.
magicsock will not have awareness of the server's disco key
pre-allocation, it only understands peerAPI address at this point. The
second client to allocate on the same server could trigger
re-allocation, breaking a functional relay server endpoint.
If magicsock needs to force reallocation we can add opt-in behaviors
for this later.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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>
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>
The typical way to implement union types in Go
is to use an interface where the set of types is limited.
However, there historically has been poor support
in v1 "encoding/json" with interface types where
you can marshal such values, but fail to unmarshal them
since type information about the concrete type is lost.
The MakeInterfaceCoders function constructs custom
marshal/unmarshal functions such that the type name
is encoded in the JSON representation.
The set of valid concrete types for an interface
must be statically specified for this to function.
Updates tailscale/corp#22024
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
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>
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>
Replace all instances of interface{} with any to resolve the
golangci-lint errors that appeared in the previous tsidp PR.
Updates #cleanup
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
tstime.GoDuration JSON serializes with time.Duration.String(), which is
more human-friendly than nanoseconds.
ServerEndpoint is currently experimental, therefore breaking changes
are tolerable.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
The encoding/json/v2 effort may end up changing
the default represention of time.Duration in JSON.
See https://go.dev/issue/71631
The GoDuration type allows us to explicitly use
the time.Duration.String representation regardless of
whether we serialize with v1 or v2 of encoding/json.
Updates tailscale/corp#27502
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We added this helper in 1e2e319e7d. Remove this copy.
Updates #cleanup
Change-Id: I5b0681acc23692beed35951c9902ac9ceca0a8b9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The relay server is still permanently disabled until node attribute
changes are wired up in a future commit.
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
QNAP now requires builds to be signed with an HSM.
This removes support for signing with a local keypair.
This adds support for signing with a Google Cloud hosted key.
The key should be an RSA key with protection level `HSM` and that uses PSS padding and a SHA256 digest.
The GCloud project, keyring and key name are passed in as command-line arguments.
The GCloud credentials and the PEM signing certificate are passed in as Base64-encoded command-line arguments.
Updates tailscale/corp#23528
Signed-off-by: Percy Wegmann <percy@tailscale.com>
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>
When an event bus is plumbed in, use it to subscribe and react to port mapping
updates instead of using the client's callback mechanism. For now, the callback
remains available as a fallback when an event bus is not provided.
Updates #15160
Change-Id: I026adca44bf6187692ee87ae8ec02641c12f7774
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
When an event bus is configured publish an event each time a new port mapping
is updated. Publication is unconditional and occurs prior to calling any
callback that is registered. For now, the callback is still fired in a separate
goroutine as before -- later, those callbacks should become subscriptions to
the published event.
For now, the event type is defined as a new type here in the package. We will
want to move it to a more central package when there are subscribers. The event
wrapper is effectively a subset of the data exported by the internal mapping
interface, but on a concrete struct so the bus plumbing can inspect it.
Updates #15160
Change-Id: I951f212429ac791223af8d75b6eb39a0d2a0053a
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
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>
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>
This feature is "registered" as an ipnlocal.Extension, and
conditionally linked depending on GOOS and ts_omit_relayserver build
tag.
The feature is not linked on iOS in attempt to limit the impact to
binary size and resulting effect of pushing up against NetworkExtension
limits. Eventually we will want to support the relay server on iOS,
specifically on the Apple TV. Apple TVs are well-fitted to act as
underlay relay servers as they are effectively always-on servers.
This skeleton begins to tie a PeerAPI endpoint to a net/udprelay.Server.
The PeerAPI endpoint is currently no-op as
extension.shouldRunRelayServer() always returns false. Follow-up commits
will implement extension.shouldRunRelayServer().
Updates tailscale/corp#27502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Bump to latest 22.x LTS release for node as the 18.x line is going EOL this month.
Updates https://github.com/tailscale/corp/issues/27737
Signed-off-by: Mario Minardi <mario@tailscale.com>
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>
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>
This change introduces an Age column in the output for all custom
resources to enhance visibility into their lifecycle status.
Fixes#15499
Signed-off-by: satyampsoni <satyampsoni@gmail.com>
[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>
Query for the const quad-100 reverse DNS name, for which a forward
record will also be served. This test was previously dependent on
search domain behavior, and now it is not.
Updates #15607
Signed-off-by: Jordan Whited <jordan@tailscale.com>
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>
Allow builds to be outputted to a specific directory.
By default, or if unset, artifacts are written to PWD/dist.
Updates tailscale/corp#27638
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
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>
Because we derive v6 addresses from v4 addresses we only need to store
the v4 address, not both.
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
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>
Adds a new diagram for ProxyGroups running in Ingress mode.
Documentation is currently not publicly available, but a link needs
adding once it is.
Updates tailscale/corp#24795
Change-Id: I0d5dd6bf6f0e1b8b0becae848dc97d8b4bfb9ccb
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
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>
ResourceCheck was previously using cmp.Diff on multiline goroutine stacks
The produced output was difficult to read for a number of reasons:
- the goroutines were sorted by count, and a changing count caused them to
jump around
- diffs would be in the middle of stacks
Instead, we now parse the pprof/goroutines?debug=1 format goroutines and
only diff whole stacks.
Updates #1253
Signed-off-by: Paul Scott <paul@tailscale.com>
Default tags to `$TAGS` if set, so that people can choose arbitrary
subsets of features.
Updates #12614
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Fix the index out of bound panic when a request is made to the local
fileserver mux with a valid secret-token, but missing share name.
Example error:
http: panic serving 127.0.0.1:40974: runtime error: slice bounds out of range [2:1]
Additionally, we document the edge case behavior of utilities that
this fileserver mux depends on.
Signed-off-by: Craig Hesling <craig@hesling.com>
This makes sure that the log target override is respected even if a
custom HTTP client is passed to logpolicy.
Updates tailscale/maple#29
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
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>
In this PR, we update the Windows client updater to:
- Run msiexec with logging enabled and preserve the log file in %ProgramData%\Tailscale\Logs;
- Preserve the updater's own log file in the same location;
- Properly handle ERROR_SUCCESS_REBOOT_REQUIRED, ERROR_SUCCESS_REBOOT_INITIATED, and ERROR_INSTALL_ALREADY_RUNNING exit codes. The first two values indicate that installation
completed successfully and no further retries are needed. The last one means the Windows Installer
service is busy. Retrying immediately is likely to fail and may be risky; it could uninstall the current version
without successfully installing the new one, potentially leaving the user without Tailscale.
Updates tailscale/corp#27496
Updates tailscale#15554
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Installer tests only run when changes are made to pkgserve. This PR schedules
these tests to be run daily and report any failures to Slack.
Fixestailscale/corp#19103
Signed-off-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com>
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>
`tailscale set` was created to set preferences, which used to be
overloaded into `tailscale up`. To move people over to the new
command, `up` was supposed to be frozen and no new preference flags
would be added. But people forgot, there was no test to warn them, and
so new flags were added anyway.
TestUpFlagSetIsFrozen complains when new flags are added to
`tailscale up`. It doesn’t try all combinations of GOOS, but since
the CI builds in every OS, the pull-request tests should cover this.
Updates #15460
Signed-off-by: Simon Law <sfllaw@sfllaw.ca>
Ensure no services are advertised as part of shutting down tailscaled.
Prefs are only edited if services are currently advertised, and they're
edited we wait for control's ~15s (+ buffer) delay to failover.
Note that editing prefs will trigger a synchronous write to the state
Secret, so it may fail to persist state if the ProxyGroup is getting
scaled down and therefore has its RBAC deleted at the same time, but that
failure doesn't stop prefs being updated within the local backend,
doesn't affect connectivity to control, and the state Secret is
about to get deleted anyway, so the only negative side effect is a harmless
error log during shutdown. Control still learns that the node is no
longer advertising the service and triggers the failover.
Note that the first version of this used a PreStop lifecycle hook, but
that only supports GET methods and we need the shutdown to trigger side
effects (updating prefs) so it didn't seem appropriate to expose that
functionality on a GET endpoint that's accessible on the k8s network.
Updates tailscale/corp#24795
Change-Id: I0a9a4fe7a5395ca76135ceead05cbc3ee32b3d3c
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
As IPv4 and IPv6 end up with different MSS and different congestion
control strategies, proxying between them can really amplify TCP
meltdown style conditions in many real world network conditions, such as
with higher latency, some loss, etc.
Attempt to match up the protocols, otherwise pick a destination address
arbitrarily. Also shuffle the target address to spread load across
upstream load balancers.
Updates #15367
Signed-off-by: James Tucker <james@tailscale.com>
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>
The test suite had grown to about 20s on my machine, but it doesn't
do much taxing work so was a good candidate to parallelise. Now runs
in under 2s on my machine.
Updates #cleanup
Change-Id: I2fcc6be9ca226c74c0cb6c906778846e959492e4
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
The earlier #15534 prevent some dup string flags. This does it for all
flag types.
Updates #6813
Change-Id: Iec2871448394ea9a5b604310bdbf7b499434bf01
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
tsconsensus enables tsnet.Server instances to form a consensus.
tsconsensus wraps hashicorp/raft with
* the ability to do discovery via tailscale tags
* inter node communication over tailscale
* routing of commands to the leader
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
So we can link open source contributors to it.
Updates #cleanup
Change-Id: I02f612b38db9594f19b3be5d982f58c136120e9a
Co-authored-by: James Sanderson <jsanderson@tailscale.com>
Co-authored-by: Will Norris <will@tailscale.com>
Co-authored-by: James Tucker <james@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Some CLI flags support multiple values separated by commas. These flags
are intended to be declared only once and will silently ignore subsequent
instances. This will now throw an error if multiple instances of advertise-tags
and advertise-routes are detected.
Fixes#6813
Signed-off-by: Jason O'Donnell <2160810+jasonodonnell@users.noreply.github.com>
Ensure that the upstream is always queried, so that if upstream is going
to NXDOMAIN natc will also return NXDOMAIN rather than returning address
allocations.
At this time both IPv4 and IPv6 are still returned if upstream has a
result, regardless of upstream support - this is ~ok as we're proxying.
Rewrite the tests to be once again slightly closer to integration tests,
but they're still very rough and in need of a refactor.
Further refactors are probably needed implementation side too, as this
removed rather than added units.
Updates #15367
Signed-off-by: James Tucker <james@tailscale.com>
This adds netx.DialFunc, unifying a type we have a bazillion other
places, giving it now a nice short name that's clickable in
editors, etc.
That highlighted that my earlier move (03b47a55c7) of stuff from
nettest into netx moved too much: it also dragged along the memnet
impl, meaning all users of netx.DialFunc who just wanted netx for the
type definition were instead also pulling in all of memnet.
So move the memnet implementation netx.Network into memnet, a package
we already had.
Then use netx.DialFunc in a bunch of places. I'm sure I missed some.
And plenty remain in other repos, to be updated later.
Updates tailscale/corp#27636
Change-Id: I7296cd4591218e8624e214f8c70dab05fb884e95
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I added yet another one in 6d117d64a2 but that new one is at the
best place int he dependency graph and has the best name, so let's use
that one for everything possible.
types/lazy can't use it for circular dependency reasons, so unexport
that copy at least.
Updates #cleanup
Change-Id: I25db6b6a0d81dbb8e89a0a9080c7f15cbf7aa770
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We want to be able to use the netx.Network (and RealNetwork
implemementation) outside of tests, without linking "testing".
So split out the non-test stuff of nettest into its own package.
We tend to use "foox" as the convention for things we wish were in the
standard library's foo package, so "netx" seems consistent.
Updates tailscale/corp#27636
Change-Id: I1911d361f4fbdf189837bf629a20f2ebfa863c44
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This fixes a bug in the local client where the DELETE request was
not being sent correctly. The route was missing a slash before the url
and this now matches the switch profile function.
Signed-off-by: Esteban-Bermudez <esteban@bermudezaguirre.com>
To avoid ephemeral port / TIME_WAIT exhaustion with high --count
values, and to eventually detect leaked connections in tests. (Later
the memory network will register a Cleanup on the TB to verify that
everything's been shut down)
Updates tailscale/corp#27636
Change-Id: Id06f1ae750d8719c5a75d871654574a8226d2733
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For future in-memory network changes (#15558) to be able to be
stricter and do automatic leak detection when it's safe to do so, in
non-parallel tests.
Updates tailscale/corp#27636
Change-Id: I50f03b16a3f92ce61a7ed88264b49d8c6628f638
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Make the perPeerState objects able to function independently without a
shared reference to the connector.
We don't currently change the values from connector that perPeerState
uses at runtime. Explicitly copying them at perPeerState creation allows
us to, for example, put the perPeerState into a consensus algorithm in
the future.
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
This shouldn't be necessary, but while we're continuing to figure out
the root cause, this is better than having to restart the app or switch
profiles on the command line.
Updates #15528
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
Android >=14 forbids the use of netlink sockets, and in some configurations
can kill apps that try.
Fixes#9836
Signed-off-by: David Anderson <dave@tailscale.com>
The regular android app constructs its own wgengine with
additional FFI shims, so this default codepath only affects
other handcrafted buids like tsnet, which do not let the
caller customize the innards of wgengine.
Android >=14 forbids the use of netlink sockets, which makes
the standard linux router fail to initialize.
Fixes#9836
Signed-off-by: David Anderson <dave@tailscale.com>
So we can link tailscale and tailscaled together into one.
Updates #5794
Change-Id: I9a8b793c64033827e4188931546cbd64db55982e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
To ease local debugging and have fewer moving pieces while bringing up
Plan 9 support.
Updates #5794
Change-Id: I2dc98e73bbb0d4d4730dc47203efc0550a0ac0a0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Otherwise this was repeated closing control/derp connections all the time
on netmon changes. Arguably we should do this on all platforms?
Updates #5794
Change-Id: If6bbeff554235f188bab2a40ab75e08dd14746b2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This wasn't right; it was spinning up new goroutines non-stop.
Revert to a boring localhost TCP implementation for now.
Updates #5794
Change-Id: If93caa20a12ee4e741c0c72b0d91cc0cc5870152
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Not currently used in the OSS tree, a View for tailcfg.VIPService will
make implementing some server side changes easier.
Updates tailscale/corp#26272
Change-Id: If1ed0bea4eff8c4425d3845b433a1c562d99eb9e
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
Avoid the unbounded runtime during random allocation, if random
allocation fails after a first pass at random through the provided
ranges, pick the next free address by walking through the allocated set.
The new ipx utilities provide a bitset based allocation pool, good for
small to moderate ranges of IPv4 addresses as used in natc.
Updates #15367
Signed-off-by: James Tucker <james@tailscale.com>
fixestailscale/corp#27506
The source address link selection on sandboxed macOS doesn't deal
with loopback addresses correctly. This adds an explicit check to ensure
we return the loopback interface for loopback addresses instead of the
default empty interface.
Specifically, this allows the dns resolver to route queries to a loopback
IP which is a common tactic for local DNS proxies.
Tested on both macos, macsys and tailscaled. Forwarded requests to
127/8 all bound to lo0.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This commit implements an experimental UDP relay server. The UDP relay
server leverages the Disco protocol for a 3-way handshake between
client and server, along with 3 new Disco message types for said
handshake. These new Disco message types are also considered
experimental, and are not yet tied to a capver.
The server expects, and imposes, a Geneve (Generic Network
Virtualization Encapsulation) header immediately following the underlay
UDP header. Geneve protocol field values have been defined for Disco
and WireGuard. The Geneve control bit must be set for the handshake
between client and server, and unset for messages relayed between
clients through the server.
Updates tailscale/corp#27101
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Add the golang-image-ico package, which is an incredibly small package
to handle the ICO container format with PNG inside. Some profile photos
look quite pixelated when displayed at this size, but it's better than
nothing, and any Windows support is just a bonus anyway.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
Otherwise you can get stuck finding minor ones nonstop.
Fixes#15484
Change-Id: I7f98ac338c0b32ec1b9fdc47d053207b5fc1bf23
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It only affected js/wasm and tamago.
Updates tailscale/corp#24697
Change-Id: I8fd29323ed9b663fe3fd8d4a86f26ff584a3e134
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
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>
For hooking up websocket VM clients to natlab.
Updates #13038
Change-Id: Iaf728b9146042f3d0c2d3a5e25f178646dd10951
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Re-enable HA Ingress again that was disabled for 1.82 release.
This reverts commit fea74a60d5.
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Not all platforms have hardlinks, or not easily.
This lets a "tailscale" wrapper script set an environment variable
before calling tailscaled.
Updates #2233
Change-Id: I9eccc18651e56c106f336fcbbd0fd97a661d312e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
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>
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>
The default values for `tailscale up` and `tailscale set` are supposed
to agree on all common flags. But they don’t for `--accept-dns`:
user@host:~$ tailscale up --help 2>&1 | grep -A1 accept-dns
--accept-dns, --accept-dns=false
accept DNS configuration from the admin panel (default true)
user@host:~$ tailscale set --help 2>&1 | grep -A1 accept-dns
--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.
This patch makes `--accept-dns` default to true in both commands and
also introduces `TestSetDefaultsMatchUpDefaults` to prevent any future
drift.
Fixes: #15319
Signed-off-by: Simon Law <sfllaw@sfllaw.ca>
Temporarily make sure that the HA Ingress reconciler does not run,
as we do not want to release this to stable just yet.
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
We now have a tailscale/alpine-base:3.19 use that as the default base image.
Updates tailscale/tailscale#15328
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This is a very dumb fix as it has an unbounded worst case runtime. IP
allocation needs to be done in a more sane way in a follow-up.
Updates #15367
Signed-off-by: James Tucker <james@tailscale.com>
Bumps Alpine 3.18 -> 3.19.
Alpine 3.19 links iptables to nftables-based
implementation that can break hosts that don't
support nftables.
Link iptables back to the legacy implementation
till we have some certainty that changing to
nftables based implementation will not break existing
setups.
Updates tailscale/tailscale#15328
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
cmd/{k8s-operator,containerboot}: check TLS cert before advertising VIPService
- Ensures that Ingress status does not advertise port 443 before
TLS cert has been issued
- Ensure that Ingress backends do not advertise a VIPService
before TLS cert has been issued, unless the service also
exposes port 80
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
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>
When compiled into TailscaleKit.framework (via the libtailscale
repository), os.Executable() returns an error instead of the name of the
executable. This commit adds another branch to the switch statement that
enumerates platforms which behave in this manner, and defaults to
"tsnet" in the same manner as those other platforms.
Fixes#15410.
Signed-off-by: James Nugent <james@jen20.com>
Minimal mitigation that doesn't do the full refactor that's probably
warranted.
Updates #15402
Change-Id: I79fd91de0e0661d25398f7d95563982ed1d11561
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
fixestailscale/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>
Add a label which differentiates the address family
for STUN checks.
Also initialize the derpprobe_attempts_total and
derpprobe_seconds_total metrics by adding 0 for
the alternate fail/ok case.
Updates tailscale/corp#27249
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
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>
Only send a stored raw map message in reply to a streaming map response.
Otherwise a non-streaming map response might pick it up first, and
potentially drop it. This guarantees that a map response sent via
AddRawMapResponse will be picked up by the main map response loop in the
client.
Fixes#15362
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
These tests aren't perfect, nor is this complete coverage, but this is a
set of coverage that is at least stable.
Updates #15367
Signed-off-by: James Tucker <james@tailscale.com>
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>
To let you easily run multiple tailscaled instances for development
and let you route CLI commands to the right one.
Updates #15145
Change-Id: I06b6a7bf024f341c204f30705b4c3068ac89b1a2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
Noticed while working on a dev tool that uses local.Client.
Updates #cleanup
Change-Id: I981efff74a5cac5f515755913668bd0508a4aa14
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Switch from using the Comment field to a ts-scoped annotation for
tracking which operators are cooperating over ownership of a
VIPService.
Updates tailscale/corp#24795
Change-Id: I72d4a48685f85c0329aa068dc01a1a3c749017bf
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
cmd/k8s-operator,k8s-operator: allow using LE staging endpoint for Ingress
Allow to optionally use LetsEncrypt staging endpoint to issue
certs for Ingress/HA Ingress, so that it is easier to
experiment with initial Ingress setup without hiting rate limits.
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
(*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>
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>
This adds a portable way to do a raw LocalAPI request without worrying
about the Unix-vs-macOS-vs-Windows ways of hitting the LocalAPI server.
(It was already possible but tedious with 'tailscale debug local-creds')
Updates tailscale/corp#24690
Change-Id: I0828ca55edaedf0565c8db192c10f24bebb95f1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
This makes the web server running inside tailscaled on 100.100.100.100:80 support requests with `Host: 100.100.100.100:80` and its IPv6 equivalent.
Prior to this commit, the web server replied to such requests with a redirect to the node's Tailscale IP:5252.
Fixes https://github.com/tailscale/tailscale/issues/14415
Signed-off-by: Alex Klyubin <klyubin@gmail.com>
There was a flaky failure case where renaming a TLS hostname for an
ingress might leave the old hostname dangling in tailscaled config. This
happened when the proxygroup reconciler loop had an outdated resource
version of the config Secret in its cache after the
ingress-pg-reconciler loop had very recently written it to delete the
old hostname. As the proxygroup reconciler then did a patch, there was
no conflict and it reinstated the old hostname.
This commit updates the patch to an update operation so that if the
resource version is out of date it will fail with an optimistic lock
error. It also checks for equality to reduce the likelihood that we make
the update API call in the first place, because most of the time the
proxygroup reconciler is not even making an update to the Secret in the
case that the hostname has changed.
Updates tailscale/corp#24795
Change-Id: Ie23a97440063976c9a8475d24ab18253e1f89050
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
updates tailscale/corp#27145
We require a means to trigger a recompilation of the DNS configuration
to pick up new nameservers for platforms where we blend the interface
nameservers from the OS into our DNS config.
Notably, on Darwin, the only API we have at our disposal will, in rare instances,
return a transient error when querying the interface nameservers on a link change if
they have not been set when we get the AF_ROUTE messages for the link
update.
There's a corresponding change in corp for Darwin clients, to track
the interface namservers during NEPathMonitor events, and call this
when the nameservers change.
This will also fix the slightly more obscure bug of changing nameservers
while tailscaled is running. That change can now be reflected in
magicDNS without having to stop the client.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
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>
Update the HA Ingress controller to wait until it sees AdvertisedServices
config propagated into at least 1 Pod's prefs before it updates the status
on the Ingress, to ensure the ProxyGroup Pods are ready to serve traffic
before indicating that the Ingress is ready
Updates tailscale/corp#24795
Change-Id: I1b8ce23c9e312d08f9d02e48d70bdebd9e1a4757
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
The use of html/template causes reflect-based linker bloat. Longer
term we have options to bring the UI back to iOS, but for now, cut
it out.
Updates #15297
Signed-off-by: David Anderson <dave@tailscale.com>
Allows the use of tsweb without pulling in all of the heavy prometheus
client libraries, protobuf and so on.
Updates #15160
Signed-off-by: David Anderson <dave@tailscale.com>
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>
When the Ingress is updated to a new hostname, the controller does not
currently clean up the old VIPService from control. Fix this up to parse
the ownership comment correctly and write a test to enforce the improved
behaviour
Updates tailscale/corp#24795
Change-Id: I792ae7684807d254bf2d3cc7aa54aa04a582d1f5
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This adds support for using ACL Grants to configure a role for the
auto-provisioned user.
Fixestailscale/corp#14567
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
cmd/containerboot: manage HA Ingress TLS certs from containerboot
When ran as HA Ingress node, containerboot now can determine
whether it should manage TLS certs for the HA Ingress replicas
and call the LocalAPI cert endpoint to ensure initial issuance
and renewal of the shared TLS certs.
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Shovel small events through the pipeine as fast as possible in a few basic
configurations, to establish some baseline performance numbers.
Updates #15160
Change-Id: I1dcbbd1109abb7b93aa4dcb70da57f183eb0e60e
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
* 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>
Allow customizing the title on the debug index page. Also add methods
for registering http.HandlerFunc to make it a little easier on callers.
Updates tailscale/corp#27058
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
The demo program generates a stream of made up bus events between
a number of bus actors, as a way to generate some interesting activity
to show on the bus debug page.
Signed-off-by: David Anderson <dave@tailscale.com>
This adds a new helper to the netmon package that allows us to
rate-limit log messages, so that they only print once per (major)
LinkChange event. We then use this when constructing the portmapper, so
that we don't keep spamming logs forever on the same network.
Updates #13145
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I6e7162509148abea674f96efd76be9dffb373ae4
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#27011tailscale/corp#27012
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
Ensure that the src address for a connection is one of the primary
addresses assigned by Tailscale. Not, for example, a virtual IP address.
Updates #14667
Signed-off-by: Fran Bull <fran@tailscale.com>
Add support for Cross-Origin XHR requests to the openid-configuration
endpoint to enable clients like Grafana's auto-population of OIDC setup
data from its contents.
Updates https://github.com/tailscale/tailscale/issues/10263
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
fixestailscale/tailscale#15269
Fixes the various CLIs for all of the various flavors of tailscaled on
darwin. The logic in version is updated so that we have methods that
return true only for the actual GUI app (which can beCLI) and the
order of the checks in localTCPPortAndTokenDarwin are corrected so
that the logic works with all 5 combinations of CLI and tailscaled.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
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>
And don't return a comma-separated string. That's kinda weird
signature-wise, and not needed by half the callers anyway. The callers
that care can do the join themselves.
Updates #cleanup
Change-Id: Ib5ad51a3c6b663d868eba14fe9dc54b2609cfb0d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
natc itself can't immediately fix the problem, but it can more correctly
error that return bad addresses.
Updates tailscale/corp#26968
Signed-off-by: James Tucker <james@tailscale.com>
This lets debug tools list the types that clients are wielding, so
that they can build a dataflow graph and other debugging views.
Updates #15160
Signed-off-by: David Anderson <dave@tailscale.com>
If any debugging hook might see an event, Publisher.ShouldPublish should
tell its caller to publish even if there are no ordinary subscribers.
Updates #15160
Signed-off-by: David Anderson <dave@tailscale.com>
Enables monitoring events as they flow, listing bus clients, and
snapshotting internal queues to troubleshoot stalls.
Updates #15160
Signed-off-by: David Anderson <dave@tailscale.com>
Delete files from `$(go env GOCACHE)` and `$(go env GOMODCACHE)/cache`
that have not been modified in >= 90 minutes as these files are not
resulting in cache hits on the current branch.
These deltions have resulted in the uploaded / downloaded compressed
cache size to go down to ~1/3 of the original size in some instances
with the extracted size being ~1/4 of the original extraced size.
Updates https://github.com/tailscale/tailscale/issues/15238
Signed-off-by: Mario Minardi <mario@tailscale.com>
We previously retried getting a UPnP mapping when the device returned
error code 725, "OnlyPermanentLeasesSupported". However, we've seen
devices in the wild also return 402, "Invalid Args", when given a lease
duration. Fall back to the no-duration mapping method in these cases.
Updates #15223
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I6a25007c9eeac0dac83750dd3ae9bfcc287c8fcf
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>
If we get a packet in over some DERP and don't otherwise know how to
reply (no known DERP home or UDP endpoint), this makes us use the
DERP connection on which we received the packet to reply. This will
almost always be our own home DERP region.
This is particularly useful for large one-way nodes (such as
hello.ts.net) that don't actively reach out to other nodes, so don't
need to be told the DERP home of peers. They can instead learn the
DERP home upon getting the first connection.
This can also help nodes from a slow or misbehaving control plane.
Updates tailscale/corp#26438
Change-Id: I6241ec92828bf45982e0eb83ad5c7404df5968bc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For people who can't use LetsEncrypt because it's banned.
Per https://github.com/tailscale/tailscale/issues/11776#issuecomment-2520955317
This does two things:
1) if you run derper with --certmode=manual and --hostname=$IP_ADDRESS
we previously permitted, but now we also:
* auto-generate the self-signed cert for you if it doesn't yet exist on disk
* print out the derpmap configuration you need to use that
self-signed cert
2) teaches derp/derphttp's derp dialer to verify the signature of
self-signed TLS certs, if so declared in the existing
DERPNode.CertName field, which previously existed for domain fronting,
separating out the dial hostname from how certs are validates,
so it's not overloaded much; that's what it was meant for.
Fixes#11776
Change-Id: Ie72d12f209416bb7e8325fe0838cd2c66342c5cf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Publicly exposed debugging functions will use these hooks to
observe dataflow in the bus.
Updates #15160
Signed-off-by: David Anderson <dave@tailscale.com>
cmd/k8s-operator: ensure HA Ingress can operate in multicluster mode.
Update the owner reference mechanism so that:
- if during HA Ingress resource creation, a VIPService
with some other operator's owner reference is already found,
just update the owner references to add one for this operator
- if during HA Ingress deletion, the VIPService is found to have owner
reference(s) from another operator, don't delete the VIPService, just
remove this operator's owner reference
- requeue after HA Ingress reconciles that resulted in VIPService updates,
to guard against overwrites due to concurrent operations from different
clusters.
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Use secure constant time comparisons for the client ID and secret values
during the allowRelyingParty authorization check.
Updates #cleanup
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Now that packets flow for VIPServices, the last piece needed to start
serving them from a ProxyGroup is config to tell the proxy Pods which
services they should advertise.
Updates tailscale/corp#24795
Change-Id: Ic7bbeac8e93c9503558107bc5f6123be02a84c77
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
The natlab VM tests are flaking on GitHub Actions.
To not distract people, disable them for now (unless they're touched
directly) until they're made more reliable, which will be some painful
debugging probably.
Updates #13038
Change-Id: I6570f1cd43f8f4d628a54af8481b67455ebe83dc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This makes the helpers closer in behavior to cancelable contexts
and taskgroup.Single, and makes the worker code use a more normal
and easier to reason about context.Context for shutdown.
Updates #15160
Signed-off-by: David Anderson <dave@tailscale.com>
The Client carries both publishers and subscribers for a single
actor. This makes the APIs for publish and subscribe look more
similar, and this structure is a better fit for upcoming debug
facilities.
Updates #15160
Signed-off-by: David Anderson <dave@tailscale.com>
We are soon going to start assigning shared-in nodes a CGNAT IPv4 in the Hello tailnet when necessary, the same way that normal node shares assign a new IPv4 on conflict.
But Hello wants to display the node's native IPv4, the one it uses in its own tailnet. That IPv4 isn't available anywhere in the netmap today, because it's not normally needed for anything.
We are going to start sending that native IPv4 in the peer node CapMap, only for Hello's netmap responses. This change enables Hello to display that native IPv4 instead, when available.
Updates tailscale/corp#25393
Change-Id: I87480b6d318ab028b41ef149eb3ba618bd7f1e08
Signed-off-by: Brian Palmer <brianp@tailscale.com>
fixestailscale/corp#26806
IsMacSysApp is not returning the correct answer... It looks like the
rest of the code base uses isMacSysExt (when what they really want
to know is isMacSysApp). To fix the immediate issue (localAPI is broken
entirely in corp), we'll add this check to safesocket which lines up with
the other usages, despite the confusing naming.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
fixestailscale/corp#26806
This was still slightly incorrect. We care only if the caller is the macSys
or macOs app. isSandBoxedMacOS doesn't give us the correct answer
for macSys because technically, macsys isn't sandboxed.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
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>
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>
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>
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>
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.
Fixestailscale/corp#26843
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
Add description of the license reports in this directory and brief
instructions for reviewers. I recently needed to convert these to CSV,
so I also wanted to place to stash that regex so I didn't lose it.
Updates tailscale/corp#5780
Signed-off-by: Will Norris <will@tailscale.com>
fixestailscale/corp#26806
Fixes a regression where LocalTCPPortAndToken needs to error out early
if we're not running as sandboxed macos so that we attempt to connect
using the normal unix machinery.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
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>
The json/v2 prototype is still in flux and the API can/will change.
Statically enforce that types implementing the v2 methods
satisfy the correct interface so that changes to the signature
can be statically detected by the compiler.
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Fix the order of the CSRF handlers (HTTP plaintext context setting,
_then_ enforcement) in the construction of the web UI server. This
resolves false-positive "invalid Origin" 403 exceptions when attempting
to update settings in the web UI.
Add unit test to exercise the CSRF protection failure and success cases
for our web UI configuration.
Updates #14822
Updates #14872
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
The upstream module has seen significant work making
the v1 emulation layer a high fidelity re-implementation
of v1 "encoding/json".
This addresses several upstream breaking changes:
* MarshalJSONV2 renamed as MarshalJSONTo
* UnmarshalJSONV2 renamed as UnmarshalJSONFrom
* Options argument removed from MarshalJSONV2
* Options argument removed from UnmarshalJSONV2
Updates tailscale/corp#791
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Ensures default Linux umask 022 for the installer script to
make sure that files created by the installer can be accessed
by other tools, such as apt.
Updates tailscale/tailscale#15133
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
In order to improve latency tracking, we will use an exponentially
weighted moving average that will smooth change over time and suppress
large outlier values.
Updates tailscale/corp#26649
Signed-off-by: James Tucker <james@tailscale.com>
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>
For tests (in another repo) that use cgo, we'd like to set CGO_ENABLED=1
explicitly when evaluating cross-compiled deps with "go list".
Updates tailscale/corp#26717
Updates tailscale/corp#26737
Change-Id: Ic21a54379ae91688d2456985068a47e73d04a645
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Diff:
7c08383913
This reverts our previous CGO_ENABLED change: c1d3e9e814
It was causing depaware problems and is no longer necessary it seems? Upstream cmd/go is static nowadays.
And pulls in:
[release-branch.go1.24] doc/godebug: mention GODEBUG=fips140
[release-branch.go1.24] cmd/compile: avoid infinite recursion when inlining closures
[release-branch.go1.24] syscall: don't truncate newly created files on Windows
[release-branch.go1.24] runtime: fix usleep on s390x/linux
[release-branch.go1.24] runtime: add some linknames back for `github.com/bytedance/sonic`
Of those, really the only the 2nd and 3rd might affect us.
Updates #15015
Updates tailscale/go#52
Change-Id: I0fa479f8b2d39f43f2dcdff6c28289dbe50b0773
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When LocalAPI returns an AccessDeniedError, display a message in the
menu and hide or disable most other menu items. This currently includes
a placeholder KB link which I'll update if we end up using something
different.
I debated whether to change the app icon to indicate an error, but opted
not to since there is actually nothing wrong with the client itself and
Tailscale will continue to function normally. It's just that the systray
app itself is in a read-only state.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
This method uses `path.Join` to build the URL. Turns out with 1.24 this
started stripping consecutive "/" characters, so "http://..." in baseURL
becomes "http:/...".
Also, `c.Tailnet` is a function that returns `c.tailnet`. Using it as a
path element would encode as a pointer instead of the tailnet name.
Finally, provide a way to prevent escaping of path elements e.g. for `?`
in `acl?details=1`.
Updates #15015
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
* go.toolchain.branch: update to Go 1.24
Updates #15015
Change-Id: I29c934ec17e60c3ac3264f30fbbe68fc21422f4d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* cmd/testwrapper: fix for go1.24
Updates #15015
Signed-off-by: Paul Scott <paul@tailscale.com>
* go.mod,Dockerfile: bump to Go 1.24
Also bump golangci-lint to a version that was built with 1.24
Updates #15015
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
---------
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Paul Scott <paul@tailscale.com>
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Co-authored-by: Paul Scott <paul@tailscale.com>
Co-authored-by: Andrew Lytvynov <awly@tailscale.com>
There's nothing about it on
https://github.com/multipath-tcp/mptcp_net-next/issues/ but empirically
MPTCP doesn't support this option on awly's kernel 6.13.2 and in GitHub
actions.
Updates #15015
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
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>
This will help debug unexpected issues encountered by consumers of the gitops-pusher.
Updates tailscale/corp#26664
Signed-off-by: Percy Wegmann <percy@tailscale.com>
`routeAdvertiser` is the `iplocal.LocalBackend`. Calls to
`Advertise/UnadvertiseRoute` end up calling `EditPrefs` which in turn
calls `authReconfig` which finally calls `readvertiseAppConnectorRoutes`
which calls `AppConnector.DomainRoutes` and gets stuck on a mutex that
was already held when `routeAdvertiser` was called.
Make all calls to `routeAdvertiser` in `app.AppConnector` go through the
execqueue instead as a short-term fix.
Updates tailscale/corp#25965
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Co-authored-by: Irbe Krumina <irbe@tailscale.com>
It's not entirely clear whether this capability will be maintained, or in what form,
so this serves as a warning to that effect.
Updates tailscale/corp#22748
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This will allow Client to be extended with additional functions for internal use.
Updates tailscale/corp#22748
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This allows use of the officially supported control server API,
authenticated with the tsnet node's nodekey.
Updates tailscale/corp#22748
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Even after we remove the deprecated API, we will want to maintain a minimal
API for internal use, in order to avoid importing the external
tailscale.com/client/tailscale/v2 package. This shim exposes only the necessary
parts of the deprecated API for internal use, which gains us the following:
1. It removes deprecation warnings for internal use of the API.
2. It gives us an inventory of which parts we will want to keep for internal use.
Updates tailscale/corp#22748
Signed-off-by: Percy Wegmann <percy@tailscale.com>
testwrapper doesn't work with Go 1.24 and the coverage support is
making it harder to debug.
Updates #15015
Updates tailscale/corp#26659
Change-Id: I0125e881d08c92f1ecef88b57344f6bbb571b569
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
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>
This reverts most of 124dc10261 (#10401).
Removing in favour of adding this in CapMaps instead (#14829).
Updates tailscale/corp#16016
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
This will be used by clients to make better decisions on when to warn users
about impending key expiry.
Updates tailscale/corp#16016
Signed-off-by: James Sanderson <jsanderson@tailscale.com>
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>
Some clients don't request 'none' authentication. Instead, they immediately supply
a password or public key. This change allows them to do so, but ignores the supplied
credentials and authenticates using Tailscale instead.
Updates #14922
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Bart has had some substantial improvements in internal representation,
update functions, and other optimizations to reduce memory usage and
improve runtime performance.
Updates tailscale/corp#26353
Signed-off-by: James Tucker <james@tailscale.com>
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>
This reverts commit 413fb5b933.
See long story in #14992
Updates #14992
Updates tailscale/corp#26058
Change-Id: I3de7d080443efe47cbf281ea20887a3caf202488
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds a new policy definition for the AlwaysOn.Enabled policy setting
as well as the AlwaysOn.OverrideWithReason sub-option.
Updates #14823
Updates tailscale/corp#26247
Signed-off-by: Nick Khyl <nickk@tailscale.com>
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>
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>
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>
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>
And add omitempty to the ProfilePicURL too while here. Plenty
of users (and tagged devices) don't have profile pics.
Updates #14988
Change-Id: I6534bc14edb58fe1034d2d35ae2395f09fd7dd0d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is deprecated anyway, and we don't need to be sending
`"Bits":null` on the wire for the majority of clients.
Updates tailscale/corp#20965
Updates tailscale/corp#26353
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I95a3e3d72619389ae34a6547ebf47043445374e1
The machine API docs were still often referring to the nacl boxes
which are no longer present in the client. Fix that up, fix the paths,
add the HTTP methods.
And then delete some unused code I found in the process.
Updates #cleanup
Change-Id: I1591274acbb00a08b7ca4879dfebd5e6b8a9fbcd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This fork golang.org/x/crypto/ssh (at upstream x/crypto git rev e47973b1c1)
into tailscale.com/tempfork/sshtest/ssh so we can hack up the client in weird
ways to simulate other SSH clients seen in the wild.
Two changes were made to the files when they were copied from x/crypto:
* internal/poly1305 imports were replaced by the non-internal version;
no code changes otherwise. It didn't need the internal one.
* all decode-with-passphrase funcs were deleted, to avoid
using the internal package x/crypto/ssh/internal/bcrypt_pbkdf
Then the tests passed.
Updates #14969
Change-Id: Ibf1abebfe608c75fef4da0255314f65e54ce5077
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
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>
When in tun mode on Linux, AllowedIPs are not automatically added to
netstack because the kernel is responsible for handling subnet routes.
This ensures that virtual IPs are always added to netstack.
When in tun mode, pings were also not being handled, so this adds
explicit support for ping as well.
Fixestailscale/corp#26387
Change-Id: I6af02848bf2572701288125f247d1eaa6f661107
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
These tunings reduced memory usage while the implementation was
struggling with earlier bugs, but will no longer be necessary after
those bugs are addressed.
Depends #14933
Depends #14934
Updates #9707
Updates #10408
Updates tailscale/corp#24483
Updates tailscale/corp#25169
Signed-off-by: James Tucker <james@tailscale.com>
Cubic performs better than Reno in higher BDP scenarios, and enables the
use of the hystart++ implementation contributed by Coder. This improves
throughput on higher BDP links with a much faster ramp.
gVisor is bumped as well for some fixes related to send queue processing
and RTT tracking.
Updates #9707
Updates #10408
Updates #12393
Updates tailscale/corp#24483
Updates tailscale/corp#25169
Signed-off-by: James Tucker <james@tailscale.com>
Originally identified by Coder and documented in their blog post, this
implementation differs slightly as our link endpoint was introduced for
a different purpose, but the behavior is the same: apply backpressure
rather than dropping packets. This reduces the negative impact of large
packet count bursts substantially. An alternative would be to swell the
size of the channel buffer substantially, however that's largely just
moving where buffering occurs and may lead to reduced signalling back to
lower layer or upstream congestion controls.
Updates #9707
Updates #10408
Updates #12393
Updates tailscale/corp#24483
Updates tailscale/corp#25169
Signed-off-by: James Tucker <james@tailscale.com>
The gVisor RACK implementation appears to perfom badly, particularly in
scenarios with higher BDP. This may have gone poorly noticed as a result
of it being gated on SACK, which is not enabled by default in upstream
gVisor, but itself has a higher positive impact on performance. Both the
RACK and DACK implementations (which are now one) have overlapping
non-completion of tasks in their work streams on the public tracker.
Updates #9707
Signed-off-by: James Tucker <james@tailscale.com>
Incorrect disabled support for not having a mesh key in
d5316a4fbb
Allow for no mesh key to be set.
Fixes#14928
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Since dynamic reload of setec is not supported
in derper at this time, close the server after
the secret is loaded.
Updates tailscale/corp#25756
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
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>
It was moved in f57fa3cbc3.
Updates tailscale/corp#22748
Change-Id: I19f965e6bded1d4c919310aa5b864f2de0cd6220
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
localclient_aliases.go was missing some package level functions from client/local.
This adds them.
Updates tailscale/corp#22748
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Shells on OpenBSD don't support the -l option. This means that when
handling SSH in-process, we can't give the user a login shell, but this
change at least allows connecting at all.
Updates #13338
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Something I accidentally added in #14217.
It doesn't seem to impact Intune or the Administrative Templates MMC extension,
but it should still be fixed.
Updates #cleanup
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Shells on FreeBSD don't support the -l option. This means that when
handling SSH in-process, we can't give the user a login shell, but this
change at least allows connecting at all.
Updates #13338
Signed-off-by: Percy Wegmann <percy@tailscale.com>
A previous PR accidentally logged the key as part
of an error. Remove logging of the key.
Add log print for Setec store steup.
Updates tailscale/corp#25756
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Add setec secret support for derper.
Support dev mode via env var, and setec via secrets URL.
For backwards compatibility use setec load from file also.
Updates tailscale/corp#25756
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
When running via tsnet, c2n will be hooked up so requests to update can
reach the node. But it will then apply whatever OS-specific update
function, upgrading the local tailscaled instead.
We can't update tsnet automatically, so refuse it.
Fixes#14892
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
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>
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>
This change:
- reinstates the HA Ingress controller that was disabled for 1.80 release
- fixes the API calls to manage VIPServices as the API was changed
- triggers the HA Ingress reconciler on ProxyGroup changes
Updates tailscale/tailscale#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
We once again have a report of a panic from ParseRIB. This panic guard
should probably remain permanent.
Updates #14201
This reverts commit de9d4b2f88.
Signed-off-by: James Tucker <james@tailscale.com>
Without adding this, the packet filter rejects traffic to VIP service
addresses before checking the filters sent in the netmap.
Fixestailscale/corp#26241
Change-Id: Idd54448048e9b786cf4873fd33b3b21e03d3ad4c
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
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>
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>
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>
Dots are not allowed in metric names and cause panics. Since we use dots in names like
AlwaysOn.OverrideWithReason, let's replace them with underscores. We don’t want to use
setting.KeyPathSeparator here just yet to make it fully hierarchical, but we will decide as
we progress on the (experimental) AlwaysOn.* policy settings.
tailscale/corp#26146
Signed-off-by: Nick Khyl <nickk@tailscale.com>
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>
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>
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>
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>
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>
SliceEqualAnyOrderFunc had an optimization missing from SliceEqualAnyOrder.
Now they share the same code and both have the optimization.
Updates #14593
Change-Id: I550726e0964fc4006e77bb44addc67be989c131c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
tailscaled's ipn package writes a collection of keys to state after
authenticating to control, but one at a time. If containerboot happens
to send a SIGTERM signal to tailscaled in the middle of writing those
keys, it may shut down with an inconsistent state Secret and never
recover. While we can't durably fix this with our current single-use
auth keys (no atomic operation to auth + write state), we can reduce
the window for this race condition by checking for partial state
before sending SIGTERM to tailscaled. Best effort only.
Updates #14080
Change-Id: I0532d51b6f0b7d391e538468bd6a0a80dbe1d9f7
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Some probes might need to run for longer than their scheduling interval,
so this change relaxes the 1-at-a-time restriction, allowing us to
configure probe concurrency and timeout separately. The default values
remain the same (concurrency of 1; timeout of 80% of interval).
Updates tailscale/corp#25479
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
The HA Ingress functionality is not actually doing anything
valuable yet, so don't run the controller in 1.80 release yet.
Updates tailscale/tailscale#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This change builds on top of #14436 to ensure minimum downtime during egress ProxyGroup update rollouts:
- adds a readiness gate for ProxyGroup replicas that prevents kubelet from marking
the replica Pod as ready before a corresponding readiness condition has been added
to the Pod
- adds a reconciler that reconciles egress ProxyGroup Pods and, for each that is not ready,
if cluster traffic for relevant egress endpoints is routed via this Pod- if so add the
readiness condition to allow kubelet to mark the Pod as ready.
During the sequenced StatefulSet update rollouts kubelet does not restart
a Pod before the previous replica has been updated and marked as ready, so
ensuring that a replica is not marked as ready allows to avoid a temporary
post-update situation where all replicas have been restarted, but none of the
new ones are yet set up as an endpoint for the egress service, so cluster traffic is dropped.
Updates tailscale/tailscale#14326
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
For 9dd6af1f6d
Update client/web and safeweb to correctly signal to the csrf middleware
whether the request is being served over TLS. This determines whether
Origin and Referer header checks are strictly enforced. The gorilla
library previously did not enforce these checks due to a logic bug based
on erroneous use of the net/http.Request API. The patch to fix this also
inverts the library behavior to presume that every request is being
served over TLS, necessitating these changes.
Updates tailscale/corp#25340
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Co-authored-by: Patrick O'Doherty <patrick@tailscale.com>
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>
Fixes the configfile reload logic- if the tailscale capver can not
yet be determined because the device info is not yet written to the
state Secret, don't assume that the proxy is pre-110.
Updates tailscale/tailscale#13032
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
cmd/{containerboot,k8s-operator},kube: add preshutdown hook for egress PG proxies
This change is part of work towards minimizing downtime during update
rollouts of egress ProxyGroup replicas.
This change:
- updates the containerboot health check logic to return Pod IP in headers,
if set
- always runs the health check for egress PG proxies
- updates ClusterIP Services created for PG egress endpoints to include
the health check endpoint
- implements preshutdown endpoint in proxies. The preshutdown endpoint
logic waits till, for all currently configured egress services, the ClusterIP
Service health check endpoint is no longer returned by the shutting-down Pod
(by looking at the new Pod IP header).
- ensures that kubelet is configured to call the preshutdown endpoint
This reduces the possibility that, as replicas are terminated during an update,
a replica gets terminated to which cluster traffic is still being routed via
the ClusterIP Service because kube proxy has not yet updated routig rules.
This is not a perfect check as in practice, it only checks that the kube
proxy on the node on which the proxy runs has updated rules. However, overall
this might be good enough.
The preshutdown logic is disabled if users have configured a custom health check
port via TS_LOCAL_ADDR_PORT env var. This change throws a warnign if so and in
future setting of that env var for operator proxies might be disallowed (as users
shouldn't need to configure this for a Pod directly).
This is backwards compatible with earlier proxy versions.
Updates tailscale/tailscale#14326
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This was flagged by @tkhattra on the merge commit; thanks!
Updates tailscale/corp#25479
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ia8045640f02bd4dcc0fe7433249fd72ac6b9cf52
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>
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>
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>
Previously we were depending on the GUI(s) to do it.
By doing it in tailscaled, GUIs can be simplified and be
guaranteed to render consistent results.
If warnable A depends on warnable B, if both A & B are unhealhy, only
B will be shown to the GUI as unhealthy. Once B clears up, only then
will A be presented as unhealthy.
Updates #14687
Change-Id: Id8566f2672d8d2d699740fa053d4e2a2c8009e83
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The c2n handling code was using the Go httptest package's
ResponseRecorder code but that's in a test package which brings in
Go's test certs, etc.
This forks the httptest recorder type into its own package that only
has the recorder and adds a test that we don't re-introduce a
dependency on httptest.
Updates #12614
Change-Id: I3546f49972981e21813ece9064cc2be0b74f4b16
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The hiding of internal packages has hidden things I wanted to see a
few times now. Stop hiding them. This makes depaware.txt output a bit
longer, but not too much. Plus we only really look at it with diffs &
greps anyway; it's not like anybody reads the whole thing.
Updates #12614
Change-Id: I868c89eeeddcaaab63e82371651003629bc9bda8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This protects against rearranging packages and not catching that a BadDeps
package got moved. That would then effectively remove a test.
Updates #12614
Change-Id: I257f1eeda9e3569c867b7628d5bfb252d3354ba6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The AsDebugJSON method (used only for a LocalAPI debug call) always
needed to be updated whenever a new controlknob was added. We had a
test for it, which was nice, but it was a tedious step we don't need
to do. Use reflect instead.
Updates #14788
Change-Id: If59cd776920f3ce7c748f86ed2eddd9323039a0b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
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>
Some natc instances have been observed with excessive memory growth,
dominant in gvisor buffers. It is likely that the connection buffers are
sticking around for too long due to the default long segment time, and
uptuned buffer size applied by default in wgengine/netstack. Apply
configurations in natc specifically which are a better match for the
natc use case, most notably a 5s maximum segment lifetime.
Updates tailscale/corp#25169
Signed-off-by: James Tucker <james@tailscale.com>
Manually update the `web-client-prebuilt` package as the GitHub action
is failing for some reason.
Updates https://github.com/tailscale/tailscale/issues/14568
Signed-off-by: Mario Minardi <mario@tailscale.com>
Removing the advanced options collapsible from the web client login for
now ahead of our next client release.
Updates https://github.com/tailscale/tailscale/issues/14568
Signed-off-by: Mario Minardi <mario@tailscale.com>
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>
The timeout still defaults to 2 seconds, but can now be changed via command-line flag.
Updates tailscale/corp#26045
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This interface is used both by the DERP client as well as the server.
Defining the interface in derp.go makes it clear that it is shared.
Updates tailscale/corp#26045
Signed-off-by: Percy Wegmann <percy@tailscale.com>
3dabea0fc2 added some docs with inconsistent usage docs.
This fixes them, and adds a test.
It also adds some other tests and fixes other verb tense
inconsistencies.
Updates tailscale/corp#25278
Change-Id: I94c2a8940791bddd7c35c1c3d5fb791a317370c2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In v1.78, we started acquiring the GP lock when reading policy settings. This led to a deadlock during
Tailscale installation via Group Policy Software Installation because the GP engine holds the write lock
for the duration of policy processing, which in turn waits for the installation to complete, which in turn
waits for the service to enter the running state.
In this PR, we prevent the acquisition of GP locks (aka EnterCriticalPolicySection) during service startup
and update the Windows Registry-based util/syspolicy/source.PlatformPolicyStore to handle this failure
gracefully. The GP lock is somewhat optional; it’s safe to read policy settings without it, but acquiring
the lock is recommended when reading multiple values to prevent the Group Policy engine from modifying
settings mid-read and to avoid inconsistent results.
Fixes#14416
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This was a slow memory leak on busy tailnets with lots of tagged
ephemeral nodes.
Updates tailscale/corp#26058
Change-Id: I298e7d438e3ffbb3cde795640e344671d244c632
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Still behind the same ts_omit_tap build tag.
See #14738 for background on the pattern.
Updates #12614
Change-Id: I03fb3d2bf137111e727415bd8e713d8568156ecc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
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>
Remove "unexpected" labelling of PeerGoneReasonNotHere.
A peer being no longer connected to a DERP server
is not an unexpected case and causes confusion in looking at logs.
Fixestailscale/corp#25609
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
The new ProxyGroup-based Ingress reconciler is causing a fatal log at
startup because it has the same name as the existing Ingress reconciler.
Explicitly name both to ensure they have unique names that are consistent
with other explicitly named reconcilers.
Updates #14583
Change-Id: Ie76e3eaf3a96b1cec3d3615ea254a847447372ea
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
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>
* 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/25965Fixes#14606
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
---------
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Updates tailscale/corp#25278
Adds definitions for new CLI commands getting added in v1.80. Refactors some pre-existing CLI commands within the `configure` tree to clean up code.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
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>
This commit intend to provide support for TCP and Web VIP services and also allow user to use Tun
for VIP services if they want to.
The commit includes:
1.Setting TCP intercept function for VIP Services.
2.Update netstack to send packet written from WG to netStack handler for VIP service.
3.Return correct TCP hander for VIP services when netstack acceptTCP.
This commit also includes unit tests for if the local backend setServeConfig would set correct TCP intercept
function and test if a hander gets returned when getting TCPHandlerForDst. The shouldProcessInbound
check is not unit tested since the test result just depends on mocked functions. There should be an integration
test to cover shouldProcessInbound and if the returned TCP handler actually does what the serveConfig says.
Updates tailscale/corp#24604
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
We previously baked in the LetsEncrypt x509 root CA for our tlsdial
package.
This moves that out into a new "bakedroots" package and is now also
shared by ipn/ipnlocal's cert validation code (validCertPEM) that
decides whether it's time to fetch a new cert.
Otherwise, a machine without LetsEncrypt roots locally in its system
roots is unable to use tailscale cert/serve and fetch certs.
Fixes#14690
Change-Id: Ic88b3bdaabe25d56b9ff07ada56a27e3f11d7159
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Both @agottardo and I tripped over this today.
Updates #cleanup
Change-Id: I64380a03bfc952b9887b1512dbcadf26499ff1cd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If unable to accept a connection from the bandwidth probe listener,
return from the goroutine immediately since the accepted connection
will be nil.
Updates tailscale/corp#25958
Signed-off-by: Percy Wegmann <percy@tailscale.com>
I saw this panic while writing a new test for #14715:
panic: send on closed channel
goroutine 826 [running]:
tailscale.com/tsnet.(*listener).handle(0x1400031a500, {0x1035fbb00, 0x14000b82300})
/Users/bradfitz/src/tailscale.com/tsnet/tsnet.go:1317 +0xac
tailscale.com/wgengine/netstack.(*Impl).acceptTCP(0x14000204700, 0x14000882100)
/Users/bradfitz/src/tailscale.com/wgengine/netstack/netstack.go:1320 +0x6dc
created by gvisor.dev/gvisor/pkg/tcpip/transport/tcp.(*Forwarder).HandlePacket in goroutine 807
/Users/bradfitz/go/pkg/mod/gvisor.dev/gvisor@v0.0.0-20240722211153-64c016c92987/pkg/tcpip/transport/tcp/forwarder.go:98 +0x32c
FAIL tailscale.com/tsnet 0.927s
Updates #14715
Change-Id: I9924e0a6c2b801d46ee44eb8eeea0da2f9ea17c4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
cmd/k8s-operator: add logic to parse L7 Ingresses in HA mode
- Wrap the Tailscale API client used by the Kubernetes Operator
into a client that knows how to manage VIPServices.
- Create/Delete VIPServices and update serve config for L7 Ingresses
for ProxyGroup.
- Ensure that ingress ProxyGroup proxies mount serve config from a shared ConfigMap.
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Adds a new Hostinfo.IngressEnabled bool field that holds whether
funnel is currently enabled for the node. Triggers control update
when this value changes.
Bumps capver so that control can distinguish the new field being false
vs non-existant in previous clients.
This is part of a fix for an issue where nodes with any AllowFunnel
block set in their serve config are being displayed as if actively
routing funnel traffic in the admin panel.
Updates tailscale/tailscale#11572
Updates tailscale/corp#25931
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
We throw error early with a warning if users attempt to enable background funnel
for a node that does not allow incoming connections
(shields up), but if it done in foreground mode, we just silently fail
(the funnel command succeeds, but the connections are not allowed).
This change makes sure that we also error early in foreground mode.
Updates tailscale/tailscale#11049
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Updates tailscale/corp#25936
This defines a new syspolicy 'Hostname' and allows an IT administrator to override the value we normally read from os.Hostname(). This is particularly useful on Android and iOS devices, where the hostname we get from the OS is really just the device model (a platform restriction to prevent fingerprinting).
If we don't implement this, all devices on the customer's side will look like `google-pixel-7a-1`, `google-pixel-7a-2`, `google-pixel-7a-3`, etc. and it is not feasible for the customer to use the API or worse the admin console to manually fix these names.
Apply code review comment by @nickkhyl
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Co-authored-by: Nick Khyl <1761190+nickkhyl@users.noreply.github.com>
Since 5297bd2cff, tstun.Wrapper has required its Start
method to be called for it to function. Failure to do so just
results in weird hangs and I've wasted too much time multiple
times now debugging. Hopefully this prevents more lost time.
Updates tailscale/corp#24454
Change-Id: I87f4539f7be7dc154627f8835a37a8db88c31be0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Metrics currently exist for dropped packets by reason, and total
received packets by kind (e.g., `disco` or `other`), but relating these
two together to gleam information about the drop rate for specific
reasons on a per-kind basis is not currently possible.
Change `derp_packets_dropped` to use a `metrics.MultiLabelMap` to
track both the `reason` and `kind` in the same metric to allow for this
desired level of granularity.
Drop metrics that this makes unnecessary (namely `packetsDroppedReason`
and `packetsDroppedType`).
Updates https://github.com/tailscale/corp/issues/25489
Signed-off-by: Mario Minardi <mario@tailscale.com>
Most users should not run into this because it's set in the helm chart
and the deploy manifest, but if namespace is not set we get confusing
authz errors because the kube client tries to fetch some namespaced resources
as though they're cluster-scoped and reports permission denied. Try to
detect namespace from the default projected volume, and otherwise fatal.
Fixes #cleanup
Change-Id: I64b34191e440b61204b9ad30bbfa117abbbe09c3
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
If the server was in use at the time of the initial check, but disconnected and was removed
from the activeReqs map by the time we registered a waiter, the ready channel will never
be closed, resulting in a deadlock. To avoid this, we check whether the server is still busy
after registering the wait.
Fixes#14655
Signed-off-by: Nick Khyl <nickk@tailscale.com>
I made a last-minute change in #14626 to split a single loop that created 1_000 concurrent
connections into an inner and outer loop that create 100 concurrent connections 10 times.
This introduced a race because the last user's connection may still be active (from the server's
perspective) when a new outer iteration begins. Since every new client gets a unique ClientID,
but we reuse usernames and UIDs, the server may let a user in (as the UID matches, which is fine),
but the test might then fail due to a ClientID mismatch:
server_test.go:232: CurrentUser(Initial): got &{S-1-5-21-1-0-0-1001 User-4 <nil> Client-2 false false};
want &{S-1-5-21-1-0-0-1001 User-4 <nil> Client-114 false false}
In this PR, we update (*testIPNServer).blockWhileInUse to check whether the server is currently busy
and wait until it frees up. We then call blockWhileInUse at the end of each outer iteration so that the server
is always in a known idle state at the beginning of the inner loop. We also check that the current user
is not set when the server is idle.
Updates tailscale/corp#25804
Updates #14655 (found when working on it)
Signed-off-by: Nick Khyl <nickk@tailscale.com>
As we look to add github.com/prometheus/client_golang/prometheus to
more parts of the codebase, lock in that we don't use it in tailscaled,
primarily for binary size reasons.
Updates #12614
Change-Id: I03c100d12a05019a22bdc23ce5c4df63d5a03ec6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This test verifies, among other things, that init functions cannot be deferred after (*DeferredFuncs).Do
has already been called and that all subsequent calls to (*DeferredFuncs).Defer return false.
However, the initial implementation of this check was racy: by the time (*DeferredFuncs).Do returned,
not all goroutines that successfully deferred an init function may have incremented the atomic variable
tracking the number of deferred functions. As a result, the variable's value could differ immediately
after (*DeferredFuncs).Do returned and after all goroutines had completed execution (i.e., after wg.Wait()).
In this PR, we replace the original racy check with a different one. Although this new check is also racy,
it can only produce false negatives. This means that if the test fails, it indicates an actual bug rather than
a flaky test.
Fixes#14039
Signed-off-by: Nick Khyl <nickk@tailscale.com>
There's at least one example of stored routes and advertised routes
getting out of sync. I don't know how they got there yet, but this would
backfill missing advertised routes on startup from stored routes.
Also add logging in LocalBackend.AdvertiseRoute to record when new
routes actually get put into prefs.
Updates #14606
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
I moved the actual rename into separate, GOOS-specific files. On
non-Windows, we do a simple os.Rename. On Windows, we first try
ReplaceFile with a fallback to os.Rename if the target file does
not exist.
ReplaceFile is the recommended way to rename the file in this use case,
as it preserves attributes and ACLs set on the target file.
Updates #14428
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
The --mesh-with flag now supports the specification of hostname tuples like
derp1a.tailscale.com/derp1a-vpc.tailscale.com, which instructs derp to mesh
with host 'derp1a.tailscale.com' but dial TCP connections to 'derp1a-vpc.tailscale.com'.
For backwards compatibility, --mesh-with still supports individual hostnames.
The logic which attempts to auto-discover '[host]-vpc.tailscale.com' dial hosts
has been removed.
Updates tailscale/corp#25653
Signed-off-by: Percy Wegmann <percy@tailscale.com>
We have observed some clients with extremely large lists of IPv6
endpoints, in some cases from subnets where the machine also has the
zero address for a whole /48 with then arbitrary addresses additionally
assigned within that /48. It is in general unnecessary for reachability
to report all of these addresses, typically only one will be necessary
for reachability. We report two, to cover some other common cases such
as some styles of IPv6 private address rotations.
Updates tailscale/corp#25850
Signed-off-by: James Tucker <james@tailscale.com>
In this commit, we add a failing test to verify that ipn/ipnserver.Server correctly
sets and unsets the current user when two different clients send requests concurrently
(A sends request, B sends request, A's request completes, B's request completes).
The expectation is that the user who wins the race becomes the current user
from the LocalBackend's perspective, remaining in this state until they disconnect,
after which a different user should be able to connect and use the LocalBackend.
We then fix the second of two bugs in (*Server).addActiveHTTPRequest, where a race
condition causes the LocalBackend's state to be reset after a new client connects,
instead of after the last active request of the previous client completes and the server
becomes idle.
Fixestailscale/corp#25804
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this commit, we add a failing test to verify that ipn/ipnserver.Server correctly
sets and unsets the current user when two different users connect sequentially
(A connects, A disconnects, B connects, B disconnects).
We then fix the test by updating (*ipn/ipnserver.Server).addActiveHTTPRequest
to avoid calling (*LocalBackend).ResetForClientDisconnect again after a new user
has connected and been set as the current user with (*LocalBackend).SetCurrentUser().
Since ipn/ipnserver.Server does not allow simultaneous connections from different
Windows users and relies on the LocalBackend's current user, and since we already
reset the LocalBackend's state by calling ResetForClientDisconnect when the last
active request completes (indicating the server is idle and can accept connections
from any Windows user), it is unnecessary to track the last connected user on the
ipnserver.Server side or call ResetForClientDisconnect again when the user changes.
Additionally, the second call to ResetForClientDisconnect occurs after the new user
has been set as the current user, resetting the correct state for the new user
instead of the old state of the now-disconnected user, causing issues.
Updates tailscale/corp#25804
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We update client/tailscale.LocalClient to allow specifying an optional Transport
(http.RoundTripper) for LocalAPI HTTP requests, and implement one that injects
an ipnauth.TestActor via request headers. We also add several functions and types
to make testing an ipn/ipnserver.Server possible (or at least easier).
We then use these updates to write basic tests for ipnserver.Server,
ensuring it works on non-Windows platforms and correctly sets and unsets
the LocalBackend's current user when a Windows user connects and disconnects.
We intentionally omit tests for switching between different OS users
and will add them in follow-up commits.
Updates tailscale/corp#25804
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In preparation for adding test coverage for ipn/ipnserver.Server, we update it
to use ipnauth.Actor instead of its concrete implementation where possible.
Updates tailscale/corp#25804
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We build up maps of both the existing MagicDNS configuration in hosts
and the desired MagicDNS configuration, compare the two, and only
write out a new one if there are changes. The comparison doesn't need
to be perfect, as the occasional false-positive is fine, but this
should greatly reduce rewrites of the hosts file.
I also changed the hosts updating code to remove the CRLF/LF conversion
stuff, and use Fprintf instead of Frintln to let us write those inline.
Updates #14428
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This deprecates the old "DERP string" packing a DERP region ID into an
IP:port of 127.3.3.40:$REGION_ID and just uses an integer, like
PeerChange.DERPRegion does.
We still support servers sending the old form; they're converted to
the new form internally right when they're read off the network.
Updates #14636
Change-Id: I9427ec071f02a2c6d75ccb0fcbf0ecff9f19f26f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This doesn't seem to have any immediate impact, but not allowing access via the IPv6 masquerade
address when an IPv4 masquerade address is also set seems like a bug.
Updates #cleanup
Updates #14570 (found when working on it)
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This finishes the work started in #14616.
Updates #8632
Change-Id: I4dc07d45b1e00c3db32217c03b21b8b1ec19e782
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In this PR, we add a generic views.ValuePointer type that can be used as a view for pointers
to basic types and struct types that do not require deep cloning and do not have corresponding
view types. Its Get/GetOk methods return stack-allocated shallow copies of the underlying value.
We then update the cmd/viewer codegen to produce getters that return either concrete views
when available or ValuePointer views when not, for pointer fields in generated view types.
This allows us to avoid unnecessary allocations compared to returning pointers to newly
allocated shallow copies.
Updates #14570
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This amends commit b7e48058c8.
That commit broke all documented ways of starting Tailscale on gokrazy:
https://gokrazy.org/packages/tailscale/ — both Option A (tailscale up)
and Option B (tailscale up --auth-key) rely on the tailscale CLI working.
I verified that the tailscale CLI just prints it help when started
without arguments, i.e. it does not stay running and is not restarted.
I verified that the tailscale CLI successfully exits when started with
tailscale up --auth-key, regardless of whether the node has joined
the tailnet yet or not.
I verified that the tailscale CLI successfully waits and exits when
started with tailscale up, as expected.
fixes https://github.com/gokrazy/gokrazy/issues/286
Signed-off-by: Michael Stapelberg <michael@stapelberg.de>
This will enable Prometheus queries to look at the bandwidth over time windows,
for example 'increase(derp_bw_bytes_total)[1h] / increase(derp_bw_transfer_time_seconds_total)[1h]'.
Fixes commit a51672cafd.
Updates tailscale/corp#25503
Signed-off-by: Percy Wegmann <percy@tailscale.com>
We still use josharian/native (hi @josharian!) via
netlink, but I also sent https://github.com/mdlayher/netlink/pull/220
Updates #8632
Change-Id: I2eedcb7facb36ec894aee7f152c8a1f56d7fc8ba
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
sync.OnceValue and slices.Compact were both added in Go 1.21.
cmp.Or was added in Go 1.22.
Updates #8632
Updates #11058
Change-Id: I89ba4c404f40188e1f8a9566c8aaa049be377754
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Bump the versions to pick up some CVE patches. They don't affect us, but
customer scanners will complain.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This commit updates the return body of c2n endpoint /vip-services to keep hash generation logic on client side.
Updates tailscale/corp#24510
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
Most of these are effectively no-ops, but appease security scanners.
At least one (x/net for x/net/html) only affect builds from the open source repo,
since we already had it updated in our "corp" repo:
golang.org/x/net v0.33.1-0.20241230221519-e9d95ba163f7
... and that's where we do the official releases from. e.g.
tailscale.io % go install tailscale.com/cmd/tailscaled
tailscale.io % go version -m ~/go/bin/tailscaled | grep x/net
dep golang.org/x/net v0.33.1-0.20241230221519-e9d95ba163f7 h1:raAbYgZplPuXQ6s7jPklBFBmmLh6LjnFaJdp3xR2ljY=
tailscale.io % cd ../tailscale.com
tailscale.com % go install tailscale.com/cmd/tailscaled
tailscale.com % go version -m ~/go/bin/tailscaled | grep x/net
dep golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
Updates #8043
Updates #14599
Change-Id: I6e238cef62ca22444145a5313554aab8709b33c9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
cmd/containerboot: load containerboot serve config that does not contain HTTPS endpoint in tailnets with HTTPS disabled
Fixes an issue where, if a tailnet has HTTPS disabled, no serve config
set via TS_SERVE_CONFIG was loaded, even if it does not contain an HTTPS endpoint.
Now for tailnets with HTTPS disabled serve config provided to containerboot is considered invalid
(and therefore not loaded) only if there is an HTTPS endpoint defined in the config.
Fixestailscale/tailscale#14495
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
cmd/{k8s-operator,containerboot}: reload tailscaled configfile when its contents have changed
Instead of restarting the Kubernetes Operator proxies each time
tailscaled config has changed, this dynamically reloads the configfile
using the new reload endpoint.
Older annotation based mechanism will be supported till 1.84
to ensure that proxy versions prior to 1.80 keep working with
operator 1.80 and newer.
Updates tailscale/tailscale#13032
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
If the total number of differences is less than a small amount, just do
the dumb quadratic thing and compare every single object instead of
allocating a map.
Updates tailscale/corp#25479
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8931b4355a2da4ec0f19739927311cf88711a840
Extracted from some code written in the other repo.
Updates tailscale/corp#25479
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I6df062fdffa1705524caa44ac3b6f2788cf64595
This will enable Prometheus queries to look at the bandwidth over time windows,
for example 'increase(derp_bw_bytes_total)[1h] / increase(derp_bw_transfer_time_seconds_total)[1h]'.
Updates tailscale/corp#25503
Signed-off-by: Percy Wegmann <percy@tailscale.com>
* cmd/k8s-operator,k8s-operator: allow users to set custom labels for the optional ServiceMonitor
Updates tailscale/tailscale#14381
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
govulncheck flagged a couple fresh vulns in that package:
* https://pkg.go.dev/vuln/GO-2025-3367
* https://pkg.go.dev/vuln/GO-2025-3368
I don't believe these affect us, as we only do any git stuff from
release tooling which is all internal and with hardcoded repo URLs.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Change the type of the `IPv4` and `IPv6` members in the `nodeData`
struct to be `netip.Addr` instead of `string`.
We were previously calling `String()` on this struct, which returns
"invalid IP" when the `netip.Addr` is its zero value, and passing this
value into the aforementioned attributes.
This caused rendering issues on the frontend
as we were assuming that the value for `IPv4` and `IPv6` would be falsy
in this case.
The zero value for a `netip.Addr` marshalls to an empty string instead
which is the behaviour we want downstream.
Updates https://github.com/tailscale/tailscale/issues/14568
Signed-off-by: Mario Minardi <mario@tailscale.com>
Extracted from some code written in the other repo.
Updates tailscale/corp#25479
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I92c97a63a8f35cace6e89a730938ea587dcefd9b
Currently this does not yet do anything apart from creating
the ProxyGroup resources like StatefulSet.
Updates tailscale/corp#24795
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit updates the VIPService c2n endpoint on client to response with actual VIPService configuration stored
in the serve config.
Fixestailscale/corp#24510
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
These erroneously blocked a recent PR, which I fixed by simply
re-running CI. But we might as well fix them anyway.
These are mostly `printf` to `print` and a couple of `!=` to `!Equal()`
Updates #cleanup
Signed-off-by: Will Norris <will@tailscale.com>
Remove the platform specificity, it is unnecessary complexity.
Deduplicate repeated code as a result of reduced complexity.
Split out error identification code.
Update call-sites and tests.
Updates #14551
Updates tailscale/corp#25648
Signed-off-by: James Tucker <james@tailscale.com>
Fixestailscale/tailscale#14563
When creating a NoiseClient, ensure that if any private IP address is provided, with both an `http` scheme and an explicit port number, we do not ever attempt to use HTTPS. We were only handling the case of `127.0.0.1` and `localhost`, but `192.168.x.y` is a private IP as well. This uses the `netip` package to check and adds some logging in case we ever need to troubleshoot this.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Observed in the wild some macOS machines gain broken sockets coming out
of sleep (we observe "time jumped", followed by EPIPE on sendto). The
cause of this in the platform is unclear, but the fix is clear: always
rebind if the socket is broken. This can also be created artificially on
Linux via `ss -K`, and other conditions or software on a system could
also lead to the same outcomes.
Updates tailscale/corp#25648
Signed-off-by: James Tucker <james@tailscale.com>
In the process, because I needed it for testing, make all
LocalBackend-managed goroutines be accounted for. And then in tests,
verify they're no longer running during LocalBackend.Shutdown.
Updates tailscale/corp#19681
Change-Id: Iad873d4df7d30103a4a7863dfacf9e078c77e6a3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates #14520
Updates #14517 (in that I pulled this out of there)
Change-Id: Ibc28162816e083fcadf550586c06805c76e378fc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was failing about an unaccepted risk ("mac-app-connector") because
it was checking runtime.GOOS ("darwin") instead of the test's env.goos
string value ("linux", which doesn't have the warning).
Fixes#14544
Change-Id: I470d86a6ad4bb18e1dd99d334538e56556147835
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates #cleanup
Updates #1909 (noticed while working on that)
Change-Id: I505001e5294287ad2a937b4db61d9e67de70fa14
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Fixes#14492
-----
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
Change-Id: I6dc1068d34bbfa7477e7b7a56a4325b3868c92e1
Signed-off-by: Marc Paquette <marcphilippaquette@gmail.com>
These were the last two Range funcs in this repo.
Updates #12912
Change-Id: I6ba0a911933cb5fc4e43697a9aac58a8035f9622
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The remaining range funcs in the tree are RangeOverTCPs and
RangeOverWebs in ServeConfig; those will be cleaned up separately.
Updates #12912
Change-Id: Ieeae4864ab088877263c36b805f77aa8e6be938d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And misc cleanup along the way.
Updates #12912
Change-Id: I0cab148b49efc668c6f5cdf09c740b84a713e388
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
While working on #13390, I ran across this non-idiomatic
pointer-to-view and parallel-sorted-map accounting code that was all
just to avoid a sort later.
But the sort later when building a new netmap.NetworkMap is already a
drop in the bucket of CPU compared to how much work & allocs
mapSession.netmap and LocalBackend's spamming of the full netmap
(potentially tens of thousands of peers, MBs of JSON) out to IPNBus
clients for any tiny little change (node changing online status, etc).
Removing the parallel sorted slice let everything be simpler to reason
about, so this does that. The sort might take a bit more CPU time now
in theory, but in practice for any netmap size for which it'd matter,
the quadratic netmap IPN bus spam (which we need to fix soon) will
overshadow that little sort.
Updates #13390
Updates #1909
Change-Id: I3092d7c67dc10b2a0f141496fe0e7e98ccc07712
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Importing the ~deprecated golang.org/x/exp/maps as "xmaps" to not
shadow the std "maps" was getting ugly.
And using slices.Collect on an iterator is verbose & allocates more.
So copy (x)maps.Keys+Values into our slicesx package instead.
Updates #cleanup
Updates #12912
Updates #14514 (pulled out of that change)
Change-Id: I5e68d12729934de93cf4a9cd87c367645f86123a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Using context.CancelFunc as the type (instead of func()) answers
questions like whether it's okay to call it multiple times, whether
it blocks, etc. And that's the type it actually is in this case.
Updates #cleanup
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On Linux, systray.SetTitle actually seems to set the tooltip on all
desktops I've tested on. But on macOS, it actually does set a title
that is always displayed in the systray area next to the icon. This
change should properly set the tooltip across platforms.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
Move a number of global state vars into the Menu struct, keeping things
better encapsulated. The systray package still relies on its own global
state, so only a single Menu instance can run at a time.
Move a lot of the initialization logic out of onReady, in particular
fetching the latest tailscale state. Instead, populate the state before
calling systray.Run, which fixes a timing issue in GNOME (#14477).
This change also creates a separate bgContext for actions not tied menu
item clicks. Because we have to rebuild the entire menu regularly, we
cancel that context as needed, which can cancel subsequent updateState
calls.
Also exit cleanly on SIGINT and SIGTERM.
Updates #1708Fixes#14477
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
Refactor code to set app icon and title as part of rebuild, rather than
separately in eventLoop. This fixes several cases where they weren't
getting updated properly. This change also makes use of the new exit
node icons.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
restructure tsLogo to allow setting a mask to be used when drawing the
logo dots, as well as add an overlay icon, such as the arrow when
connected to an exit node.
The icon is still renders as white on black, but this change also
prepare for doing a black on white version, as well a fully transparent
icon. I don't know if we can consistently determine which to use, so
this just keeps the single icon for now.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
metrics.LabelMap grows slightly more heavy, needing a lock to ensure
proper ordering for newly initialized ShardedInt values. An Add method
enables callers to use .Add for both expvar.Int and syncs.ShardedInt
values, but retains the original behavior of defaulting to initializing
expvar.Int values.
Updates tailscale/corp#25450
Co-Authored-By: Andrew Dunham <andrew@du.nham.ca>
Signed-off-by: James Tucker <james@tailscale.com>
- rebuild menu when prefs change outside of systray, such as setting an
exit node
- refactor onClick handler code
- compare lowercase country name, the same as macOS and Windows (now
sorts Ukraine before USA)
- fix "connected / disconnected" menu items on stopped status
- prevent nil pointer on "This Device" menu item
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
Noted as useful during review of #14448.
Updates #14457
Change-Id: I0f16f08d5b05a8e9044b19ef6c02d3dab497f131
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Remove EOL Ubuntu versions.
Add new Ubuntu LTS.
Update Alpine to test latest version.
Also, make the test run when its workflow is updated and installer.sh isn't.
Updates #cleanup
Signed-off-by: Erisa A <erisa@tailscale.com>
This commit builds the exit node menu including the recommended exit
node, if available, as well as tailnet and mullvad exit nodes.
This does not yet update the menu based on changes in exit node outside
of the systray app, which will come later. This also does not include
the ability to run as an exit node.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
* tailcfg: rename and retype ServiceHost capability, add value type
Updates tailscale/corp#22743.
In #14046, this was accidentally made a PeerCapability when it
should have been NodeCapability. Also, renaming it to use the
nomenclature that we decided on after #14046 went up, and adding
the type of the value that will be passed down in the RawMessage
for this capability.
This shouldn't break anything, since no one was using this string or
variable yet.
Signed-off-by: Naman Sood <mail@nsood.in>
The new menu delay added to fix libdbusmenu systrays causes problems
with KDE. Given the state of wildly varying systray implementations, I
suspect we may need more desktop-specific hacks, so I'm setting this up
to accommodate that.
Updates #1708
Updates #14431
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
Bring UI closer to macOS and windows:
- split login and tailnet name over separate lines
- render profile picture (with very simple caching)
- use checkbox to indicate active profile. I've not found any desktops
that can't render checkboxes, so I'd like to explore other options
if needed.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
ShardedInt provides an int type expvar.Var that supports more efficient
writes at high frequencies (one order of magnigude on an M1 Max, much
more on NUMA systems).
There are two implementations of ShardValue, one that abuses sync.Pool
that will work on current public Go versions, and one that takes a
dependency on a runtime.TailscaleP function exposed in Tailscale's Go
fork. The sync.Pool variant has about 10x the throughput of a single
atomic integer on an M1 Max, and the runtime.TailscaleP variant is about
10x faster than the sync.Pool variant.
Neither variant have perfect distribution, or perfectly always avoid
cross-CPU sharing, as there is no locking or affinity to ensure that the
time of yield is on the same core as the time of core biasing, but in
the average case the distributions are enough to provide substantially
better performance.
See golang/go#18802 for a related upstream proposal.
Updates tailscale/go#109
Updates tailscale/corp#25450
Signed-off-by: James Tucker <james@tailscale.com>
Some notification managers crop the application icon to a circle, so
ensure we have enough padding to account for that.
Updates #1708
Change-Id: Ia101a4a3005adb9118051b3416f5a64a4a45987d
Signed-off-by: Will Norris <will@tailscale.com>
This new type of probe sends DERP packets sized similarly to CallMeMaybe packets
at a rate of 10 packets per second. It records the round-trip times in a Prometheus
histogram. It also keeps track of how many packets are dropped. Packets that fail to
arrive within 5 seconds are considered dropped.
Updates tailscale/corp#24522
Signed-off-by: Percy Wegmann <percy@tailscale.com>
MutexValue is simply a value guarded by a mutex.
For any type that is not pointer-sized,
MutexValue will perform much better than AtomicValue
since it will not incur an allocation boxing the value
into an interface value (which is how Go's atomic.Value
is implemented under-the-hood).
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This is an experiment to see how useful we will find it to have some
text-based diagrams to document how various components of the operator
work. There are no plans to link to this from elsewhere yet, but
hopefully it will be a useful reference internally.
Updates #cleanup
Change-Id: If5911ed39b09378fec0492e87738ec0cc3d8731e
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
1ed9bd76d6 meant to make tunAddress be optional.
Updates tailscale/corp#24635
Change-Id: Idc4a8540b294e480df5bd291967024c04df751c0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For https://github.com/tailscale/go/pull/108 so we can depend on it in
other repos. (This repo can't yet use it; we permit building
tailscale/tailscale with the latest stock Go release) But that will be
in Go 1.24. We're just impatient elsewhere and would like it in the
control plane code earlier.
Updates tailscale/corp#25406
Change-Id: I53ff367318365c465cbd02cea387c8ff1eb49fab
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The omitzero tag option has been backported to v1 "encoding/json"
from the "encoding/json/v2" prototype and will land in Go1.24.
Until we fully upgrade to Go1.24, adjust the test to be agnostic
to which version of Go someone is using.
Updates tailscale/corp#25406
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The go-httpstat package has a data race when used with connections that
are performing happy-eyeballs connection setups as we are in the DERP
client. There is a long-stale PR upstream to address this, however
revisiting the purpose of this code suggests we don't really need
httpstat here.
The code populates a latency table that may be used to compare to STUN
latency, which is a lightweight RTT check. Switching out the reported
timing here to simply the request HTTP request RTT avoids the
problematic package.
Fixestailscale/corp#25095
Signed-off-by: James Tucker <james@tailscale.com>
When we first made Tailscale SSH, we assumed people would want public
key support soon after. Turns out that hasn't been the case; people
love the Tailscale identity authentication and check mode.
In light of CVE-2024-45337, just remove all our public key code to not
distract people, and to make the code smaller. We can always get it
back from git if needed.
Updates tailscale/corp#25131
Updates golang/go#70779
Co-authored-by: Percy Wegmann <percy@tailscale.com>
Change-Id: I87a6e79c2215158766a81942227a18b247333c22
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The errors emitted by util/dnsname are all written at least moderately
friendly and none of them emit sensitive information. They should be
safe to display to end users.
Updates tailscale/corp#9025
Change-Id: Ic58705075bacf42f56378127532c5f28ff6bfc89
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
The IfElse function is equivalent to the ternary (c ? a : b) operator
in many other languages like C. Unfortunately, this function
cannot perform short-circuit evaluation like in many other languages,
but this is a restriction that's not much different
than the pre-existing cmp.Or function.
The argument against ternary operators in Go is that
nested ternary operators become unreadable
(e.g., (c1 ? (c2 ? a : b) : (c2 ? x : y))).
But a single layer of ternary expressions can sometimes
make code much more readable.
Having the bools.IfElse function gives code authors the
ability to decide whether use of this is more readable or not.
Obviously, code authors will need to be judicious about
their use of this helper function.
Readability is more of an art than a science.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Throughout our codebase we have types that only exist only
to implement an io.Reader or io.Writer, when it would have been
simpler, cleaner, and more readable to use an inlined function literal
that closes over the relevant types.
This is arguably more readable since it keeps the semantic logic
in place rather than have it be isolated elsewhere.
Note that a function literal that closes over some variables
is semantic equivalent to declaring a struct with fields and
having the Read or Write method mutate those fields.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This is the start of an integration/e2e test suite for the tailscale operator.
It currently only tests two major features, ingress proxy and API server proxy,
but we intend to expand it to cover more features over time. It also only
supports manual runs for now. We intend to integrate it into CI checks in a
separate update when we have planned how to securely provide CI with the secrets
required for connecting to a test tailnet.
Updates #12622
Change-Id: I31e464bb49719348b62a563790f2bc2ba165a11b
Co-authored-by: Irbe Krumina <irbe@tailscale.com>
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
A method on kc was called unconditionally, even if was not initialized,
leading to a nil pointer dereference when TS_SERVE_CONFIG was set
outside Kubernetes.
Add a guard symmetric with other uses of the kubeClient.
Fixes#14354.
Signed-off-by: Bjorn Neergaard <bjorn@neersighted.com>
Make dev-mode DERP probes work without TLS. Properly dial port `3340`
when not using HTTPS when dialing nodes in `derphttp_client`. Skip
verifying TLS state in `newConn` if we are not running a prober.
Updates tailscale/corp#24635
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Co-authored-by: Percy Wegmann <percy@tailscale.com>
Use envknob to configure the per client send
queue depth for the derp server.
Fixestailscale/corp#24978
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
Previously this unit test failed if it was run in a container. Update the assert
to focus on exactly the condition we are trying to assert: the package type
should only be 'container' if we use the build tag.
Updates #14317
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Make argparsing use flag for adding a new
parameter that requires parsing.
Enforce a read timeout deadline waiting for response
from the stun server provided in the args. Otherwise
the program will never exit.
Fixes#14267
Signed-off-by: Mike O'Driscoll <mikeo@tailscale.com>
OAuth clients that were used to generate an auth_key previously
specified the scope 'device'. 'device' is not an actual scope,
the real scope is 'devices'. The resulting OAuth token ended up
including all scopes from the specified OAuth client, so the code
was able to successfully create auth_keys.
It's better not to hardcode a scope here anyway, so that we have
the flexibility of changing which scope(s) are used in the future
without having to update old clients.
Since the qualifier never actually did anything, this commit simply
removes it.
Updates tailscale/corp#24934
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This package grew organically over time and
is an awful mix of explicitly declared options and
globally set parameters via environment variables and
other subtle effects.
Add a new Options and TransportOptions type to
allow for the creation of a Policy or http.RoundTripper
with some set of options.
The options struct avoids the need to add yet more
NewXXX functions for every possible combination of
ordered arguments.
The goal of this refactor is to allow specifying the http.Client
to use with the Policy.
Updates tailscale/corp#18177
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
If previousEtag is empty, then we assume control ACLs were not modified
manually and push the local ACLs. Instead, we defaulted to localEtag
which would be different if local ACLs were different from control.
AFAIK this was always buggy, but never reported?
Fixes#14295
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Every so often, the ProxyGroup and other controllers lose an optimistic locking race
with other controllers that update the objects they create. Stop treating
this as an error event, and instead just log an info level log line for it.
Fixes#14072
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This provides an interface for a user to force a preferred DERP outcome
for all future netchecks that will take precedence unless the forced
region is unreachable.
The option does not persist and will be lost when the daemon restarts.
Updates tailscale/corp#18997
Updates tailscale/corp#24755
Signed-off-by: James Tucker <james@tailscale.com>
cmd/containerboot,kube/kubetypes,cmd/k8s-operator: detect if Ingress is created in a tailnet that has no HTTPS
This attempts to make Kubernetes Operator L7 Ingress setup failures more explicit:
- the Ingress resource now only advertises HTTPS endpoint via status.ingress.loadBalancer.hostname when/if the proxy has succesfully loaded serve config
- the proxy attempts to catch cases where HTTPS is disabled for the tailnet and logs a warning
Updates tailscale/tailscale#12079
Updates tailscale/tailscale#10407
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
cmd/k8s-operator/deploy/chart: allow reading OAuth creds from a CSI driver's volume and annotating operator's Service account
Updates #14264
Signed-off-by: Oliver Rahner <o.rahner@dke-data.com>
When the operator enables metrics on a proxy, it uses the port 9001,
and in the near future it will start using 9002 for the debug endpoint
as well. Make sure we don't choose ports from a range that includes
9001 so that we never clash. Setting TS_SOCKS5_SERVER, TS_HEALTHCHECK_ADDR_PORT,
TS_OUTBOUND_HTTP_PROXY_LISTEN, and PORT could also open arbitrary ports,
so we will need to document that users should not choose ports from the
10000-11000 range for those settings.
Updates #13406
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
* cmd/k8s-operator,k8s-operator,go.mod: optionally create ServiceMonitor
Adds a new spec.metrics.serviceMonitor field to ProxyClass.
If that's set to true (and metrics are enabled), the operator
will create a Prometheus ServiceMonitor for each proxy to which
the ProxyClass applies.
Additionally, create a metrics Service for each proxy that has
metrics enabled.
Updates tailscale/tailscale#11292
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
We were previously relying on unintended behaviour by runc where
all containers where by default given read/write/mknod permissions
for tun devices.
This behaviour was removed in https://github.com/opencontainers/runc/pull/3468
and released in runc 1.2.
Containerd container runtime, used by Docker and majority of Kubernetes distributions
bumped runc to 1.2 in 1.7.24 https://github.com/containerd/containerd/releases/tag/v1.7.24
thus breaking our reference tun mode Tailscale Kubernetes manifests and Kubernetes
operator proxies.
This PR changes the all Kubernetes container configs that run Tailscale in tun mode
to privileged. This should not be a breaking change because all these containers would
run in a Pod that already has a privileged init container.
Updates tailscale/tailscale#14256
Updates tailscale/tailscale#10814
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit updates ServeConfig to allow configuration to Services (VIPServices for now) via Serve.
The scope of this commit is only adding the Services field to ServeConfig. The field doesn't actually
allow packet flowing yet. The purpose of this commit is to unblock other work on k8s end.
Updates #22953
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
* cmd/containerboot: serve health on local endpoint
We introduced stable (user) metrics in #14035, and `TS_LOCAL_ADDR_PORT`
with it. Rather than requiring users to specify a new addr/port
combination for each new local endpoint they want the container to
serve, this combines the health check endpoint onto the local addr/port
used by metrics if `TS_ENABLE_HEALTH_CHECK` is used instead of
`TS_HEALTHCHECK_ADDR_PORT`.
`TS_LOCAL_ADDR_PORT` now defaults to binding to all interfaces on 9002
so that it works more seamlessly and with less configuration in
environments other than Kubernetes, where the operator always overrides
the default anyway. In particular, listening on localhost would not be
accessible from outside the container, and many scripted container
environments do not know the IP address of the container before it's
started. Listening on all interfaces allows users to just set one env
var (`TS_ENABLE_METRICS` or `TS_ENABLE_HEALTH_CHECK`) to get a fully
functioning local endpoint they can query from outside the container.
Updates #14035, #12898
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This commit adds a command to validate that all the metrics that
are registring in the client are also present in a path or url.
It is intended to be ran from the KB against the latest version of
tailscale.
Updates tailscale/corp#24066
Updates tailscale/corp#22075
Co-Authored-By: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Ensure that the ExternalName Service port names are always synced to the
ClusterIP Service, to fix a bug where if users created a Service with
a single unnamed port and later changed to 1+ named ports, the operator
attempted to apply an invalid multi-port Service with an unnamed port.
Also, fixes a small internal issue where not-yet Service status conditons
were lost on a spec update.
Updates tailscale/tailscale#10102
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
this commit reduced the amount of data sent in the metrics
data integration test from 10MB to 1MB.
On various machines 10MB was quite flaky, while 1MB has not failed
once on 10000 runs.
Updates #13420
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Re-use a pre-allocated bytes.Buffer struct and
shallow the copy the result of bytes.NewBuffer into it
to avoid allocating the struct.
Note that we're only reusing the bytes.Buffer struct itself
and not the underling []byte temporarily stored within it.
Updates #cleanup
Updates tailscale/corp#18514
Updates golang/go#67004
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
In https://github.com/tailscale/tailscale/pull/13726 we added logic to
`checkExitNodePrefsLocked` to error out on platforms where using an
exit node is unsupported in order to give users more obvious feedback
than having this silently fail downstream.
The above change neglected to properly check whether the device in
question was actually trying to use an exit node when doing the check
and was incorrectly returning an error on any calls to
`checkExitNodePrefsLocked` on platforms where using an exit node is not
supported as a result.
This change remedies this by adding a check to see whether the device is
attempting to use an exit node before doing the `CanUseExitNode` check.
Updates https://github.com/tailscale/corp/issues/24835
Signed-off-by: Mario Minardi <mario@tailscale.com>
I was hoping we'd catch an example input quickly, but the reporter had
rebooted their machine and it is no longer exhibiting the behavior. As
such this code may be sticking around quite a bit longer and we might
encounter other errors, so include the panic in the log entry.
Updates #14201
Updates #14202
Updates golang/go#70528
Signed-off-by: James Tucker <james@tailscale.com>
We add a policy definition for the AllowedSuggestedExitNodes syspolicy setting, allowing admins
to configure a list of exit node IDs to be used as a pool for automatic suggested exit node selection.
We update definitions for policy settings configurable on both a per-user and per-machine basis,
such as UI customizations, to specify class="Both".
Lastly, we update the help text for existing policy definitions to include a link to the KB article
as the last line instead of in the first paragraph.
Updates #12687
Updates tailscale/corp#19681
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this PR, we update LocalBackend to rebuild the set of allowed suggested exit nodes whenever
the AllowedSuggestedExitNodes syspolicy setting changes. Additionally, we request a new suggested
exit node when this occurs, enabling its use if the ExitNodeID syspolicy setting is set to auto:any.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This PR removes the sync.Once wrapper around retrieving the MachineCertificateSubject policy
setting value, ensuring the most recent version is always used if it changes after the service starts.
Although this policy setting is used by a very limited number of customers, recent support escalations have highlighted issues caused by outdated or incorrect policy values being applied.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this PR, we update ipnlocal.NewLocalBackend to subscribe to policy change notifications
and reapply syspolicy settings to the current profile's ipn.Prefs whenever a change occurs.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This moves code that handles ExitNodeID/ExitNodeIP syspolicy settings
from (*LocalBackend).setExitNodeID to applySysPolicy.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This updates the syspolicy.LogSCMInteractions check to run at the time of an interaction,
just before logging a message, instead of during service startup. This ensures the most
recent policy setting is used if it has changed since the service started.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this PR, we move the syspolicy.FlushDNSOnSessionUnlock check from service startup
to when a session change notification is received. This ensures that the most recent policy
setting value is used if it has changed since the service started.
We also plan to handle session change notifications for unrelated reasons
and need to decouple notification subscriptions from DNS anyway.
Updates #12687
Updates tailscale/corp#18342
Signed-off-by: Nick Khyl <nickk@tailscale.com>
These delays determine how soon syspolicy change callbacks are invoked after a policy setting is updated
in a policy source. For tests, we shorten these delays to minimize unnecessary wait times. This adjustment
only affects tests that subscribe to policy change notifications and modify policy settings after they have
already been set. Initial policy settings are always available immediately without delay.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We have several places where LocalBackend instances are created for testing, but they are rarely shut down
when the tests that created them exit.
In this PR, we update newTestLocalBackend and similar functions to use testing.TB.Cleanup(lb.Shutdown)
to ensure LocalBackend instances are properly shut down during test cleanup.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
containerboot:
Adds 3 new environment variables for containerboot, `TS_LOCAL_ADDR_PORT` (default
`"${POD_IP}:9002"`), `TS_METRICS_ENABLED` (default `false`), and `TS_DEBUG_ADDR_PORT`
(default `""`), to configure metrics and debug endpoints. In a follow-up PR, the
health check endpoint will be updated to use the `TS_LOCAL_ADDR_PORT` if
`TS_HEALTHCHECK_ADDR_PORT` hasn't been set.
Users previously only had access to internal debug metrics (which are unstable
and not recommended) via passing the `--debug` flag to tailscaled, but can now
set `TS_METRICS_ENABLED=true` to expose the stable metrics documented at
https://tailscale.com/kb/1482/client-metrics at `/metrics` on the addr/port
specified by `TS_LOCAL_ADDR_PORT`.
Users can also now configure a debug endpoint more directly via the
`TS_DEBUG_ADDR_PORT` environment variable. This is not recommended for production
use, but exposes an internal set of debug metrics and pprof endpoints.
operator:
The `ProxyClass` CRD's `.spec.metrics.enable` field now enables serving the
stable user metrics documented at https://tailscale.com/kb/1482/client-metrics
at `/metrics` on the same "metrics" container port that debug metrics were
previously served on. To smooth the transition for anyone relying on the way the
operator previously consumed this field, we also _temporarily_ serve tailscaled's
internal debug metrics on the same `/debug/metrics` path as before, until 1.82.0
when debug metrics will be turned off by default even if `.spec.metrics.enable`
is set. At that point, anyone who wishes to continue using the internal debug
metrics (not recommended) will need to set the new `ProxyClass` field
`.spec.statefulSet.pod.tailscaleContainer.debug.enable`.
Users who wish to opt out of the transitional behaviour, where enabling
`.spec.metrics.enable` also enables debug metrics, can set
`.spec.statefulSet.pod.tailscaleContainer.debug.enable` to false (recommended).
Separately but related, the operator will no longer specify a host port for the
"metrics" container port definition. This caused scheduling conflicts when k8s
needs to schedule more than one proxy per node, and was not necessary for allowing
the pod's port to be exposed to prometheus scrapers.
Updates #11292
---------
Co-authored-by: Kristoffer Dalby <kristoffer@tailscale.com>
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
A small follow-up to #14112- ensures that the operator itself can emit
Events for its kube state store changes.
Updates tailscale/tailscale#14080
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
https://go.dev/wiki/CodeReviewComments#useful-test-failures
(Previously it was using subtests with names including the input, but
once those went away, there was no context left)
Updates #14169
Change-Id: Ib217028183a3d001fe4aee58f2edb746b7b3aa88
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Otherwise we'll see a panic if we hit the dnsfallback code and try to
call NewDialer with a nil NetMon.
Updates #14161
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I81c6e72376599b341cb58c37134c2a948b97cf5f
So we can locate them in logs more easily.
Updates tailscale/corp#24721
Change-Id: Ia766c75608050dde7edc99835979a6e9bb328df2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Extracts tsaddr.IsTailscaleIPv4 out of tsaddr.IsTailscaleIP.
This will allow for checking valid Tailscale assigned IPv4 addresses
without checking IPv6 addresses.
Updates #14168
Updates tailscale/corp#24620
Signed-off-by: James Scott <jim@tailscale.com>
This is a follow-up to #14112 where our internal kube client was updated
to allow it to emit Events - this updates our sample kube manifests
and tsrecorder manifest templates so they can benefit from this functionality.
Updates tailscale/tailscale#14080
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Initial support for SrcCaps was added in 5ec01bf but it was not actually
working without this.
Updates #12542
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Adds functionality to kube client to emit Events.
Updates kube store to emit Events when tailscaled state has been loaded, updated or if any errors where
encountered during those operations.
This should help in cases where an error related to state loading/updating caused the Pod to crash in a loop-
unlike logs of the originally failed container instance, Events associated with the Pod will still be
accessible even after N restarts.
Updates tailscale/tailscale#14080
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
I merged 5cae7c51bf (removing Notify.BackendLogID) and 93db503565
(adding another reference to Notify.BackendLogID) that didn't have merge
conflicts, but didn't compile together.
This removes the new reference, fixing the build.
Updates #14129
Change-Id: I9bb68efd977342ea8822e525d656817235039a66
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Limit spamming GUIs with boring updates to once in 3 seconds, unless
the notification is relatively interesting and the GUI should update
immediately.
This is basically @barnstar's #14119 but with the logic moved to be
per-watch-session (since the bit is per session), rather than
globally. And this distinguishes notable Notify messages (such as
state changes) and makes them send immediately.
Updates tailscale/corp#24553
Change-Id: I79cac52cce85280ce351e65e76ea11e107b00b49
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The v2 endpoint supports HTTP/2 bidirectional streaming and acks for
received bytes. This is used to detect when a recorder disappears to
more quickly terminate the session.
Updates https://github.com/tailscale/corp/issues/24023
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
* ipn,tailcfg: add VIPService struct and c2n to fetch them from client
Updates tailscale/corp#22743, tailscale/corp#22955
Signed-off-by: Naman Sood <mail@nsood.in>
* more review fixes
Signed-off-by: Naman Sood <mail@nsood.in>
* don't mention PeerCapabilityServicesDestination since it's currently unused
Signed-off-by: Naman Sood <mail@nsood.in>
---------
Signed-off-by: Naman Sood <mail@nsood.in>
Back in the day this testcontrol package only spoke the
nacl-boxed-based control protocol, which used this.
Then we added ts2021, which didn't, but still sometimes used it.
Then we removed the old mode and didn't remove this parameter
in 2409661a0d.
Updates #11585
Change-Id: Ifd290bd7dbbb52b681b3599786437a15bc98b6a5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously we required the program to be running in a test or have
TS_CONTROL_IS_PLAINTEXT_HTTP before we disabled its https fallback
on "http" schema control URLs to localhost with ports.
But nobody accidentally does all three of "http", explicit port
number, localhost and doesn't mean it. And when they mean it, they're
testing a localhost dev control server (like I was) and don't want 443
getting involved.
As of the changes for #13597, this became more annoying in that we
were trying to use a port which wasn't even available.
Updates #13597
Change-Id: Icd00bca56043d2da58ab31de7aa05a3b269c490f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
https://portsmouthbrewery.com/shilling-scale/
Any scale that includes "wee heavy" is a scale worth including.
Updates #words
Change-Id: I85fd7a64cf22e14f686f1093a220cb59c43e46ba
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We currently annotate pods with a hash of the tailscaled config so that
we can trigger pod restarts whenever it changes. However, the hash
updates more frequently than is necessary causing more restarts than is
necessary. This commit removes two causes; scaling up/down and removing
the auth key after pods have initially authed to control. However, note
that pods will still restart on scale-up/down because of the updated set
of volumes mounted into each pod. Hopefully we can fix that in a planned
follow-up PR.
Updates #13406
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This gets close to all of the remaining ones.
Updates #12912
Change-Id: I9c672bbed2654a6c5cab31e0cbece6c107d8c6fa
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It doesn't need a Clone method, like a time.Time, etc.
And then, because Go 1.23+ uses unique.Handle internally for
the netip package types, we can remove those special cases.
Updates #14058 (pulled out from that PR)
Updates tailscale/corp#24485
Change-Id: Iac3548a9417ccda5987f98e0305745a6e178b375
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Perhaps I was too opimistic in #13323 thinking we won't need logs for
this. Let's log a summary of the response without logging specific
identifiers.
Updates tailscale/corp#24437
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Or unless the new "ts_debug_websockets" build tag is set.
Updates #1278
Change-Id: Ic4c4f81c1924250efd025b055585faec37a5491d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Otherwise all the clients only using control/controlhttp for the
ts2021 HTTP client were also pulling in WebSocket libraries, as the
server side always needs to speak websockets, but only GOOS=js clients
speak it.
This doesn't yet totally remove the websocket dependency on Linux because
Linux has a envknob opt-in to act like GOOS=js for manual testing and force
the use of WebSockets for DERP only (not control). We can put that behind
a build tag in a future change to eliminate the dep on all GOOSes.
Updates #1278
Change-Id: I4f60508f4cad52bf8c8943c8851ecee506b7ebc9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Some environments would like to remove Tailscale SSH support for the
binary for various reasons when not needed (either for peace of mind,
or the ~1MB of binary space savings).
Updates tailscale/corp#24454
Updates #1278
Updates #12614
Change-Id: Iadd6c5a393992c254b5dc9aa9a526916f96fd07a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adds a /disconnect-control local API endpoint that just shuts down control client.
This can be run before shutting down an HA subnet router/app connector replica - it will ensure
that all connection to control are dropped and control thus considers this node inactive and tells
peers to switch over to another replica. Meanwhile the existing connections keep working (assuming
that the replica is given some graceful shutdown period).
Updates tailscale/tailscale#14020
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Sets a custom hostinfo app type for ProxyGroup replicas, similarly
to how we do it for all other Kubernetes Operator managed components.
Updates tailscale/tailscale#13406,tailscale/corp#22920
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
- Basic description of DERP
If configured to do so, also show
- Mailto link to security@tailscale.com
- Link to Tailscale Security Policies
- Link to Tailscale Acceptable Use Policy
Updates tailscale/corp#24092
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This adds a new generic result type (motivated by golang/go#70084) to
try it out, and uses it in the new lineutil package (replacing the old
lineread package), changing that package to return iterators:
sometimes over []byte (when the input is all in memory), but sometimes
iterators over results of []byte, if errors might happen at runtime.
Updates #12912
Updates golang/go#70084
Change-Id: Iacdc1070e661b5fb163907b1e8b07ac7d51d3f83
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Thanks to @davidbuzz for raising the issue in #13973.
Fixes#8272Fixes#13973
Change-Id: Ic413e14d34c82df3c70a97e591b90316b0b4946b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Key changes:
- No mutex for every udp package: replace syncs.Map with regular map for udpTargetConns
- Use socksAddr as map key for better type safety
- Add test for multi udp target
Updates #7581
Change-Id: Ic3d384a9eab62dcbf267d7d6d268bf242cc8ed3c
Signed-off-by: VimT <me@vimt.me>
This commit addresses an issue with the SOCKS5 UDP relay functionality
when using the --tun=userspace-networking option. Previously, UDP packets
were not being correctly routed into the Tailscale network in this mode.
Key changes:
- Replace single UDP connection with a map of connections per target
- Use c.srv.dial for creating connections to ensure proper routing
Updates #7581
Change-Id: Iaaa66f9de6a3713218014cf3f498003a7cac9832
Signed-off-by: VimT <me@vimt.me>
A filesystem was plumbed into netstack in 993acf4475
but hasn't been used since 2d5d6f5403. Remove it.
Noticed while rebasing a Tailscale fork elsewhere.
Updates tailscale/corp#16827
Change-Id: Ib76deeda205ffe912b77a59b9d22853ebff42813
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We were only updating the ProfileManager and not going down
the EditPrefs path which meant the prefs weren't applied
till either the process restarted or some other pref changed.
This makes it so that we reconfigure everything correctly when
ReloadConfig is called.
Updates #13032
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Add an explicit case for exercising preferred DERP hysteresis around
the branch that compares latencies on a percentage basis.
Updates #cleanup
Signed-off-by: Jordan Whited <jordan@tailscale.com>
By counting "/" elements in the pattern we catch many scenarios, but not
the root-level handler. If either of the patterns is "/", compare the
pattern length to pick the right one.
Updates https://github.com/tailscale/corp/issues/8027
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
In this PR, we add the tailscale syspolicy command with two subcommands: list, which displays
policy settings, and reload, which forces a reload of those settings. We also update the LocalAPI
and LocalClient to facilitate these additions.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Make it possible to advertise app connector via a new conffile field.
Also bumps capver - conffile deserialization errors out if unknonw
fields are set, so we need to know which clients understand the new field.
Updates tailscale/tailscale#11113
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This required sharing the dropped packet metric between two packages
(tstun and magicsock), so I've moved its definition to util/usermetric.
Updates tailscale/corp#22075
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
The user-facing metrics are intended to track data transmitted at
the overlay network level.
Updates tailscale/corp#22075
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
In an environment with unstable latency, such as upstream bufferbloat,
there are cases where a full netcheck could drop the prior preferred
DERP (likely home DERP) from future netcheck probe plans. This will then
likely result in a home DERP having a missing sample on the next
incremental netcheck, ultimately resulting in a home DERP move.
This change does not fix our overall response to highly unstable
latency, but it is an incremental improvement to prevent single spurious
samples during a full netcheck from alone triggering a flapping
condition, as now the prior changes to include historical latency will
still provide the desired resistance, and the home DERP should not move
unless latency is consistently worse over a 5 minute period.
Note that there is a nomenclature and semantics issue remaining in the
difference between a report preferred DERP and a home DERP. A report
preferred DERP is aspirational, it is what will be picked as a home DERP
if a home DERP connection needs to be established. A nodes home DERP may
be different than a recent preferred DERP, in which case a lot of
netcheck logic is fallible. In future enhancements much of the DERP move
logic should move to consider the home DERP, rather than recent report
preferred DERP.
Updates #8603
Updates #13969
Signed-off-by: James Tucker <james@tailscale.com>
We make setting.Snapshot JSON-marshallable in preparation for returning it from the LocalAPI.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We add setting.RawValue, a new type that facilitates unmarshalling JSON numbers and arrays
as uint64 and []string (instead of float64 and []any) for policy setting values.
We then use it to make setting.RawItem JSON-marshallable and update the tests.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In this PR, we implement (but do not use yet, pending #13727 review) a syspolicy/source.Store
that reads policy settings from environment variables. It converts a CamelCase setting.Key,
such as AuthKey or ExitNodeID, to a SCREAMING_SNAKE_CASE, TS_-prefixed environment
variable name, such as TS_AUTH_KEY and TS_EXIT_NODE_ID. It then looks up the variable
and attempts to parse it according to the expected value type. If the environment variable
is not set, the policy setting is considered not configured in this store (the syspolicy package
will still read it from other sources). Similarly, if the environment variable has an invalid value
for the setting type, it won't be used (though the reported/logged error will differ).
Updates #13193
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Now when we have HA for egress proxies, it makes sense to support topology
spread constraints that would allow users to define more complex
topologies of how proxy Pods need to be deployed in relation with other
Pods/across regions etc.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This adds additional logging on DERP home changes to allow
better troubleshooting.
Updates tailscale/corp#18095
Signed-off-by: Tim Walters <tim@tailscale.com>
updates tailscale/corp#24197
tailmac run now supports the --share option which will allow you
to specify a directory on the host which can be mounted in the guest
using mount_virtiofs vmshare <path>.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
updates tailscale/corp#24197
Generation of the Host.app path was erroneous and tailmac run
would not work unless the pwd was tailmac/bin. Now you can
be able to invoke tailmac from anywhere.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
- `tailscale metrics print`: to show metric values in console
- `tailscale metrics write`: to write metrics to a file (with a tempfile
& rename dance, which is atomic on Unix).
Also, remove the `TS_DEBUG_USER_METRICS` envknob as we are getting
more confident in these metrics.
Updates tailscale/corp#22075
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Not confident this is the right way to expose this, so let's remote it
for now.
Updates tailscale/corp#22075
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
If the client cannot fetch a serial number, write a log message helping
the user understand what happened. Also, don't just return the error
immediately, since we still have a chance to collect network interface
addresses.
Updates #5902
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
trimpath can be inconvenient for IDEs and LSPs that do not always
correctly handle module relative paths, and can also contribute to
caching bugs taking effect. We rarely have a real need for trimpath of
test produced binaries, so avoiding it should be a net win.
Updates #2988
Signed-off-by: James Tucker <james@tailscale.com>
A simple implementation of latency and loss simulation, applied to
writes to the ethernet interface of the NIC. The latency implementation
could be optimized substantially later if necessary.
Updates #13355
Signed-off-by: James Tucker <james@tailscale.com>
During resolv.conf update, old 'search' lines are cleared but '\n' is not
deleted, leaving behind a new blank line on every update.
This adds 's' flag to regexp, so '\n' is included in the match and deleted when
old lines are cleared.
Also, insert missing `\n` when updated 'search' line is appended to resolv.conf.
Signed-off-by: Renato Aguiar <renato@renatoaguiar.net>
Preloading of state from kube Secret should not
error if the Secret does not exist.
Updates tailscale/tailscale#7671
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Cache state in memory on writes, read from memory
in reads.
kubestore was previously always reading state from a Secret.
This change should fix bugs caused by temporary loss of access
to kube API server and imporove overall performance
Fixes#7671
Updates tailscale/tailscale#12079,tailscale/tailscale#13900
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Maisem Ali <maisem@tailscale.com>
In this PR, we update the syspolicy package to utilize syspolicy/rsop under the hood,
and remove syspolicy.CachingHandler, syspolicy.windowsHandler and related code
which is no longer used.
We mark the syspolicy.Handler interface and RegisterHandler/SetHandlerForTest functions
as deprecated, but keep them temporarily until they are no longer used in other repos.
We also update the package to register setting definitions for all existing policy settings
and to register the Registry-based, Windows-specific policy stores when running on Windows.
Finally, we update existing internal and external tests to use the new API and add a few more
tests and benchmarks.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This allows us to print the time that a netcheck was run, which is
useful in debugging.
Updates #10972
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Id48d30d4eb6d5208efb2b1526a71d83fe7f9320b
Few changes to resolve TODOs in the code:
- Instead of using a hardcoded IP, get it from the netmap.
- Use 100.100.100.100 as the gateway IP
- Use the /10 CGNAT range instead of a random /24
Updates #2589
Signed-off-by: Maisem Ali <maisem@tailscale.com>
It had bit-rotted likely during the transition to vector io in
76389d8baf. Tested on Ubuntu 24.04
by creating a netns and doing the DHCP dance to get an IP.
Updates #2589
Signed-off-by: Maisem Ali <maisem@tailscale.com>
In f77821fd63 (released in v1.72.0), we made the client tell a DERP server
when the connection was not its ideal choice (the first node in its region).
But we didn't do anything with that information until now. This adds a
metric about how many such connections are on a given derper, and also
adds a bit to the PeerPresentFlags bitmask so watchers can identify
(and rebalance) them.
Updates tailscale/corp#372
Change-Id: Ief8af448750aa6d598e5939a57c062f4e55962be
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates tailscale/tailscale#13839
Adds a new blockblame package which can detect common MITM SSL certificates used by network appliances. We use this in `tlsdial` to display a dedicated health warning when we cannot connect to control, and a network appliance MITM attack is detected.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Clamp the min and max version for DSM 7.0 and DSM 7.2 packages when we
are building packages for the synology package centre. This change
leaves packages destined for pkgs.tailscale.com with just the min
version set to not break packages in the wild / our update flow.
Updates https://github.com/tailscale/corp/issues/22908
Signed-off-by: Mario Minardi <mario@tailscale.com>
GetReport() may have side effects when the caller enforces a deadline
that is shorter than ReportTimeout.
Updates #13783
Updates #13394
Signed-off-by: Jordan Whited <jordan@tailscale.com>
We add the ClientID() method to the ipnauth.Actor interface and updated ipnserver.actor to implement it.
This method returns a unique ID of the connected client if the actor represents one. It helps link a series
of interactions initiated by the client, such as when a notification needs to be sent back to a specific session,
rather than all active sessions, in response to a certain request.
We also add LocalBackend.WatchNotificationsAs and LocalBackend.StartLoginInteractiveAs methods,
which are like WatchNotifications and StartLoginInteractive but accept an additional parameter
specifying an ipnauth.Actor who initiates the operation. We store these actor identities in
watchSession.owner and LocalBackend.authActor, respectively,and implement LocalBackend.sendTo
and related helper methods to enable sending notifications to watchSessions associated with actors
(or, more broadly, identifiable recipients).
We then use the above to change who receives the BrowseToURL notifications:
- For user-initiated, interactive logins, the notification is delivered only to the user who initiated the
process. If the initiating actor represents a specific connected client, the URL notification is sent back
to the same LocalAPI client that called StartLoginInteractive. Otherwise, the notification is sent to all
clients connected as that user.
Currently, we only differentiate between users on Windows, as it is inherently a multi-user OS.
- In all other cases (e.g., node key expiration), we send the notification to all connected users.
Updates tailscale/corp#18342
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Write timeouts can be indicative of stalled TCP streams. Understanding
changes in the rate of such events can be helpful in an ops context.
Updates tailscale/corp#23668
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This fixes the installation on newer Fedora versions that use dnf5 as
the 'dnf' binary.
Updates #13828
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I39513243c81640fab244a32b7dbb3f32071e9fce
Adds logic to `checkExitNodePrefsLocked` to return an error when
attempting to use exit nodes on a platform where this is not supported.
This mirrors logic that was added to error out when trying to use `ssh`
on an unsupported platform, and has very similar semantics.
Fixes https://github.com/tailscale/tailscale/issues/13724
Signed-off-by: Mario Minardi <mario@tailscale.com>
While looking at deflaking TestTwoDevicePing/ping_1.0.0.2_via_SendPacket,
there were a bunch of distracting:
WARNING: (non-fatal) nil health.Tracker (being strict in CI): ...
This pacifies those so it's easier to work on actually deflaking the test.
Updates #11762
Updates #11874
Change-Id: I08dcb44511d4996b68d5f1ce5a2619b555a2a773
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* updates to LocalBackend require metrics to be passed in which are now initialized
* os.MkdirTemp isn't supported in wasm/js so we simply return empty
string for logger
* adds a UDP dialer which was missing and led to the dialer being
incompletely initialized
Fixes#10454 and #8272
Signed-off-by: Christian <christian@devzero.io>
In this PR we add syspolicy/rsop package that facilitates policy source registration
and provides access to the resultant policy merged from all registered sources for a
given scope.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
For a customer that wants to run their own DERP prober, let's add a
/healthz endpoint that can be used to monitor derpprobe itself.
Updates #6526
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Iba315c999fc0b1a93d8c503c07cc733b4c8d5b6b
Our existing container-detection tricks did not work on Kubernetes,
where Docker is no longer used as a container runtime. Extends the
existing go build tags for containers to the other container packages
and uses that to reliably detect builds that were created by Tailscale
for use in a container. Unfortunately this doesn't necessarily improve
detection for users' custom builds, but that's a separate issue.
Updates #13825
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
connstats currently increments the packet counter whenever it is called
to store a length of data, however when udp batch sending was introduced
we pass the length for a series of packages, and it is only incremented
ones, making it count wrongly if we are on a platform supporting udp
batches.
Updates tailscale/corp#22075
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This allows passing through any environment variables that we set ourselves, for example DBUS_SESSION_BUS_ADDRESS.
Updates #11175
Co-authored-by: Mario Minardi <mario@tailscale.com>
Signed-off-by: Percy Wegmann <percy@tailscale.com>
The bools.Compare function compares boolean values
by reporting -1, 0, +1 for ordering so that it can be easily
used with slices.SortFunc.
Updates #cleanup
Updates tailscale/corp#11038
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
If multiple upstream DNS servers are available, quad-100 sends requests to all of them
and forwards the first successful response, if any. If no successful responses are received,
it propagates the first failure from any of them.
This PR adds some test coverage for these scenarios.
Updates #13571
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We currently have two executions paths where (*forwarder).forwardWithDestChan
returns nil, rather than an error, without sending a DNS response to responseChan.
These paths are accompanied by a comment that reads:
// Returning an error will cause an internal retry, there is
// nothing we can do if parsing failed. Just drop the packet.
But it is not (or no longer longer) accurate: returning an error from forwardWithDestChan
does not currently cause a retry.
Moreover, although these paths are currently unreachable due to implementation details,
if (*forwarder).forwardWithDestChan were to return nil without sending a response to
responseChan, it would cause a deadlock at one call site and a panic at another.
Therefore, we update (*forwarder).forwardWithDestChan to return errors in those two paths
and remove comments that were no longer accurate and misleading.
Updates #cleanup
Updates #13571
Signed-off-by: Nick Hill <mykola.khyl@gmail.com>
If a DoH server returns an HTTP server error, rather than a SERVFAIL within
a successful HTTP response, we should handle it in the same way as SERVFAIL.
Updates #13571
Signed-off-by: Nick Hill <mykola.khyl@gmail.com>
As per the docstring, (*forwarder).forwardWithDestChan should either send to responseChan
and returns nil, or returns a non-nil error (without sending to the channel).
However, this does not hold when all upstream DNS servers replied with an error.
We've been handling this special error path in (*Resolver).Query but not in (*Resolver).HandlePeerDNSQuery.
As a result, SERVFAIL responses from upstream servers were being converted into HTTP 503 responses,
instead of being properly forwarded as SERVFAIL within a successful HTTP response, as per RFC 8484, section 4.2.1:
A successful HTTP response with a 2xx status code (see Section 6.3 of [RFC7231]) is used for any valid DNS response,
regardless of the DNS response code. For example, a successful 2xx HTTP status code is used even with a DNS message
whose DNS response code indicates failure, such as SERVFAIL or NXDOMAIN.
In this PR we fix (*forwarder).forwardWithDestChan to no longer return an error when it sends a response to responseChan,
and remove the special handling in (*Resolver).Query, as it is no longer necessary.
Updates #13571
Signed-off-by: Nick Hill <mykola.khyl@gmail.com>
This helps better distinguish what is generating activity to the
Tailscale public API.
Updates tailscale/corp#23838
Signed-off-by: Percy Wegmann <percy@tailscale.com>
No need to prefix this with 'Tailscale' for tailscale.com
custom resource types.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
We were using google/uuid in two places and that brought in database/sql/driver.
We didn't need it in either place.
Updates #13760
Updates tailscale/corp#20099
Change-Id: Ieed32f1bebe35d35f47ec5a2a429268f24f11f1f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There's never a tailscaled on iOS. And we can't run child processes to
look for it anyway.
Updates tailscale/corp#20099
Change-Id: Ieb3776f4bb440c4f1c442fdd169bacbe17f23ddb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We probably shouldn't link it in anywhere, but let's fix iOS for now.
Updates #13762
Updates tailscale/corp#20099
Change-Id: Idac116e9340434334c256acba3866f02bd19827c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
One primary purpose of WithLock is to mutate the underlying map.
However, this can lead to a panic if it happens to be nil.
Thus, always allocate a map before passing it to f.
Updates tailscale/corp#11038
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Thus new function allows constructing vizerrors that combine a message
appropriate for display to users with a wrapped underlying error.
Updates tailscale/corp#23781
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Add Keys, Values, and All to iterate over
all keys, values, and entries, respectively.
Updates #11038
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
cmd/k8s-operator,k8s-operator/apis: set a readiness condition on egress Services
Set a readiness condition on ExternalName Services that define a tailnet target
to route cluster traffic to via a ProxyGroup's proxies. The condition
is set to true if at least one proxy is currently set up to route.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Their callers using Range are all kinda clunky feeling. Iterators
should make them more readable.
Updates #12912
Change-Id: I93461eba8e735276fda4a8558a4ae4bfd6c04922
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We don't need to error out and continuously reconcile if ProxyClass
has not (yet) been created, once it gets created the ProxyGroup
reconciler will get triggered.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Ensure that .status.podIPs is used to select Pod's IP
in all reconcilers.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
As discussed in #13684, base the ProxyGroup's proxy definitions on the same
scaffolding as the existing proxies, as defined in proxy.yaml
Updates #13406
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Instead of converting our PortMap struct to a string during marshalling
for use as a key, convert the whole collection of PortMaps to a list of
PortMap objects, which improves the readability of the JSON config while
still keeping the data structure we need in the code.
Updates #13406
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Currently egress Services for ProxyGroup only work for Pods and Services
with IPv4 addresses. Ensure that it works on dual stack clusters by reading
proxy Pod's IP from the .status.podIPs list that always contains both
IPv4 and IPv6 address (if the Pod has them) rather than .status.podIP that
could contain IPv6 only for a dual stack cluster.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The default ProxyClass can be set via helm chart or env var, and applies
to all proxies that do not otherwise have an explicit ProxyClass set.
This ensures proxies created by the new ProxyGroup CRD are consistent
with the behaviour of existing proxies
Nearby but unrelated changes:
* Fix up double error logs (controller runtime logs returned errors)
* Fix a couple of variable names
Updates #13406
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Rearrange conditionals to reduce indentation and make it a bit easier to read
the logic. Also makes some error message updates for better consistency
with the recent decision around capitalising resource names and the
upcoming addition of config secrets.
Updates #cleanup
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
It is sometimes necessary to defer initialization steps until the first actual usage
or until certain prerequisites have been met. For example, policy setting and
policy source registration should not occur during package initialization.
Instead, they should be deferred until the syspolicy package is actually used.
Additionally, any errors should be properly handled and reported, rather than
causing a panic within the package's init function.
In this PR, we add DeferredInit, to facilitate the registration and invocation
of deferred initialization functions.
Updates #12687
Signed-off-by: Nick Hill <mykola.khyl@gmail.com>
To avoid warning:
find: warning: you have specified the global option -maxdepth after the argument -type, but global options are not positional, i.e., -maxdepth affects tests specified before it as well as those specified after it. Please specify global options before other arguments.
Fixestailscale/corp#23689
Change-Id: I91ee260b295c552c0a029883d5e406733e081478
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Implements the controller for the new ProxyGroup CRD, designed for
running proxies in a high availability configuration. Each proxy gets
its own config and state Secret, and its own tailscale node ID.
We are currently mounting all of the config secrets into the container,
but will stop mounting them and instead read them directly from the kube
API once #13578 is implemented.
Updates #13406
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Like we do for the ones on iOS.
As a bonus, this removes a caller of tsaddr.IsTailscaleIP which we
want to revamp/remove soonish.
Updates #13687
Change-Id: Iab576a0c48e9005c7844ab52a0aba5ba343b750e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Per my investigation just now, the $HOME environment variable is unset
on the macsys (standalone macOS GUI) variant, but the current working
directory is valid. Look for the environment variable file in that
location in addition to inside the home directory.
Updates #3707
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I481ae2e0d19b316244373e06865e3b5c3a9f3b88
Extend safeweb.Config with the ability to pass a http.Server that
safeweb will use to server traffic.
Updates corp#8207
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Adds a new reconciler that reconciles ExternalName Services that define a
tailnet target that should be exposed to cluster workloads on a ProxyGroup's
proxies.
The reconciler ensures that for each such service, the config mounted to
the proxies is updated with the tailnet target definition and that
and EndpointSlice and ClusterIP Service are created for the service.
Adds a new reconciler that ensures that as proxy Pods become ready to route
traffic to a tailnet target, the EndpointSlice for the target is updated
with the Pods' endpoints.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The AddSNATRuleForDst rule was adding a new rule each time it was called including:
- if a rule already existed
- if a rule matching the destination, but with different desired source already existed
This was causing issues especially for the in-progress egress HA proxies work,
where the rules are now refreshed more frequently, so more redundant rules
were being created.
This change:
- only creates the rule if it doesn't already exist
- if a rule for the same dst, but different source is found, delete it
- also ensures that egress proxies refresh firewall rules
if the node's tailnet IP changes
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Add the ability to specify Strict-Transport-Security options in response
to BrowserMux HTTP requests in safeweb.
Updates https://github.com/tailscale/corp/issues/23375
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Updates tailscale/tailscale#3363
We know `log.tailscale.io` supports TLS 1.3, so we can enforce its usage in the client to shake some bytes off the TLS handshake each time a connection is opened to upload logs.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Not just its code.
Updates tailscale/corp#23584
Change-Id: I8001a675372fe15da797adde22f04488d8683448
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The new logging in 2dd71e64ac is spammy at shutdown:
Receive func ReceiveIPv6 exiting with error: *net.OpError, read udp [::]:38869: raw-read udp6 [::]:38869: use of closed network connection
Receive func ReceiveIPv4 exiting with error: *net.OpError, read udp 0.0.0.0:36123: raw-read udp4 0.0.0.0:36123: use of closed network connection
Skip it if we're in the process of shutting down.
Updates #10976
Change-Id: I4f6d1c68465557eb9ffe335d43d740e499ba9786
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We were selectively uploading it, but we were still gathering it,
which can be a waste of CPU.
Also remove a bunch of complexity that I don't think matters anymore.
And add an envknob to force service collection off on a single node,
even if the tailnet policy permits it.
Fixes#13463
Change-Id: Ib6abe9e29d92df4ffa955225289f045eeeb279cf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When an Exit Node is used, we create a WFP rule to block all inbound and outbound traffic,
along with several rules to permit specific types of traffic. Notably, we allow all inbound and
outbound traffic to and from LocalRoutes specified in wgengine/router.Config. The list of allowed
routes always includes routes for internal interfaces, such as loopback and virtual Hyper-V/WSL2
interfaces, and may also include LAN routes if the "Allow local network access" option is enabled.
However, these permitting rules do not allow link-local multicast on the corresponding interfaces.
This results in broken mDNS/LLMNR, and potentially other similar issues, whenever an exit node is used.
In this PR, we update (*wf.Firewall).UpdatePermittedRoutes() to create rules allowing outbound and
inbound link-local multicast traffic to and from the permitted IP ranges, partially resolving the mDNS/LLMNR
and *.local name resolution issue.
Since Windows does not attempt to send mDNS/LLMNR queries if a catch-all NRPT rule is present,
it is still necessary to disable the creation of that rule using the disable-local-dns-override-via-nrpt nodeAttr.
Updates #13571
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Of tests we wish we could easily add. One day.
Updates #13038
Change-Id: If44646f8d477674bbf2c9a6e58c3cd8f94a4e8df
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates tailscale/tailscale#6148
This is the result of some observations we made today with @raggi. The DNS over HTTPS client currently doesn't cap the number of connections it uses, either in-use or idle. A burst of DNS queries will open multiple connections. Idle connections remain open for 30 seconds (this interval is defined in the dohTransportTimeout constant). For DoH providers like NextDNS which send keep-alives, this means the cellular modem will remain up more than expected to send ACKs if any keep-alives are received while a connection remains idle during those 30 seconds. We can set the IdleConnTimeout to 10 seconds to ensure an idle connection is terminated if no other DNS queries come in after 10 seconds. Additionally, we can cap the number of connections to 1. This ensures that at all times there is only one open DoH connection, either active or idle. If idle, it will be terminated within 10 seconds from the last query.
We also observed all the DoH providers we support are capable of TLS 1.3. We can force this TLS version to reduce the number of packets sent/received each time a TLS connection is established.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
1eaad7d3de regressed some tests in another repo that were starting up
a control server on `http://127.0.0.1:nnn`. Because there was no https
running, and because of a bug in 1eaad7d3de (which ended up checking
the recently-dialed-control check twice in a single dial call), we
ended up forcing only the use of TLS dials in a test that only had
plaintext HTTP running.
Instead, plumb down support for explicitly disabling TLS fallbacks and
use it only when running in a test and using `http` scheme control
plane URLs to 127.0.0.1 or localhost.
This fixes the tests elsewhere.
Updates #13597
Change-Id: I97212ded21daf0bd510891a278078daec3eebaa6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I noticed while debugging a test failure elsewhere that our failure
logs (when verbosity is cranked up) were uselessly attributing dial
failures to failure to dial an invalid IP address (this IPv6 address
we didn't have), rather than showing me the actual IPv4 connection
failure.
Updates #13597 (tangentially)
Change-Id: I45ffbefbc7e25ebfb15768006413a705b941dae5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates tailscale/tailscale#1634
Updates tailscale/tailscale#13265
Captive portal detection uses a custom `net.Dialer` in its `http.Client`. This custom Dialer ensures that the socket is bound specifically to the Wi-Fi interface. This is crucial because without it, if any default routes are set, the outgoing requests for detecting a captive portal would bypass Wi-Fi and go through the default route instead.
The Dialer did not have a Timeout property configured, so the default system timeout was applied. This caused issues in #13265, where we attempted to make captive portal detection requests over an IPsec interface used for Wi-Fi Calling. The call to `connect()` would fail and remain blocked until the system timeout (approximately 1 minute) was reached.
In #13598, I simply excluded the IPsec interface from captive portal detection. This was a quick and safe mitigation for the issue. This PR is a follow-up to make the process more robust, by setting a 3 seconds timeout on any connection establishment on any interface (this is the same timeout interval we were already setting on the HTTP client).
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
We were previously not checking that the external IP that we got back
from a UPnP portmap was a valid endpoint; add minimal validation that
this endpoint is something that is routeable by another host.
Updates tailscale/corp#23538
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Id9649e7683394aced326d5348f4caa24d0efd532
This pulls out the clock and forceNoise443 code into methods on the
Dialer as cleanup in its own commit to make a future change less
distracting.
Updates #13597
Change-Id: I7001e57fe7b508605930c5b141a061b6fb908733
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for a future port 80 MITM fix, make the 'debug ts2021' command
retry once after a failure to give it a chance to pick a new strategy.
Updates #13597
Change-Id: Icb7bad60cbf0dbec78097df4a00e9795757bc8e4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add logic to set environment variables that match the SSH rule's
`acceptEnv` settings in the SSH session's environment.
Updates https://github.com/tailscale/corp/issues/22775
Signed-off-by: Mario Minardi <mario@tailscale.com>
* cmd/containerboot,kube,util/linuxfw: configure kube egress proxies to route to 1+ tailnet targets
This commit is first part of the work to allow running multiple
replicas of the Kubernetes operator egress proxies per tailnet service +
to allow exposing multiple tailnet services via each proxy replica.
This expands the existing iptables/nftables-based proxy configuration
mechanism.
A proxy can now be configured to route to one or more tailnet targets
via a (mounted) config file that, for each tailnet target, specifies:
- the target's tailnet IP or FQDN
- mappings of container ports to which cluster workloads will send traffic to
tailnet target ports where the traffic should be forwarded.
Example configfile contents:
{
"some-svc": {"tailnetTarget":{"fqdn":"foo.tailnetxyz.ts.net","ports"{"tcp:4006:80":{"protocol":"tcp","matchPort":4006,"targetPort":80},"tcp:4007:443":{"protocol":"tcp","matchPort":4007,"targetPort":443}}}}
}
A proxy that is configured with this config file will configure firewall rules
to route cluster traffic to the tailnet targets. It will then watch the config file
for updates as well as monitor relevant netmap updates and reconfigure firewall
as needed.
This adds a bunch of new iptables/nftables functionality to make it easier to dynamically update
the firewall rules without needing to restart the proxy Pod as well as to make
it easier to debug/understand the rules:
- for iptables, each portmapping is a DNAT rule with a comment pointing
at the 'service',i.e:
-A PREROUTING ! -i tailscale0 -p tcp -m tcp --dport 4006 -m comment --comment "some-svc:tcp:4006 -> tcp:80" -j DNAT --to-destination 100.64.1.18:80
Additionally there is a SNAT rule for each tailnet target, to mask the source address.
- for nftables, a separate prerouting chain is created for each tailnet target
and all the portmapping rules are placed in that chain. This makes it easier
to look up rules and delete services when no longer needed.
(nftables allows hooking a custom chain to a prerouting hook, so no extra work
is needed to ensure that the rules in the service chains are evaluated).
The next steps will be to get the Kubernetes Operator to generate
the configfile and ensure it is mounted to the relevant proxy nodes.
Updates tailscale/tailscale#13406
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The operator creates a non-reusable auth key for each of
the cluster proxies that it creates and puts in the tailscaled
configfile mounted to the proxies.
The proxies are always tagged, and their state is persisted
in a Kubernetes Secret, so their node keys are expected to never
be regenerated, so that they don't need to re-auth.
Some tailnet configurations however have seen issues where the auth
keys being left in the tailscaled configfile cause the proxies
to end up in unauthorized state after a restart at a later point
in time.
Currently, we have not found a way to reproduce this issue,
however this commit removes the auth key from the config once
the proxy can be assumed to have logged in.
If an existing, logged-in proxy is upgraded to this version,
its redundant auth key will be removed from the conffile.
If an existing, logged-in proxy is downgraded from this version
to a previous version, it will work as before without re-issuing key
as the previous code did not enforce that a key must be present.
Updates tailscale/tailscale#13451
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The ProxyGroup CRD specifies a set of N pods which will each be a
tailnet device, and will have M different ingress or egress services
mapped onto them. It is the mechanism for specifying how highly
available proxies need to be. This commit only adds the definition, no
controller loop, and so it is not currently functional.
This commit also splits out TailnetDevice and RecorderTailnetDevice
into separate structs because the URL field is specific to recorders,
but we want a more generic struct for use in the ProxyGroup status field.
Updates #13406
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Updates tailscale/tailscale#1634
Logs from some iOS users indicate that we're pointlessly performing captive portal detection on certain interfaces named ipsec*. These are tunnels with the cellular carrier that do not offer Internet access, and are only used to provide internet calling functionality (VoLTE / VoWiFi).
```
attempting to do captive portal detection on interface ipsec1
attempting to do captive portal detection on interface ipsec6
```
This PR excludes interfaces with the `ipsec` prefix from captive portal detection.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Add logic for parsing and matching against our planned format for
AcceptEnv values. Namely, this supports direct matches against string
values and matching where * and ? are treated as wildcard characters
which match against an arbitrary number of characters and a single
character respectively.
Actually using this logic in non-test code will come in subsequent
changes.
Updates https://github.com/tailscale/corp/issues/22775
Signed-off-by: Mario Minardi <mario@tailscale.com>
Like Linux, macOS will reply to sendto(2) with EPERM if the firewall is
currently blocking writes, though this behavior is like Linux
undocumented. This is often caused by a faulting network extension or
content filter from EDR software.
Updates #11710
Updates #12891
Updates #13511
Signed-off-by: James Tucker <james@tailscale.com>
This breaks its ability to be used as an expvar and is blocking a trunkd
deploy. Revert for now, and add a test to ensure that we don't break it
in a future change.
Updates #13550
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I1f1221c257c1de47b4bff0597c12f8530736116d
When querying for an exit node suggestion, occasionally it triggers a
new report concurrently with an existing report in progress. Generally,
there should always be a recent report or one in progress, so it is
redundant to start one there, and it causes concurrency issues.
Fixes#12643
Change-Id: I66ab9003972f673e5d4416f40eccd7c6676272a5
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
this commit changes usermetrics to be non-global, this is a building
block for correct metrics if a go process runs multiple tsnets or
in tests.
Updates #13420
Updates tailscale/corp#22075
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
So it doesn't delete and re-pull when switching between branches.
Updates tailscale/corp#17686
Change-Id: Iffb989781db42fcd673c5f03dbd0ce95972ede0f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add separate builds for DSM7.2 for synology so that we can encode
separate versioning information in the INFO file to distinguish between
the two.
Fixes https://github.com/tailscale/corp/issues/22908
Signed-off-by: Mario Minardi <mario@tailscale.com>
Updates tailscale/tailscale#13326
Adds a CLI subcommand to perform DNS queries using the internal DNS forwarder and observe its internals (namely, which upstream resolvers are being used).
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Pin re-actors/alls-green usage to latest 1.x. This was previously
pointing to `@release/v2` which pulls in the latest changes from this
branch as they are released, with the potential to break our workflows
if a breaking change or malicious version on this stream is ever pushed.
Changing this to a pinned version also means that dependabot will keep
this in the pinned version format (e.g., referencing a SHA) when it
opens a PR to bump the dependency.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Update and pin actions/upload-artifact usage to latest 4.x. These were
previously pointing to @3 which pulls in the latest v3 as they are
released, with the potential to break our workflows if a breaking change
or malicious version on the @3 stream is ever pushed.
Changing this to a pinned version also means that dependabot will keep
this in the pinned version format (e.g., referencing a SHA) when it
opens a PR to bump the dependency.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Update and pin actions/cache usage to latest 4.x. These were previously
pointing to `@3` which pulls in the latest v3 as they are released, with
the potential to break our workflows if a breaking change or malicious
version on the `@3` stream is ever pushed.
Changing this to a pinned version also means that dependabot will keep
this in the pinned version format (e.g., referencing a SHA) when it
opens a PR to bump the dependency.
The breaking change between v3 and v4 is that v4 requires Node 20 which
should be a non-issue where this is run.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Use slackapi/slack-github-action across the board and pin to latest 1.x.
Previously we were referencing the 1.27.0 tag directly which is
vulnerable to someone replacing that version tag with malicious code.
Replace usage of ruby/action-slack with slackapi/slack-github-action as
the latter is the officially supported action from slack.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Pin codeql actions usage to latest 3.x. These were previously pointing
to `@2` which pulls in the latest v2 as they are released, with the
potential to break our workflows if a breaking change or malicious
version on the `@2` stream is ever pushed.
Changing this to a pinned version also means that dependabot will keep
this in the pinend version format (e.g., referencing a SHA) when it
opens a PR to bump the dependency.
The breaking change between v2 and v3 is that v3 requires Node 20 which
is a non-issue as we are running this on ubuntu latest.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Pin actions/checkout usage to latest 5.x. These were previously pointing
to `@4` which pulls in the latest v4 as they are released, with the
potential to break our workflows if a breaking change or malicious
version on the `@4` stream is ever pushed.
Changing this to a pinned version also means that dependabot will keep
this in the pinend version format (e.g., referencing a SHA) when it
opens a PR to bump the dependency.
The breaking change between v4 and v5 is that v5 requires Node 20 which
should be a non-issue where it is used.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Pin actions/checkout usage to latest 3.x or 4.x as appropriate. These
were previously pointing to `@4` or `@3` which pull in the latest
versions at these tags as they are released, with the potential to break
our workflows if a breaking change or malicious version for either of
these streams are released.
Changing this to a pinned version also means that dependabot will keep
this in the pinend version format (e.g., referencing a SHA) when it
opens a PR to bump the dependency.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
Add an `AcceptEnv` field to `SSHRule`. This will contain the collection
of environment variable names / patterns that are specified in the
`acceptEnv` block for the SSH rule within the policy file. This will be
used in the tailscale client to filter out unacceptable environment
variables.
Updates: https://github.com/tailscale/corp/issues/22775
Signed-off-by: Mario Minardi <mario@tailscale.com>
Update go.toolchain.rev for https://github.com/tailscale/go/pull/104 and
add a test that, when using the tailscale_go build tag, we use the
right Go toolchain.
We'll crank up the strictness in later commits.
Updates #13527
Change-Id: Ifb09a844858be2beb144a420e4e9dbdc5c03ae3a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
containerboot's main.go had grown to well over 1000 lines with
lots of disparate bits of functionality. This commit is pure copy-
paste to group related functionality outside of the main function
into its own set of files. Everything is still in the main package
to keep the diff incremental and reviewable.
Updates #cleanup
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
mdnsResponder at least as of macOS Sequoia does not find NXDOMAIN
responses to these dns-sd PTR queries acceptable unless they include the
question section in the response. This was found debugging #13511, once
we turned on additional diagnostic reporting from mdnsResponder we
witnessed:
```
Received unacceptable 12-byte response from 100.100.100.100 over UDP via utun6/27 -- id: 0x7F41 (32577), flags: 0x8183 (R/Query, RD, RA, NXDomain), counts: 0/0/0/0,
```
If the response includes a question section, the resposnes are
acceptable, e.g.:
```
Received acceptable 59-byte response from 8.8.8.8 over UDP via en0/17 -- id: 0x2E55 (11861), flags: 0x8183 (R/Query, RD, RA, NXDomain), counts: 1/0/0/0,
```
This may be contributing to an issue under diagnosis in #13511 wherein
some combination of conditions results in mdnsResponder no longer
answering DNS queries correctly to applications on the system for
extended periods of time (multiple minutes), while dig against quad-100
provides correct responses for those same domains. If additional debug
logging is enabled in mdnsResponder we see it reporting:
```
Penalizing server 100.100.100.100 for 60 seconds
```
It is also possible that the reason that macOS & iOS never "stopped
spamming" these queries is that they have never been replied to with
acceptable responses. It is not clear if this special case handling of
dns-sd PTR queries was ever beneficial, and given this evidence may have
always been harmful. If we subsequently observe that the queries settle
down now that they have acceptable responses, we should remove these
special cases - making upstream queries very occasionally isn't a lot of
battery, so we should be better off having to maintain less special
cases and avoid bugs of this class.
Updates #2442
Updates #3025
Updates #3363
Updates #3594
Updates #13511
Signed-off-by: James Tucker <james@tailscale.com>
Updates tailscale/tailscale#13452
Bump the Go toolchain to the latest to pick up changes required to not crash on Android 9/10.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
In prep for upcoming flow tracking & mutex contention optimization
changes, this change refactors (subjectively simplifying) how the DERP
Server accounts for which peers have written to which other peers, to
be able to send PeerGoneReasonDisconnected messages to writes to
uncache their DRPO (DERP Return Path Optimization) routes.
Notably, this removes the Server.sentTo field which was guarded by
Server.mu and checked on all packet sends. Instead, the accounting is
moved to each sclient's sendLoop goroutine and now only needs to
acquire Server.mu for newly seen senders, the first time a peer sends
a packet to that sclient.
This change reduces the number of reasons to acquire Server.mu
per-packet from two to one. Removing the last one is the subject of an
upcoming change.
Updates #3560
Updates #150
Change-Id: Id226216d6629d61254b6bfd532887534ac38586c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This un-breaks vim-go (which doesn't understand "go 1.23") and allows
the natlab tests to work in a Nix shell (by adding the "qemu-img" and
"mkfs.ext4" binaries to the shell). These binaries are available even on
macOS, as I'm testing on my M1 Max.
Updates #13038
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I99f8521b5de93ea47dc33b099d5b243ffc1303da
Now that we have our API docs hosted at https://tailscale.com/api we can
remove the previous (and now outdated) markdown based docs. The top
level api.md has been left with the only content being the redirect to
the new docs.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
netcheck.Client.GetReport() applies its own deadlines. This 2s deadline
was causing GetReport() to never fall back to HTTPS/ICMP measurements
as it was shorter than netcheck.stunProbeTimeout, leaving no time
for fallbacks.
Updates #13394
Updates #6187
Signed-off-by: Jordan Whited <jordan@tailscale.com>
And update a few callers as examples of motivation. (there are a
couple others, but these are the ones where it's prettier)
Updates #cleanup
Change-Id: Ic8c5cb7af0a59c6e790a599136b591ebe16d38eb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
73280595a8 for #2751 added a "clientSet" interface to
distinguish the two cases of a client being singly connected (the
common case) vs tolerating multiple connections from the client at
once. At the time (three years ago) it was kinda an experiment
and we didn't know whether it'd stop the reconnect floods we saw
from certain clients. It did.
So this promotes it to a be first-class thing a bit, removing the
interface. The old tests from 73280595a were invaluable in ensuring
correctness while writing this change (they failed a bunch).
But the real motivation for this change is that it'll permit a future
optimization to add flow tracking for stats & performance where we
don't contend on Server.mu for each packet sent via DERP. Instead,
each client can track its active flows and hold on to a *clientSet and
ask the clientSet per packet what the active client is via one atomic
load rather than a mutex. And if the atomic load returns nil, we'll
know we need to ask the server to see if they died and reconnected and
got a new clientSet. But that's all coming later.
Updates #3560
Change-Id: I9ccda3e5381226563b5ec171ceeacf5c210e1faf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When the desired netfilter mode was unset, we would always try
to use the `iptables` binary. In such cases if iptables was not found,
tailscaled would just crash as seen in #13440. To work around this, in those
cases check if the `iptables` binary even exists and if it doesn't fall back
to the nftables implementation.
Verified that it works on stock Ubuntu 24.04.
Updates #5621
Updates #8555
Updates #8762Fixes#13440
Signed-off-by: Maisem Ali <maisem@tailscale.com>
cmd/k8s-operator,k8s-operator,kube: Add TSRecorder CRD + controller
Deploys tsrecorder images to the operator's cluster. S3 storage is
configured via environment variables from a k8s Secret. Currently
only supports a single tsrecorder replica, but I've tried to take early
steps towards supporting multiple replicas by e.g. having a separate
secret for auth and state storage.
Example CR:
```yaml
apiVersion: tailscale.com/v1alpha1
kind: Recorder
metadata:
name: rec
spec:
enableUI: true
```
Updates #13298
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
This mimics having Tailscale in the 'Stopped' state by programming an
empty DNS configuration when the current node key is expired.
Updates tailscale/support-escalations#55
Change-Id: I68ff4665761fb621ed57ebf879263c2f4b911610
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
It was scaring people. It's been pretty stable for quite some time now
and we're unlikely to change the API and break people at this point.
We might, but have been trying not to.
Fixestailscale/corp#22933
Change-Id: I0c3c79b57ccac979693c62ba320643a940ac947e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Rename kube/{types,client,api} -> kube/{kubetypes,kubeclient,kubeapi}
so that we don't need to rename the package on each import to
convey that it's kubernetes specific.
Updates#cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Further split kube package into kube/{client,api,types}. This is so that
consumers who only need constants/static types don't have to import
the client and api bits.
Updates#cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
We already disable dynamic updates by setting DisableDynamicUpdate to 1 for the Tailscale interface.
However, this does not prevent non-dynamic DNS registration from happening when `ipconfig /registerdns`
runs and in similar scenarios. Notably, dns/windowsManager.SetDNS runs `ipconfig /registerdns`,
triggering DNS registration for all interfaces that do not explicitly disable it.
In this PR, we update dns/windowsManager.disableDynamicUpdates to also set RegistrationEnabled to 0.
Fixes#13411
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We no longer need this on Windows, and it was never required on other platforms.
It just results in more short-lived connections unless we use HTTP/2.
Updates tailscale/corp#18342
Signed-off-by: Nick Khyl <nickk@tailscale.com>
When tailscaled restarts and our watch connection goes down, we get
stuck in an infinite loop printing `ipnbus error: EOF` (which ended up
consuming all the disk space on my laptop via the log file). Instead,
handle errors in `watchIPNBus` and reconnect after a short delay.
Updates #1708
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Disable TCP & UDP GRO if the probe fails.
torvalds/linux@e269d79c7d broke virtio_net
TCP & UDP GRO causing GRO writes to return EINVAL. The bug was then
resolved later in
torvalds/linux@89add40066. The offending
commit was pulled into various LTS releases.
Updates #13041
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Discovered this while investigating the following issue; I think it's
unrelated, but might as well fix it. Also, add a test helper for
checking things that have an IsZero method using the reflect package.
Updates tailscale/support-escalations#55
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I57b7adde43bcef9483763b561da173b4c35f49e2
When a rotation signature chain reaches a certain size, remove the
oldest rotation signature from the chain before wrapping it in a new
rotation signature.
Since all previous rotation signatures are signed by the same wrapping
pubkey (node's own tailnet lock key), the node can re-construct the
chain, re-signing previous rotation signatures. This will satisfy the
existing certificate validation logic.
Updates #13185
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
With the upcoming syspolicy changes, it's imperative that all syspolicy keys are defined in the syspolicy package
for proper registration. Otherwise, the corresponding policy settings will not be read.
This updates a couple of places where we still use string literals rather than syspolicy consts.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Updates tailscale/tailscale#13326
This PR begins implementing a `tailscale dns` command group in the Tailscale CLI. It provides an initial implementation of `tailscale dns status` which dumps the state of the internal DNS forwarder.
Two new endpoints were added in LocalAPI to support the CLI functionality:
- `/netmap`: dumps a copy of the last received network map (because the CLI shouldn't have to listen to the ipn bus for a copy)
- `/dns-osconfig`: dumps the OS DNS configuration (this will be very handy for the UI clients as well, as they currently do not display this information)
My plan is to implement other subcommands mentioned in tailscale/tailscale#13326, such as `query`, in later PRs.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This PR changes how LocalBackend handles interactive (initiated via StartLoginInteractive) and non-interactive (e.g., due to key expiration) logins,
and when it sends the authURL to the connected clients.
Specifically,
- When a user initiates an interactive login by clicking Log In in the GUI, the LocalAPI calls StartLoginInteractive.
If an authURL is available and hasn't expired, we immediately send it to all connected clients, suggesting them to open that URL in a browser.
Otherwise, we send a login request to the control plane and set a flag indicating that an interactive login is in progress.
- When LocalBackend receives an authURL from the control plane, we check if it differs from the previous one and whether an interactive login
is in progress. If either condition is true, we notify all connected clients with the new authURL and reset the interactive login flag.
We reset the auth URL and flags upon a successful authentication, when a different user logs in and when switching Tailscale login profiles.
Finally, we remove the redundant dedup logic added to WatchNotifications in #12096 and revert the tests to their original state to ensure that
calling StartLoginInteractive always produces BrowseToURL notifications, either immediately or when the authURL is received from the control plane.
Fixes#13296
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Updates tailscale/tailscale#177
It appears that the OSS distribution of `tailscaled` is currently unable to get the current system base DNS configuration, as GetBaseConfig() in manager_darwin.go is unimplemented. This PR adds a basic implementation that reads the current values in `/etc/resolv.conf`, to at least unblock DNS resolution via Quad100 if `--accept-dns` is enabled.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
We've added more probe targets recently which has resulted in more
timeouts behind restrictive NATs in localized testing that don't
like how many flows we are creating at once. Not so much an issue
for datacenter or cloud-hosted deployments.
Updates tailscale/corp#22114
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This reproduces the bug report from
https://github.com/tailscale/tailscale/issues/13346
It does not yet fix it.
Updates #13346
Change-Id: Ia5af7b0481a64a37efe259c798facdda6d9da618
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We add package defining interfaces for policy stores, enabling creation of policy sources
and reading settings from them. It includes a Windows-specific PlatformPolicyStore for GP and MDM
policies stored in the Registry, and an in-memory TestStore for testing purposes.
We also include an internal package that tracks and reports policy usage metrics when a policy setting
is read from a store. Initially, it will be used only on Windows and Android, as macOS, iOS, and tvOS
report their own metrics. However, we plan to use it across all platforms eventually.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
* cmd/k8s-operator,k8s-operator/sessonrecording: ensure CastHeader contains terminal size
For tsrecorder to be able to play session recordings, the recording's
CastHeader must have '.Width' and '.Height' fields set to non-zero.
Kubectl (or whoever is the client that initiates the 'kubectl exec'
session recording) sends the terminal dimensions in a resize message that
the API server proxy can intercept, however that races with the first server
message that we need to record.
This PR ensures we wait for the terminal dimensions to be processed from
the first resize message before any other data is sent, so that for all
sessions with terminal attached, the header of the session recording
contains the terminal dimensions and the recording can be played by tsrecorder.
Updates tailscale/tailscale#19821
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Previously, despite what the commit said, we were using a raw IP socket
that was *not* an AF_PACKET socket, and thus was subject to the host
firewall rules. Switch to using a real AF_PACKET socket to actually get
the functionality we want.
Updates #13140
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If657daeeda9ab8d967e75a4f049c66e2bca54b78
I should've bumped capver in 65fe0ba7b5 but forgot.
This lets us turn off the cryptokey routing change from control for
the affected panicky range of commits, based on capver.
Updates #13332
Updates tailscale/corp#20732
Change-Id: I32c17cfcb45b2369b2b560032330551d47a0ce0b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Both for Raspberry Pis, and for running natlab tests faster on Apple
Silicon Macs without emulating x86.
Not fully wired up yet.
Updates #1866
Updates #13038
Change-Id: I1552bf107069308f325f640773cc881ed735b5ab
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
No need to make callers specify the redundant IP version or
TTL/HopLimit or EthernetType in the common case. The mkPacket helper
can set those when unset.
And use the mkIPLayer in another place, simplifying some code.
And rename mkPacketErr to just mkPacket, then move mkPacket to
test-only code, as mustPacket.
Updates #13038
Change-Id: Ic216e44dda760c69ab9bfc509370040874a47d30
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And clean up some of the test helpers in the process.
Updates #13038
Change-Id: I3e2b5f7028a32d97af7f91941e59399a8e222b25
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I'd added this helper for tests, but then moved it to non-test code
and forgot some places to use it. This uses it in more places to
remove some boilerplate.
Updates #13038
Change-Id: Ic4dc339be1c47a55b71d806bab421097ee3d75ed
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Logging serial numbers every time they are read might have been useful
early on, but seems unnecessary now.
Updates #5902
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
The LocalBackend's state machine starts in NoState and soon transitions to NeedsLogin if there's no auto-start profile,
with the profileManager starting with a new empty profile. Notably, entering the NeedsLogin state blocks engine updates.
We expect the user to transition out of this state by logging in interactively, and we set WantRunning to true when
controlclient enters the StateAuthenticated state.
While our intention is correct, and completing an interactive login should set WantRunning to true, our assumption
that logging into the current Tailscale profile is the only way to transition out of the NeedsLogin state is not accurate.
Another common transition path includes an explicit profile switch (via LocalBackend.SwitchProfile) or an implicit switch
when a Windows user connects to the backend. This results in a bug where WantRunning is set to true even when it was
previously set to false, and the user expressed no intention of changing it.
A similar issue occurs when switching from (sic) a Tailnet that has seamlessRenewalEnabled, regardless of the current state
of the LocalBackend's state machine, and also results in unexpectedly set WantRunning. While this behavior is generally
undesired, it is also incorrect that it depends on the control knobs of the Tailnet we're switching from rather than
the Tailnet we're switching to. However, this issue needs to be addressed separately.
This PR updates LocalBackend.SetControlClientStatus to only set WantRunning to true in response to an interactive login
as indicated by a non-empty authURL.
Fixes#6668Fixes#11280
Updates #12756
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This adds tests for DNS requests, and ignoring IPv6 packets on v4-only
networks.
No behavior changes. But some things are pulled out into functions.
And the mkPacket helpers previously just for tests are moved into
non-test code to be used elsewhere to reduce duplication, doing the
checksum stuff automatically.
Updates #13038
Change-Id: I4dd0b73c75b2b9567b4be3f05a2792999d83f6a3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When the TS_DEBUG_NETSTACK_LOOPBACK_PORT environment variable is set,
netstack will loop back (dnat to addressFamilyLoopback:loopbackPort)
TCP & UDP flows originally destined to localServicesIP:loopbackPort.
localServicesIP is quad-100 or the IPv6 equivalent.
Updates tailscale/corp#22713
Signed-off-by: Jordan Whited <jordan@tailscale.com>
In preparation for multi-user and unattended mode improvements, we are
refactoring and cleaning up `ipn/ipnlocal.profileManager`. The concept of the
"current user", which is only relevant on Windows, is being deprecated and will
soon be removed to allow more than one Windows user to connect and utilize
`LocalBackend` according to that user's access rights to the device and specific
Tailscale profiles.
We plan to pass the user's identity down to the `profileManager`, where it can
be used to determine the user's access rights to a given `LoginProfile`. While
the new permission model in `ipnauth` requires more work and is currently
blocked pending PR reviews, we are updating the `profileManager` to reduce its
reliance on the concept of a single OS user being connected to the backend at
the same time.
We extract the switching to the default Tailscale profile, which may also
trigger legacy profile migration, from `profileManager.SetCurrentUserID`. This
introduces `profileManager.DefaultUserProfileID`, which returns the default
profile ID for the current user, and `profileManager.SwitchToDefaultProfile`,
which is essentially a shorthand for `pm.SwitchProfile(pm.DefaultUserProfileID())`.
Both methods will eventually be updated to accept the user's identity and
utilize that user's default profile.
We make access checks more explicit by introducing the `profileManager.checkProfileAccess`
method. The current implementation continues to use `profileManager.currentUserID`
and `LoginProfile.LocalUserID` to determine whether access to a given profile
should be granted. This will be updated to utilize the `ipnauth` package and the
new permissions model once it's ready. We also expand access checks to be used
more widely in the `profileManager`, not just when switching or listing
profiles. This includes access checks in methods like `SetPrefs` and, most notably,
`DeleteProfile` and `DeleteAllProfiles`, preventing unprivileged Windows users
from deleting Tailscale profiles owned by other users on the same device,
including profiles owned by local admins.
We extract `profileManager.ProfilePrefs` and `profileManager.SetProfilePrefs`
methods that can be used to get and set preferences of a given `LoginProfile` if
`profileManager.checkProfileAccess` permits access to it.
We also update `profileManager.setUnattendedModeAsConfigured` to always enable
unattended mode on Windows if `Prefs.ForceDaemon` is true in the current
`LoginProfile`, even if `profileManager.currentUserID` is `""`. This facilitates
enabling unattended mode via `tailscale up --unattended` even if
`tailscale-ipn.exe` is not running, such as when a Group Policy or MDM-deployed
script runs at boot time, or when Tailscale is used on a Server Code or otherwise
headless Windows environments. See #12239, #2137, #3186 and
https://github.com/tailscale/tailscale/pull/6255#issuecomment-2016623838 for
details.
Fixes#12239
Updates tailscale/corp#18342
Updates #3186
Updates #2137
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This adds support for sending packets to 33:33:00:00:01 at IPv6
multicast address ff02::1 to send to all nodes.
Nothing in Tailscale depends on this (yet?), but it makes debugging in
VMs behind natlab easier (e.g. you can ping all nodes), and other
things might depend on this in the future.
Mostly I'm trying to flesh out the IPv6 support in natlab now that we
can write vnet tests.
Updates #13038
Change-Id: If590031fcf075690ca35c7b230a38c3e72e621eb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Currently, we use PermitRead/PermitWrite/PermitCert permission flags to determine which operations are allowed for a LocalAPI client.
These checks are performed when localapi.Handler handles a request. Additionally, certain operations (e.g., changing the serve config)
requires the connected user to be a local admin. This approach is inherently racey and is subject to TOCTOU issues.
We consider it to be more critical on Windows environments, which are inherently multi-user, and therefore we prevent more than one
OS user from connecting and utilizing the LocalBackend at the same time. However, the same type of issues is also applicable to other
platforms when switching between profiles that have different OperatorUser values in ipn.Prefs.
We'd like to allow more than one Windows user to connect, but limit what they can see and do based on their access rights on the device
(e.g., an local admin or not) and to the currently active LoginProfile (e.g., owner/operator or not), while preventing TOCTOU issues on Windows
and other platforms. Therefore, we'd like to pass an actor from the LocalAPI to the LocalBackend to represent the user performing the operation.
The LocalBackend, or the profileManager down the line, will then check the actor's access rights to perform a given operation on the device
and against the current (and/or the target) profile.
This PR does not change the current permission model in any way, but it introduces the concept of an actor and includes some preparatory
work to pass it around. Temporarily, the ipnauth.Actor interface has methods like IsLocalSystem and IsLocalAdmin, which are only relevant
to the current permission model. It also lacks methods that will actually be used in the new model. We'll be adding these gradually in the next
PRs and removing the deprecated methods and the Permit* flags at the end of the transition.
Updates tailscale/corp#18342
Signed-off-by: Nick Khyl <nickk@tailscale.com>
To test how virtual machines connect to the natlab vnet code.
Updates #13038
Change-Id: Ia4fd4b0c1803580ee7d94cc9878d777ad4f24f82
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And refactor some of vnet.go for testability.
The only behavioral change (with a new test) is that ethernet
broadcasts no longer get sent back to the sender.
Updates #13038
Change-Id: Ic2e7e7d6d8805b7b7f2b5c52c2c5ba97101cef14
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit adds a new usermetric package and wires
up metrics across the tailscale client.
Updates tailscale/corp#22075
Co-authored-by: Anton Tolchanov <anton@tailscale.com>
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This was previously disabled in 8e42510 due to missing GSO-awareness in
tstun, which was resolved in d097096.
Updates tailscale/corp#22511
Signed-off-by: Jordan Whited <jordan@tailscale.com>
The bad naming (which had only been half updated with the IPv6
changes) tripped me up in the earlier change.
Updates #13038
Change-Id: I65ce07c167e8219d35b87e1f4bf61aab4cac31ff
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The reason they weren't working was because the cmd/tta agent in the
guest was dialing out to the test and the vnet couldn't map its global
unicast IPv6 address to a node as it was just using a
map[netip.Addr]*node and blindly trusting the *node was
populated. Instead, it was nil, so the agent connection fetching
didn't work for its RoundTripper and the test could never drive the
node. That map worked for IPv4 but for IPv6 we need to use the method
that takes into account the node's IPv6 SLAAC address. Most call sites
had been converted but I'd missed that one.
Also clean up some debug, and prohibit nodes' link-local unicast
addresses from dialing 2000::/3 directly for now. We can allow that to
be configured opt-in later (some sort of IPv6 NAT mode. Whatever it's
called.) That mode was working on accident, but was confusing: Linux
would do source address selection from link local for the first few
seconds and then after SLAAC and DAD, switch to using the global
unicast source address. Be consistent for now and force it to use the
global unicast.
Updates #13038
Change-Id: I85e973aaa38b43c14611943ff45c7c825ee9200a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Really we need to fix logpolicy + bootstrapDNS to not be so aggressive,
but this is a quick workaround meanwhile.
Without this, tailscaled starts immediately while IPv6 DAD is
happening for a couple seconds and logpolicy freaks out without the
network available and starts spamming stderr about bootstrap DNS
options. But we see that regularly anyway from people whose wifi is
down. So we need to fix the general case. This is not that fix.
Updates #13038
Change-Id: Iba7e536d08e59d34abded1d279f88fdc9c46d94d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There were a few places it could get wedged (notably the dial without
a timeout).
And add a knob for verbose debug logs.
And keep two idle connections always.
Updates #13038
Change-Id: I952ad182d7111481d97a83c12aa2ff4bfdc55fe8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Move all the UDP handling to its own func to remove a bunch of "if
isUDP" checks in a bunch of blocks.
Updates #13038
Change-Id: If71d71b49e57651d15bd307a2233c43751cc8639
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I didn't actually see this, but added this while debugging something
and figured it'd be good to keep.
Updates #13038
Change-Id: I67934c8a329e0233f79c3b08516fd6bad6bfe22a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On a major link change the LAN routes may change, so on linkChange where
ChangeDelta.Major, we need to call authReconfig to ensure that new
routes are observed and applied.
Updates tailscale/corp#22574
Signed-off-by: James Tucker <james@tailscale.com>
This is the equivalent of quad-100, but for IPv6. This is technically
already contained in the Tailscale IPv6 ULA prefix, but that is only
installed when remote peers are visible via control with contained
addrs. The service addr should always be reachable.
Updates #1152
Signed-off-by: Jordan Whited <jordan@tailscale.com>
And sprinkle some more docs around.
Updates #13038
Change-Id: Ia2dcf567b68170481cc2094d64b085c6b94a778a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We have several checked type assertions to *types.Named in both cmd/cloner and cmd/viewer.
As Go 1.23 updates the go/types package to produce Alias type nodes for type aliases,
these type assertions no longer work as expected unless the new behavior is disabled
with gotypesalias=0.
In this PR, we add codegen.NamedTypeOf(t types.Type), which functions like t.(*types.Named)
but also unrolls type aliases. We then use it in place of type assertions in the cmd/cloner and
cmd/viewer packages where appropriate.
We also update type switches to include *types.Alias alongside *types.Named in relevant cases,
remove *types.Struct cases when switching on types.Type.Underlying and update the tests
with more cases where type aliases can be used.
Updates #13224
Updates #12912
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Go 1.23 updates the go/types package to produce Alias type nodes for type aliases, unless disabled with gotypesalias=0.
This new default behavior breaks codegen.LookupMethod, which uses checked type assertions to types.Named and
types.Interface, as only named types and interfaces have methods.
In this PR, we update codegen.LookupMethod to perform method lookup on the right-hand side of the alias declaration
and clearly switch on the supported type nodes types. We also improve support for various edge cases, such as when an alias
is used as a type parameter constraint, and add tests for the LookupMethod function.
Additionally, we update cmd/viewer/tests to include types with aliases used in type fields and generic type constraints.
Updates #13224
Updates #12912
Signed-off-by: Nick Khyl <nickk@tailscale.com>
All the magic service names with virtual IPs will need IPv6 variants.
Pull this out in prep.
Updates #13038
Change-Id: I53b5eebd0679f9fa43dc0674805049258c83a0de
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So we don't log about them when verbose logging is enabled.
Updates #13038
Change-Id: I925bc3a23e6c93d60dd4fb4bf6a4fdc5a326de95
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The natlab Test Agent (tta) still had its old log streaming hack in
place where it dialed out to anything on TCP port 124 and those logs
were streamed to the host running the tests. But we'd since added gokrazy
syslog streaming support, which made that redundant.
So remove all the port 124 stuff. And then make sure we log to stderr
so gokrazy logs it to syslog.
Also, keep the first 1MB of logs in memory in tta too, exported via
localhost:8034/logs for interactive debugging. That was very useful
during debugging when I added IPv6 support. (which is coming in future
PRs)
Updates #13038
Change-Id: Ieed904a704410b9031d5fd5f014a73412348fa7f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Otherwise you get "Access denied: watch IPN bus access denied, must
set ipn.NotifyNoPrivateKeys when not running as admin/root or
operator".
This lets a non-operator at least start the app and see the status, even
if they can't change everything. (the web UI is unaffected by operator)
A future change can add a LocalAPI call to check permissions and guide
people through adding a user as an operator (perhaps the web client
can do that?)
Updates #1708
Change-Id: I699e035a251b4ebe14385102d5e7a2993424c4b7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds a systray app for linux, similar to the apps for macOS and
windows. There are already a number of community-developed systray apps,
but most of them are either long abandoned, are built for a specific
desktop environment, or simply wrap the tailscale CLI.
This uses fyne.io/systray (a fork of github.com/getlantern/systray)
which uses newer D-Bus specifications to render the tray icon and menu.
This results in a pretty broad support for modern desktop environments.
This initial commit lacks a number of features like profile switching,
device listing, and exit node selection. This is really focused on the
application structure, the interaction with LocalAPI, and some system
integration pieces like the app icon, notifications, and the clipboard.
Updates #1708
Signed-off-by: Will Norris <will@tailscale.com>
updates tailcale/corp#22371
For dgram mode, we need to store the write addresses of
the client socket(s) alongside the writer functions and
the write operation needs to use WriteToUnix.
Unix also has multiple clients writing to the same socket,
so the serve method is modified to handle packets from
multiple mac addresses.
Cleans up a bit of cruft from the initial tailmac tooling
commit.
Now all the macOS packets are belong to us.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
After the upstream PR is merged, we can point directly at github.com/vishvananda/netlink
and retire github.com/tailscale/netlink.
See https://github.com/vishvananda/netlink/pull/1006
Updates #12298
Signed-off-by: Percy Wegmann <percy@tailscale.com>
And convert a few callers as an example, but nowhere near all.
Updates #12912
Change-Id: I5eaa12a29a6cd03b58d6f1072bd27bc0467852f2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for updating to new staticcheck required for Go 1.23.
Updates #12912
Change-Id: If77892a023b79c6fa798f936fc80428fd4ce0673
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
To avoid dig vs nslookup vs $X availability issues between
OSes/distros. And to be in Go, to match the resolver we use.
Updates #13038
Change-Id: Ib7e5c351ed36b5470a42cbc230b8f27eed9a1bf8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
net/tstun.Wrapper.InjectInboundPacketBuffer is not GSO-aware, which can
break quad-100 TCP streams as a result. Linux is the only platform where
gVisor GSO was previously enabled.
Updates tailscale/corp#22511
Updates #13211
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Instead of changing the working directory before launching the incubator process,
this now just changes the working directory after dropping privileges, at which
point we're more likely to be able to enter the user's home directory since we're
running as the user.
For paths that use the 'login' or 'su -l' commands, those already take care of changing
the working directory to the user's home directory.
Fixes#13120
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This adds a new package containing generic types to be used for defining preference hierarchies.
These include prefs.Item, prefs.List, prefs.StructList, and prefs.StructMap. Each of these types
represents a configurable preference, holding the preference's state, value, and metadata.
The metadata includes the default value (if it differs from the zero value of the Go type)
and flags indicating whether a preference is managed via syspolicy or is hidden/read-only for
another reason. This information can be marshaled and sent to the GUI, CLI and web clients
as a source of truth regarding preference configuration, management, and visibility/mutability states.
We plan to use these types to define device preferences, such as the updater preferences,
the permission mode to be used on Windows with #tailscale/corp#18342, and certain global options
that are currently exposed as tailscaled flags. We also aim to eventually use these types for
profile-local preferences in ipn.Prefs and and as a replacement for ipn.MaskedPrefs.
The generic preference types are compatible with the tailscale.com/cmd/viewer and
tailscale.com/cmd/cloner utilities.
Updates #12736
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In Tailnet Lock, there is an implicit limit on the number of rotation
signatures that can be chained before the signature becomes too long.
This program helps tailnet admins to identify nodes that have signatures
with long chains and prints commands to re-sign those node keys with a
fresh direct signature. It's a temporary mitigation measure, and we will
remove this tool as we design and implement a long-term approach for
rotation signatures.
Example output:
```
2024/08/20 18:25:03 Self: does not need re-signing
2024/08/20 18:25:03 Visible peers with valid signatures:
2024/08/20 18:25:03 Peer xxx2.yy.ts.net. (100.77.192.34) nodeid=nyDmhiZiGA11KTM59, current signature kind=direct: does not need re-signing
2024/08/20 18:25:03 Peer xxx3.yy.ts.net. (100.84.248.22) nodeid=ndQ64mDnaB11KTM59, current signature kind=direct: does not need re-signing
2024/08/20 18:25:03 Peer xxx4.yy.ts.net. (100.85.253.53) nodeid=nmZfVygzkB21KTM59, current signature kind=rotation: chain length 4, printing command to re-sign
tailscale lock sign nodekey:530bddbfbe69e91fe15758a1d6ead5337aa6307e55ac92dafad3794f8b3fc661 tlpub:4bf07597336703395f2149dce88e7c50dd8694ab5bbde3d7c2a1c7b3e231a3c2
```
To support this, the NetworkLockStatus localapi response now includes
information about signatures of all peers rather than just the invalid
ones. This is not displayed by default in `tailscale lock status`, but
will be surfaced in `tailscale lock status --json`.
Updates #13185
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This involved the following:
1. Pass the su command path as first of args in call to unix.Exec to make sure that busybox sees the correct program name.
Busybox is a single executable userspace that implements various core userspace commands in a single binary. You'll
see it used via symlinking, so that for example /bin/su symlinks to /bin/busybox. Busybox knows that you're trying
to execute /bin/su because argv[0] is '/bin/su'. When we called unix.Exec, we weren't including the program name for
argv[0], which caused busybox to fail with 'applet not found', meaning that it didn't know which command it was
supposed to run.
2. Tell su to whitelist the SSH_AUTH_SOCK environment variable in order to support ssh agent forwarding.
3. Run integration tests on alpine, which uses busybox.
4. Increment CurrentCapabilityVersion to allow turning on SSH V2 behavior from control.
Fixes#12849
Signed-off-by: Percy Wegmann <percy@tailscale.com>
In df6014f1d7 we removed build tag
gating preventing importation, which tripped a NetworkExtension limit
test in corp. This was a reversal of
25f0a3fc8f which actually made the
situation worse, hence the simplification.
This commit goes back to the strategy in
25f0a3fc8f, and gets us back under the
limit in my local testing. Admittedly, we don't fully understand
the effects of importing or excluding importation of this package,
and have seen mixed results, but this commit allows us to move forward
again.
Updates tailscale/corp#22125
Signed-off-by: Jordan Whited <jordan@tailscale.com>
In 2f27319baf we disabled GRO due to a
data race around concurrent calls to tstun.Wrapper.Write(). This commit
refactors GRO to be thread-safe, and re-enables it on Linux.
This refactor now carries a GRO type across tstun and netstack APIs
with a lifetime that is scoped to a single tstun.Wrapper.Write() call.
In 25f0a3fc8f we used build tags to
prevent importation of gVisor's GRO package on iOS as at the time we
believed it was contributing to additional memory usage on that
platform. It wasn't, so this commit simplifies and removes those
build tags.
Updates tailscale/corp#22353
Updates tailscale/corp#22125
Updates #6816
Signed-off-by: Jordan Whited <jordan@tailscale.com>
cmd/k8s-operator/deploy: replace wildcards in Kubernetes Operator RBAC role definitions with verbs
fixes: #13168
Signed-off-by: Pierig Le Saux <pierig@n3xt.io>
Updates tailscale/corp#22120
Adds the ability to start the backend by reading an authkey stored in the syspolicy database (MDM). This is useful for devices that are provisioned in an unattended fashion.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
updates tailcale/corp#22371
Adds custom macOS vm tooling. See the README for
the general gist, but this will spin up VMs with unixgram
capable network interfaces listening to a named socket,
and with a virtio socket device for host-guest communication.
We can add other devices like consoles, serial, etc as needed.
The whole things is buildable with a single make command, and
everything is controllable via the command line using the TailMac
utility.
This should all be generally functional but takes a few shortcuts
with error handling and the like. The virtio socket device support
has not been tested and may require some refinement.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
Some machines have multiple network interfaces with the same MAC
address.
Updates tailscale/corp#21371
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
`DNS unavailable` was marked as a high severity warning. On Android (and other platforms), these trigger a system notification. Here we reduce the severity level to medium. A medium severity warning will still display the warning icon on platforms with a tray icon because of the `ImpactsConnectivity=true` flag being set here, but it won't show a notification anymore. If people enter an area with bad cellular reception, they're bound to receive so many of these notifications and we need to reduce notification fatigue.
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
In a93dc6cdb1 tryUpgradeToBatchingConn()
moved to build tag gated files, but the runtime.GOOS condition excluding
Android was removed unintentionally from batching_conn_linux.go. Add it
back.
Updates tailscale/corp#22348
Signed-off-by: Jordan Whited <jordan@tailscale.com>
By default, Windows sets the SIO_UDP_CONNRESET and SIO_UDP_NETRESET
options on created UDP sockets. These behaviours make the UDP socket
ICMP-aware; when the system gets an ICMP message (e.g. an "ICMP Port
Unreachable" message, in the case of SIO_UDP_CONNRESET), it will cause
the underlying UDP socket to throw an error. Confusingly, this can occur
even on reads, if the same UDP socket is used to write a packet that
triggers this response.
The Go runtime disabled the SIO_UDP_CONNRESET behavior in 3114bd6, but
did not change SIO_UDP_NETRESET–probably because that socket option
isn't documented particularly well.
Various other networking code seem to disable this behaviour, such as
the Godot game engine (godotengine/godot#22332) and the Eclipse TCF
agent (link below). Others appear to work around this by ignoring the
error returned (anacrolix/dht#16, among others).
For now, until it's clear whether this ends up in the upstream Go
implementation or not, let's also disable the SIO_UDP_NETRESET in a
similar manner to SIO_UDP_CONNRESET.
Eclipse TCF agent: https://gitlab.eclipse.org/eclipse/tcf/tcf.agent/-/blob/master/agent/tcf/framework/mdep.c
Updates #10976
Updates golang/go#68614
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I70a2f19855f8dec1bfb82e63f6d14fc4a22ed5c3
Coder has just adopted nhooyr/websocket which unfortunately changes the import path.
`github.com/coder/coder` imports `tailscale.com/net/wsconn` which was still pointing
to `nhooyr.io/websocket`, but this change updates it.
See https://coder.com/blog/websocket
Updates #13154
Change-Id: I3dec6512472b14eae337ae22c5bcc1e3758888d5
Signed-off-by: Kyle Carberry <kyle@carberry.com>
This PR modifies viewTypeForContainerType to use the last type parameter of a container type
as the value type, enabling the implementation of map-like container types where the second-to-last
(usually first) type parameter serves as the key type.
It also adds a MapContainer type to test the code generation.
Updates #12736
Signed-off-by: Nick Khyl <nickk@tailscale.com>
A SIGSEGV was observed around packet merging logic in gVisor's GRO
package.
Updates tailscale/corp#22353
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This prevents two things:
1. Crashing if there's no response body
2. Sending a nonsensical 0 response status code
Updates tailscale/corp#22357
Signed-off-by: Percy Wegmann <percy@tailscale.com>
cmd/k8s-operator,k8s-operator/sessionrecording: support recording WebSocket sessions
Kubernetes currently supports two streaming protocols, SPDY and WebSockets.
WebSockets are replacing SPDY, see
https://github.com/kubernetes/enhancements/issues/4006.
We were currently only supporting SPDY, erroring out if session
was not SPDY and relying on the kube's built-in SPDY fallback.
This PR:
- adds support for parsing contents of 'kubectl exec' sessions streamed
over WebSockets
- adds logic to distinguish 'kubectl exec' requests for a SPDY/WebSockets
sessions and call the relevant handler
Updates tailscale/corp#19821
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
Add functionality to optionally serve a health check endpoint
(off by default).
Users can enable health check endpoint by setting
TS_HEALTHCHECK_ADDR_PORT to [<addr>]:<port>.
Containerboot will then serve an unauthenticatd HTTP health check at
/healthz at that address. The health check returns 200 OK if the
node has at least one tailnet IP address, else returns 503.
Updates tailscale/tailscale#12898
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This latest version allows for building on various OpenBSD architectures.
(such as openbsd/riscv64)
Updates #8043
Change-Id: Ie9a8738e6aa96335214d5750e090db35e526a4a4
Signed-off-by: Aaron Bieber <aaron@bolddaemon.com>
... rather than abusing the generic tsapp.
Per discussion in https://github.com/gokrazy/gokrazy/pull/275
It also means we can remove stuff we don't need, like ntp or randomd.
Updates #13038
Change-Id: Iccf579c354bd3b5025d05fa1128e32f1d5bde4e4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It's too new to be supported in Debian bookworm so just remove it.
It doesn't seem to matter or help speed anything up.
Updates #13038
Change-Id: I39077ba8032bebecd75209552b88f1842c843c33
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
84adfa1ba3 made MAC addresses 1-based too, but didn't adjust this IP address
calculation which was based on the MAC address
Updates #13038
Change-Id: Idc112b303b0b85f41fe51fd61ce1c0d8a3f0f57e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The heartbeat package does nothing if not configured anyway, so don't
even put it in the image and pay the cost of it running.
Updates #13038
Updates #1866
Change-Id: Id22c0fb1f8395ad21ab0e0350973d31730e8d39f
The change in b7e48058c8 was too loose; it also captured the CLI
being run as a child process under cmd/tta.
Updates #13038
Updates #1866
Change-Id: Id410b87132938dd38ed4dd3959473c5d0d242ff5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* cmd/k8s-operator: fix DNS reconciler for dual-stack clusters
This fixes a bug where DNS reconciler logic was always assuming
that no more than one EndpointSlice exists for a Service.
In fact, there can be multiple, for example, in dual-stack
clusters, but also in other cases this is valid (as per kube docs).
This PR:
- allows for multiple EndpointSlices
- picks out the ones for IPv4 family
- deduplicates addresses
Updates tailscale/tailscale#13056
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Tom Proctor <tomhjp@users.noreply.github.com>
These three packages aren't in gokrazy/tsapp/config.json but
used to be. Unfortunately, that meant that were being included
in the resulting image. Apparently `gok` doesn't delete them or
warn about them being present on disk when they're moved from
the config file.
Updates #13038
Updates #1866
Change-Id: I54918a9e3286ea755b11dde5e9efdd433b8f8fb8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We had a mix of 0-based and 1-based nodes and MACs in logs.
Updates #13038
Change-Id: I36d1b00f7f94b37b4ae2cd439bcdc5dbee6eda4d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Using https://github.com/gokrazy/gokrazy/pull/275
This is much lower latency than logcatcher, which is higher latency
and chunkier. And this is better than getting it via 'tailscale debug
daemon-logs', which misses early interesting logs.
Updates #13038
Change-Id: I499ec254c003a9494c0e9910f9c650c8ac44ef33
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Package setting contains types for defining and representing policy settings.
It facilitates the registration of setting definitions using Register and RegisterDefinition,
and the retrieval of registered setting definitions via Definitions and DefinitionOf.
This package is intended for use primarily within the syspolicy package hierarchy,
and added in a preparation for the next PRs.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In particular, tests showing that #3824 works. But that test doesn't
actually work yet; it only gets a DERP connection. (why?)
Updates #13038
Change-Id: Ie1fd1b6a38d4e90fae7e72a0b9a142a95f0b2e8f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Similar to UseSocketOnly, but pulled out separately in case
people are doing unknown weird things.
Updates #13038
Change-Id: I7478e5cb9794439b947440b831caa798941845ea
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
getConns() is now responsible for returning both stable and unstable
conns. conn and measureFn are now passed together via connAndMeasureFn.
newConnAndMeasureFn() is responsible for constructing them.
TCP measurement timeouts are adjusted to more closely match netcheck.
Updates tailscale/corp#22114
Signed-off-by: Jordan Whited <jordan@tailscale.com>
To test local connections.
Updates #13038
Change-Id: I575dcab31ca812edf7d04fa126772611cf89b9a7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds a new NodeAgentClient type that can be used to
invoke the LocalAPI using the LocalClient instead of
handcrafted URLs. However, there are certain cases where
it does make sense for the node agent to provide more
functionality than whats possible with just the LocalClient,
as such it also exposes a http.Client to make requests directly.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
And don't make guests under vnet/natlab upload to logcatcher,
as there won't be a valid cert anyway.
Updates #13038
Change-Id: Ie1ce0139788036b8ecc1804549a9b5d326c5fef5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
'stun' has been removed from metric names and replaced with a protocol
label. This refactor is preparation work for HTTPS & ICMP support.
Updates tailscale/corp#22114
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Troubleshooting DNS resolution issues often requires additional information.
This PR expands the effect of the TS_DEBUG_DNS_FORWARD_SEND envknob to forwarder.forwardWithDestChan,
and includes the request type, domain name length, and the first 3 bytes of the domain's SHA-256 hash in the output.
Fixes#13070
Signed-off-by: Nick Khyl <nickk@tailscale.com>
In a situation when manual edits are made on the admin panel, around the
GitOps process, the pusher will be stuck if `--fail-on-manual-edits` is
set, as expected.
To recover from this, there are 2 options:
1. revert the admin panel changes to get back in sync with the code
2. check in the manual edits to code
The former will work well, since previous and local ETags will match
control ETag again. The latter will still fail, since local and control
ETags match, but previous does not.
For this situation, check the local ETag against control first and
ignore previous when things are already in sync.
Updates https://github.com/tailscale/corp/issues/22177
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
For cases where users want to be extra careful about not overwriting
manual changes, add a flag to hard-fail. This is only useful if the etag
cache is persistent or otherwise reliable. This flag should not be used
in ephemeral CI workers that won't persist the cache.
Updates https://github.com/tailscale/corp/issues/22177
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
* cmd/tsidp: add funnel support
Updates #10263.
Signed-off-by: Naman Sood <mail@nsood.in>
* look past funnel-ingress-node to see who we're authenticating
Signed-off-by: Naman Sood <mail@nsood.in>
* fix comment typo
Signed-off-by: Naman Sood <mail@nsood.in>
* address review feedback, support Basic auth for /token
Turns out you need to support Basic auth if you do client ID/secret
according to OAuth.
Signed-off-by: Naman Sood <mail@nsood.in>
* fix typos
Signed-off-by: Naman Sood <mail@nsood.in>
* review fixes
Signed-off-by: Naman Sood <mail@nsood.in>
* remove debugging log
Signed-off-by: Naman Sood <mail@nsood.in>
* add comments, fix header
Signed-off-by: Naman Sood <mail@nsood.in>
---------
Signed-off-by: Naman Sood <mail@nsood.in>
This commit adds a batchingConn interface, and renames batchingUDPConn
to linuxBatchingConn. tryUpgradeToBatchingConn() may return a platform-
specific implementation of batchingConn. So far only a Linux
implementation of this interface exists, but this refactor is being
done in anticipation of a Windows implementation.
Updates tailscale/corp#21874
Signed-off-by: Jordan Whited <jordan@tailscale.com>
The same context we use for the HTTP request here might be re-used by
the dialer, which could result in `GotConn` being called multiple times.
We only care about the last one.
Fixes#13009
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This change adds an HTTP handler with a table showing a list of all
probes, their status, and a button that allows triggering a specific
probe.
Updates tailscale/corp#20583
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
- Keep track of the last 10 probe results and successful probe
latencies;
- Add an HTTP handler that triggers a given probe by name and returns it
result as a plaintext HTML page, showing recent probe results as a
baseline
Updates tailscale/corp#20583
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
I noticed a few places with custom http.Transport where we are not
closing idle connections when transport is no longer used.
Updates tailscale/corp#21609
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
During review of #8644 the `recover-compromised-key` command was renamed
to `revoke-key`, but the old name remained in some messages printed by
the command.
Fixestailscale/corp#19446
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
We were copying 12 out of the 16 bytes which meant that
the 1:1 NAT required would only work if the last 4 bytes
happened to match between the new and old address, something
that our tests accidentally had. Fix it by copying the full
16 bytes and make the tests also verify the addr and use rand
addresses.
Updates #9511
Signed-off-by: Maisem Ali <maisem@tailscale.com>
It was returning a nil `*iptablesRunner` instead of a
nil `NetfilterRunner` interface which would then fail
checks later.
Fixes#13012
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit increases gVisor's TCP max send (4->6MiB) and receive
(4->8MiB) buffer sizes on all platforms except iOS. These values are
biased towards higher throughput on high bandwidth-delay product paths.
The iperf3 results below demonstrate the effect of this commit between
two Linux computers with i5-12400 CPUs. 100ms of RTT latency is
introduced via Linux's traffic control network emulator queue
discipline.
The first set of results are from commit f0230ce prior to TCP buffer
resizing.
gVisor write direction:
Test Complete. Summary Results:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 180 MBytes 151 Mbits/sec 0 sender
[ 5] 0.00-10.10 sec 179 MBytes 149 Mbits/sec receiver
gVisor read direction:
Test Complete. Summary Results:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.10 sec 337 MBytes 280 Mbits/sec 20 sender
[ 5] 0.00-10.00 sec 323 MBytes 271 Mbits/sec receiver
The second set of results are from this commit with increased TCP
buffer sizes.
gVisor write direction:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 297 MBytes 249 Mbits/sec 0 sender
[ 5] 0.00-10.10 sec 297 MBytes 247 Mbits/sec receiver
gVisor read direction:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.10 sec 501 MBytes 416 Mbits/sec 17 sender
[ 5] 0.00-10.00 sec 485 MBytes 407 Mbits/sec receiver
Updates #9707
Updates tailscale/corp#22119
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Updates tailscale/tailscale#1634
This PR optimizes captive portal detection on Android and iOS by excluding cellular data interfaces (`pdp*` and `rmnet`). As cellular networks do not present captive portals, frequent network switches between Wi-Fi and cellular would otherwise trigger captive detection unnecessarily, causing battery drain.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This commit implements TCP GRO for packets being written to gVisor on
Linux. Windows support will follow later. The wireguard-go dependency is
updated in order to make use of newly exported IP checksum functions.
gVisor is updated in order to make use of newly exported
stack.PacketBuffer GRO logic.
TCP throughput towards gVisor, i.e. TUN write direction, is dramatically
improved as a result of this commit. Benchmarks show substantial
improvement, sometimes as high as 2x. High bandwidth-delay product
paths remain receive window limited, bottlenecked by gVisor's default
TCP receive socket buffer size. This will be addressed in a follow-on
commit.
The iperf3 results below demonstrate the effect of this commit between
two Linux computers with i5-12400 CPUs. There is roughly ~13us of round
trip latency between them.
The first result is from commit 57856fc without TCP GRO.
Starting Test: protocol: TCP, 1 streams, 131072 byte blocks
- - - - - - - - - - - - - - - - - - - - - - - - -
Test Complete. Summary Results:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 4.77 GBytes 4.10 Gbits/sec 20 sender
[ 5] 0.00-10.00 sec 4.77 GBytes 4.10 Gbits/sec receiver
The second result is from this commit with TCP GRO.
Starting Test: protocol: TCP, 1 streams, 131072 byte blocks
- - - - - - - - - - - - - - - - - - - - - - - - -
Test Complete. Summary Results:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 10.6 GBytes 9.14 Gbits/sec 20 sender
[ 5] 0.00-10.00 sec 10.6 GBytes 9.14 Gbits/sec receiver
Updates #6816
Signed-off-by: Jordan Whited <jordan@tailscale.com>
I updated the address parsing stuff to return a specific error for
unspecified hosts passed as empty strings, and look for that
when logging errors. I explicitly did not make parseAddress return a
netip.Addr containing an unspecified address because at this layer,
in the absence of any host, we don't necessarily know the address
family we're dealing with.
For the purposes of this code I think this is fine, at least until
we implement #12588.
Fixes#12979
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
It seems some security software or macOS itself might be MITMing TLS
(for ScreenTime?), so don't warn unless it fails x509 validation
against system roots.
Updates #3198
Change-Id: I6ea381b5bb6385b3d51da4a1468c0d803236b7bf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit implements TCP GSO for packets being read from gVisor on
Linux. Windows support will follow later. The wireguard-go dependency is
updated in order to make use of newly exported GSO logic from its tun
package.
A new gVisor stack.LinkEndpoint implementation has been established
(linkEndpoint) that is loosely modeled after its predecessor
(channel.Endpoint). This new implementation supports GSO of monster TCP
segments up to 64K in size, whereas channel.Endpoint only supports up to
32K. linkEndpoint will also be required for GRO, which will be
implemented in a follow-on commit.
TCP throughput from gVisor, i.e. TUN read direction, is dramatically
improved as a result of this commit. Benchmarks show substantial
improvement through a wide range of RTT and loss conditions, sometimes
as high as 5x.
The iperf3 results below demonstrate the effect of this commit between
two Linux computers with i5-12400 CPUs. There is roughly ~13us of round
trip latency between them.
The first result is from commit 57856fc without TCP GSO.
Starting Test: protocol: TCP, 1 streams, 131072 byte blocks
- - - - - - - - - - - - - - - - - - - - - - - - -
Test Complete. Summary Results:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 2.51 GBytes 2.15 Gbits/sec 154 sender
[ 5] 0.00-10.00 sec 2.49 GBytes 2.14 Gbits/sec receiver
The second result is from this commit with TCP GSO.
Starting Test: protocol: TCP, 1 streams, 131072 byte blocks
- - - - - - - - - - - - - - - - - - - - - - - - -
Test Complete. Summary Results:
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 12.6 GBytes 10.8 Gbits/sec 6 sender
[ 5] 0.00-10.00 sec 12.6 GBytes 10.8 Gbits/sec receiver
Updates #6816
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Fixestailscale/tailscale#12973
Updates tailscale/tailscale#1634
There was a logic issue in the captive detection code we shipped in https://github.com/tailscale/tailscale/pull/12707.
Assume a captive portal has been detected, and the user notified. Upon switching to another Wi-Fi that does *not* have a captive portal, we were issuing a signal to interrupt any pending captive detection attempt. However, we were not also setting the `captive-portal-detected` warnable to healthy. The result was that any "captive portal detected" alert would not be cleared from the UI.
Also fixes a broken log statement value.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
fixes tailscale#12968
The dns manager cleanup func was getting passed a nil
health tracker, which will panic. Fixed to pass it
the system health tracker.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
It is no longer correct to state that we don't support running Tailscale in containers or on Kubernetes.
Updates tailscale/tailscale#12842
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Add a warning that the Dockerfile in the OSS repo is not the
currently used mechanism to build the images we publish - for folks
who want to contribute to image build scripts or otherwise need to
understand the image build process that we use.
Updates#cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
All wasi* are GOARCH wasm, so check that instead.
Updates #12732
Change-Id: Id3cc346295c1641bcf80a6c5eb1ad65488509656
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
updates tailscale/corp#21823
Misconfigured, broken, or blocked DNS will often present as
"internet is broken'" to the end user. This plumbs the health tracker
into the dns manager and forwarder and adds a health warning
with a 5 second delay that is raised on failures in the forwarder and
lowered on successes.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This picks up https://github.com/tailscale/xnet/pull/1 so that
clients can move files even when holding only a lock for the source
file.
Updates #12941
Signed-off-by: Percy Wegmann <percy@tailscale.com>
cmd/k8s-operator,k8s-operator/sessionrecording,sessionrecording,ssh/tailssh: refactor session recording functionality
Refactor SSH session recording functionality (mostly the bits related to
Kubernetes API server proxy 'kubectl exec' session recording):
- move the session recording bits used by both Tailscale SSH
and the Kubernetes API server proxy into a shared sessionrecording package,
to avoid having the operator to import ssh/tailssh
- move the Kubernetes API server proxy session recording functionality
into a k8s-operator/sessionrecording package, add some abstractions
in preparation for adding support for a second streaming protocol (WebSockets)
Updates tailscale/corp#19821
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Allows the use of tsweb.LogHandler exclusively for callbacks describing the
handler HTTP requests.
Fixes#12837
Signed-off-by: Paul Scott <paul@tailscale.com>
Re-instates the functionality that generates CRD API docs, but using
a different library as the one we were using earlier seemed to have
some issues with its Git history.
Also regenerates the docs (make kube-generate-all).
Updates tailscale/tailscale#12859
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Remove the restriction that getent is skipped on non-Linux unixes.
Improve validation of the parsed output from getent, in case unknown
systems return unusable information.
Fixes#12730.
Signed-off-by: Ross Williams <ross@ross-williams.net>
Updates tailscale/corp#21949
As discussed with @raggi, this PR updates the static DERPMap embedded in the client to reflect the availability of HTTP on the DERP servers run by Tailscale.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Updates tailscale/tailscale#1634
This PR introduces a new `captive-portal-detected` Warnable which is set to an unhealthy state whenever a captive portal is detected on the local network, preventing Tailscale from connecting.
ipn/ipnlocal: fix captive portal loop shutdown
Change-Id: I7cafdbce68463a16260091bcec1741501a070c95
net/captivedetection: fix mutex misuse
ipn/ipnlocal: ensure that we don't fail to start the timer
Change-Id: I3e43fb19264d793e8707c5031c0898e48e3e7465
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
wgengine/magicsock,ipn: allow setting static node endpoints via tailscaled config file.
Adds a new StaticEndpoints field to tailscaled config
that can be used to statically configure the endpoints
that the node advertizes. This field will replace
TS_DEBUG_PRETENDPOINTS env var that can be used to achieve the same.
Additionally adds some functionality that ensures that endpoints
are updated when configfile is reloaded.
Also, refactor configuring/reconfiguring components to use the
same functionality when configfile is parsed the first time or
subsequent times (after reload). Previously a configfile reload
did not result in resetting of prefs. Now it does- but does not yet
tell the relevant components to consume the new prefs. This is to
be done in a follow-up.
Updates tailscale/tailscale#12578
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
It is sometimes necessary to change a global lazy.SyncValue for the duration of a test. This PR adds a (*SyncValue[T]).SetForTest method to facilitate that.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
The standard library includes these for strings and byte slices,
but it lacks similar functions for generic slices of comparable types.
Although they are not as commonly used, these functions are useful
in scenarios such as working with field index sequences (i.e., []int)
via reflection.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This adds support for container-like types such as Container[T] that
don't explicitly specify a view type for T. Instead, a package implementing
a container type should also implement and export a ContainerView[T, V] type
and a ContainerViewOf(*Container[T]) ContainerView[T, V] function, which
returns a view for the specified container, inferring the element view type V
from the element type T.
Updates #12736
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Some users run "tailscale cert" in a cron job to renew their
certificates on disk. The time until the next cron job run may be long
enough for the old cert to expire with our default heristics.
Add a `--min-validity` flag which ensures that the returned cert is
valid for at least the provided duration (unless it's longer than the
cert lifetime set by Let's Encrypt).
Updates #8725
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Remove fybrik.io/crdoc dependency as it is causing issues for folks attempting
to vendor tailscale using GOPROXY=direct.
This means that the CRD API docs in ./k8s-operator/api.md will no longer
be generated- I am going to look at replacing it with another tool
in a follow-up.
Updates tailscale/tailscale#12859
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Bump node version to latest lts on the 18.x line which is 18.20.4 at the time of writing.
Updates https://github.com/tailscale/corp/issues/21741
Signed-off-by: Mario Minardi <mario@tailscale.com>
Windows requires routes to have a nexthop. Routes created using the interface's local IP address or an unspecified IP address ("0.0.0.0" or "::") as the nexthop are considered on-link routes. Notably, Windows treats on-link subnet routes differently, reserving the last IP in the range as the broadcast IP and therefore prohibiting TCP connections to it, resulting in WSA error 10049: "The requested address is not valid in its context. This does not happen with single-host routes, such as routes to Tailscale IP addresses, but becomes a problem with advertised subnets when all IPs in the range should be reachable.
Before Windows 8, only routes created with an unspecified IP address were considered on-link, so our previous approach of using the interface's own IP as the nexthop likely worked on Windows 7.
This PR updates configureInterface to use the TailscaleServiceIP (100.100.100.100) and its IPv6 counterpart as the nexthop for subnet routes.
Fixestailscale/support-escalations#57
Signed-off-by: Nick Khyl <nickk@tailscale.com>
With this change, the error handling and request logging are all done in defers
after calling inner.ServeHTTP. This ensures that any recovered values which we
want to re-panic with retain a useful stacktrace. However, we now only
re-panic from errorHandler when there's no outside logHandler. Which if you're
using StdHandler there always is. We prefer this to ensure that we are able to
write a 500 Internal Server Error to the client. If a panic hits http.Server
then the response is not sent back.
Updates #12784
Signed-off-by: Paul Scott <paul@tailscale.com>
... and then do approximately nothing with that information, other
than a big TODO. This is mostly me relearning this code and leaving
breadcrumbs for others in the future.
Updates #12724
Signed-off-by: Brad Fitzpatrick <brad@danga.com>
StdHandler/retHandler would previously emit one log line for each request.
If there were multiple StdHandler in the chain, there would be one log line
per instance of retHandler.
With this change, only the outermost StdHandler/logHandler actually logs the
request or invokes OnStart or OnCompletion callbacks. The error-rendering part
of retHandler lives on in errorHandler, and errorHandler passes those errors up
the stack to logHandler through a callback that logHandler places in the
request.Context().
Updates tailscale/corp#19999
Signed-off-by: Paul Scott <paul@tailscale.com>
To match the format of exit node suggestions and ensure that the result
is not ambiguous, relax exit node CLI selection to permit using a FQDN
including the trailing dot.
Updates #12618
Change-Id: I04b9b36d2743154aa42f2789149b2733f8555d3f
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
Fixestailscale/tailscale#12794
We were printing some leftover debug logs within a callback function that would be executed after the test completion, causing the test to fail. This change drops the log calls to address the issue.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
If we get an non-disco presumably-wireguard-encrypted UDP packet from
an IP:port we don't recognize, rather than drop the packet, give it to
WireGuard anyway and let WireGuard try to figure out who it's from and
tell us.
This uses the new hook added in https://github.com/tailscale/wireguard-go/pull/27
Updates tailscale/corp#20732
Change-Id: I5c61a40143810592f9efac6c12808a87f924ecf2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Some operations cannot be implemented with the prior API:
* Iterating over the map and deleting keys
* Iterating over the map and replacing items
* Calling APIs that expect a native Go map
Add a Map.WithLock method that acquires a write-lock on the map
and then calls a user-provided closure with the underlying Go map.
This allows users to interact with the Map as a regular Go map,
but with the gaurantees that it is concurrent safe.
Updates tailscale/corp#9115
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This adds support for generic types and interfaces to our cloner and viewer codegens.
It updates these packages to determine whether to make shallow or deep copies based
on the type parameter constraints. Additionally, if a template parameter or an interface
type has View() and Clone() methods, we'll use them for getters and the cloner of the
owning structure.
Updates #12736
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Updates tailscale/tailscale#4136
To reduce the likelihood of presenting spurious warnings, add the ability to delay the visibility of certain Warnables, based on a TimeToVisible time.Duration field on each Warnable. The default is zero, meaning that a Warnable is immediately visible to the user when it enters an unhealthy state.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This commit truncates any additional information (mainly hostnames) that's passed to controlD via DOH URL in DoHIPsOfBase.
This change is to make sure only resolverID is passed to controlDv6Gen but not the additional information.
Updates: #7946
Signed-off-by: KevinLiang10 <37811973+KevinLiang10@users.noreply.github.com>
If an optional `hwaddrs` URL parameter is present, add network interface
hardware addresses to the posture identity response.
Just like with serial numbers, this requires client opt-in via MDM or
`tailscale set --posture-checking=true`
(https://tailscale.com/kb/1326/device-identity)
Updates tailscale/corp#21371
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Load Balancers often have more than one ingress IP, so allowing us to
add multiple means we can offer multiple options.
Updates #12578
Change-Id: I4aa49a698d457627d2f7011796d665c67d4c7952
Signed-off-by: Lee Briggs <lee@leebriggs.co.uk>
This adds a package with GP-related functions and types to be used in the future PRs.
It also updates nrptRuleDatabase to use the new package instead of its own gpNotificationWatcher implementation.
Updates #12687
Signed-off-by: Nick Khyl <nickk@tailscale.com>
We added a workaround for --wait, but didn't confirm the other flags,
which were added in systemd 235 and 236. Check systemd version for
deciding when to set all 3 flags.
Fixes#12136
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
While `clientupdate.Updater` won't be able to apply updates on macsys,
we use `clientupdate.CanAutoUpdate` to gate the EditPrefs endpoint in
localAPI. We should allow the GUI client to set AutoUpdate.Apply on
macsys for it to properly get reported to the control plane. This also
allows the tailnet-wide default for auto-updates to propagate to macsys
clients.
Updates https://github.com/tailscale/corp/issues/21339
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
cmd/k8s-operator,ssh/tailssh,tsnet: optionally record kubectl exec sessions
The Kubernetes operator's API server proxy, when it receives a request
for 'kubectl exec' session now reads 'RecorderAddrs', 'EnforceRecorder'
fields from tailcfg.KubernetesCapRule.
If 'RecorderAddrs' is set to one or more addresses (of a tsrecorder instance(s)),
it attempts to connect to those and sends the session contents
to the recorder before forwarding the request to the kube API
server. If connection cannot be established or fails midway,
it is only allowed if 'EnforceRecorder' is not true (fail open).
Updates tailscale/corp#19821
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Maisem Ali <maisem@tailscale.com>
For testing. Lee wants to play with 'AWS Global Accelerator Custom
Routing with Amazon Elastic Kubernetes Service'. If this works well
enough, we can promote it.
Updates #12578
Change-Id: I5018347ed46c15c9709910717d27305d0aedf8f4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The DERP Return Path Optimization (DRPO) is over four years old (and
on by default for over two) and we haven't had problems, so time to
remove the emergency shutoff code (controlknob) which we've never
used. The controlknobs are only meant for new features, to mitigate
risk. But we don't want to keep them forever, as they kinda pollute
the code.
Updates #150
Change-Id: If021bc8fd1b51006d8bddd1ffab639bb1abb0ad1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And fix up a bogus comment and flesh out some other comments.
Updates #cleanup
Change-Id: Ia60a1c04b0f5e44e8d9587914af819df8e8f442a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
cmd/containerboot,cmd/k8s-operator: enable IPv6 for fqdn egress proxies
Don't skip installing egress forwarding rules for IPv6 (as long as the host
supports IPv6), and set headless services `ipFamilyPolicy` to
`PreferDualStack` to optionally enable both IP families when possible. Note
that even with `PreferDualStack` set, testing a dual-stack GKE cluster with
the default DNS setup of kube-dns did not correctly set both A and
AAAA records for the headless service, and instead only did so when
switching the cluster DNS to Cloud DNS. For both IPv4 and IPv6 to work
simultaneously in a dual-stack cluster, we require headless services to
return both A and AAAA records.
If the host doesn't support IPv6 but the FQDN specified only has IPv6
addresses available, containerboot will exit with error code 1 and an
error message because there is no viable egress route.
Fixes#12215
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Updates tailscale/tailscale#4136
We should make sure to send the value of ImpactsConnectivity over to the clients using LocalAPI as they need it to display alerts in the GUI properly.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This change expands the `exit-node list -filter` command to display all
location based exit nodes for the filtered country. This allows users
to switch to alternative servers when our recommended exit node is not
working as intended.
This change also makes the country filter matching case insensitive,
e.g. both USA and usa will work.
Updates #12698
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Updates tailscale/tailscale#4136
High severity health warning = a system notification will appear, which can be quite disruptive to the user and cause unnecessary concern in the event of a temporary network issue.
Per design decision (@sonovawolf), the severity of all warnings but "network is down" should be tuned down to medium/low. ImpactsConnectivity should be set, to change the icon to an exclamation mark in some cases, but without a notification bubble.
I also tweaked the messaging for update-available, to reflect how each platform gets updates in different ways.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Updates tailscale/corp#20677
The recover function wasn't getting set in the benchmark
tests. Default changed to an empty func.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
Fix regression from #8108 (Mar 2023). Since that change, gocross has
always been rebuilt on each run of ./tool/go (gocross-wrapper.sh),
adding ~100ms. (Well, not totally rebuilt; cmd/go's caching still
ends up working fine.)
The problem was $gocross_path was just "gocross", which isn't in my
path (and "." isn't in my $PATH, as it shouldn't be), so this line was
always evaluating to the empty string:
gotver="$($gocross_path gocross-version 2>/dev/null || echo '')"
The ./gocross is fine because of the earlier `cd "$repo_root"`
Updates tailscale/corp#21262
Updates tailscale/corp#21263
Change-Id: I80d25446097a3bb3423490c164352f0b569add5f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
go get github.com/tailscale/mkctr@main
Pulls in changes to support a local target that only pushes
a single-platform image to the machine's local image store.
Fixestailscale/mkctr#18
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
BPF links require that the owning FD remains open, this FD is embedded
into the RawLink returned by the attach function and must live for the
duration of the server.
Updates ENG-4274
Signed-off-by: James Tucker <james@tailscale.com>
Detection of duplicate Network Lock signature chains added in
01847e0123 failed to account for chains
originating with a SigCredential signature, which is used for wrapped
auth keys. This results in erroneous removal of signatures that
originate from the same re-usable auth key.
This change ensures that multiple nodes created by the same re-usable
auth key are not getting filtered out by the network lock.
Updates tailscale/corp#19764
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This change moves handling of wrapped auth keys to the `tka` package and
adds a test covering auth key originating signatures (SigCredential) in
netmap.
Updates tailscale/corp#19764
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
When auto-udpates are enabled, we don't need to nag users to update
after a new release, before we release auto-updates.
Updates https://github.com/tailscale/corp/issues/20081
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This is not valid in many situations, specifically when running a local astro site that listens on localhost, but ignores 127.0.0.1
Fixes: https://github.com/tailscale/tailscale/issues/12201
Signed-off-by: Josh McKinney <joshka@users.noreply.github.com>
In hopes it'll be found more.
Updates tailscale/corp#20844
Change-Id: Ic92ee9908f45b88f8770de285f838333f9467465
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
A few other minor language updates.
Updates tailscale/corp#20844
Change-Id: Idba85941baa0e2714688cc8a4ec3e242e7d1a362
Signed-off-by: James Tucker <james@tailscale.com>
And some misc doc tweaks for idiomatic Go style.
Updates #cleanup
Change-Id: I3ca45f78aaca037f433538b847fd6a9571a2d918
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We cannot directly pass a flat domain name into NetUserGetInfo; we must
resolve the address of a domain controller first.
This PR implements the appropriate resolution mechanisms to do that, and
also exposes a couple of new utility APIs for future needs.
Fixes#12627
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This turns the checklocks workflow into a real check, and adds
annotations to a few basic packages as a starting point.
Updates #12625
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I2b0185bae05a843b5257980fc6bde732b1bdd93f
The exit node suggestion CLI command was written with the assumption
that it's possible to provide a stableid on the command line, but this
is incorrect. Instead, it will now emit the name of the exit node.
Fixes#12618
Change-Id: Id7277f395b5fca090a99b0d13bfee7b215bc9802
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
The context can get canceled during backoff, and binding after that
makes the listener impossible to close afterwards.
Fixes#12620.
Signed-off-by: Naman Sood <mail@nsood.in>
To complement the existing `onCompletion` callback, which is called
after request handler.
Updates tailscale/corp#17075
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
We can observe a data race in tests when logging after a test is
finished. `b.onHealthChange` is called in a goroutine after being
registered with `health.Tracker.RegisterWatcher`, which calls callbacks
in `setUnhealthyLocked` in a new goroutine.
See: https://github.com/tailscale/tailscale/actions/runs/9672919302/job/26686038740
Updates #12054
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ibf22cc994965d88a9e7236544878d5373f91229e
This PR ties together pseudoconsoles, user profiles, s4u logons, and
process creation into what is (hopefully) a simple API for various
Tailscale services to obtain Windows access tokens without requiring
knowledge of any Windows passwords. It works both for domain-joined
machines (Kerberos) and non-domain-joined machines. The former case
is fairly straightforward as it is fully documented. OTOH, the latter
case is not documented, though it is fully defined in the C headers in
the Windows SDK. The documentation blanks were filled in by reading
the source code of Microsoft's Win32 port of OpenSSH.
We need to do a bit of acrobatics to make conpty work correctly while
creating a child process with an s4u token; see the doc comments above
startProcessInternal for details.
Updates #12383
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Previously, if we had a umask set (e.g. 0027) that prevented creating a
world-readable file, /etc/resolv.conf would be created without the o+r
bit and thus other users may be unable to resolve DNS.
Since a umask only applies to file creation, chmod the file after
creation and before renaming it to ensure that it has the appropriate
permissions.
Updates #12609
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I2a05d64f4f3a8ee8683a70be17a7da0e70933137
The logic we added in #11378 would prevent selecting a home DERP if we
have no control connection.
Updates tailscale/corp#18095
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I44bb6ac4393989444e4961b8cfa27dc149a33c6e
Fixestailscale/corp#20677
Replaces the original attempt to rectify this (by injecting a netMon
event) which was both heavy handed, and missed cases where the
netMon event was "minor".
On apple platforms, the fetching the interface's nameservers can
and does return an empty list in certain situations. Apple's API
in particular is very limiting here. The header hints at notifications
for dns changes which would let us react ahead of time, but it's all
private APIs.
To avoid remaining in the state where we end up with no
nameservers but we absolutely need them, we'll react
to a lack of upstream nameservers by attempting to re-query
the OS.
We'll rate limit this to space out the attempts. It seems relatively
harmless to attempt a reconfig every 5 seconds (triggered
by an incoming query) if the network is in this broken state.
Missing nameservers might possibly be a persistent condition
(vs a transient error), but that would also imply that something
out of our control is badly misconfigured.
Tested by randomly returning [] for the nameservers. When switching
between Wifi networks, or cell->wifi, this will randomly trigger
the bug, and we appear to reliably heal the DNS state.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
So non-local users (e.g. Kerberos on FreeIPA) on Linux can be looked
up. Our default binaries are built with pure Go os/user which only
supports the classic /etc/passwd and not any libc-hooked lookups.
Updates #12601
Change-Id: I9592db89e6ca58bf972f2dcee7a35fbf44608a4f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
stunstamp now sends data to Prometheus via remote write, and Prometheus
can serve the same data. Retaining and cleaning up old data in sqlite
leads to long probing pauses, and it's not worth investing more effort
to optimize the schema and/or concurrency model.
Updates tailscale/corp#20344
Signed-off-by: Jordan Whited <jordan@tailscale.com>
PeerPresentFlags was added in 5ffb2668ef but wasn't plumbed through to
the RunConnectionLoop. Rather than add yet another parameter (as
IP:port was added earlier), pass in the raw PeerPresentMessage and
PeerGoneMessage struct values, which are the same things, plus two
fields: PeerGoneReasonType for gone and the PeerPresentFlags from
5ffb2668ef.
Updates tailscale/corp#17816
Change-Id: Ib19d9f95353651ada90656071fc3656cf58b7987
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When the store-appc-routes flag is on for a tailnet we are writing the
routes more often than seems necessary. Investigation reveals that we
are doing so ~every time we observe a dns response, even if this causes
us not to advertise any new routes. So when we have no new routes,
instead do not advertise routes.
Fixes#12593
Signed-off-by: Fran Bull <fran@tailscale.com>
I couldn't convince myself the old way was safe and couldn't lose
writes.
And it seemed too complicated.
Updates tailscale/corp#21104
Change-Id: I17ba7c7d6fd83458a311ac671146a1f6a458a5c1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
sendMeshUpdates tries to write as much as possible without blocking,
being careful to check the bufio.Writer.Available size before writes.
Except that regressed in 6c791f7d60 which made those messages larger, which
meants we were doing network I/O with the Server mutex held.
Updates tailscale/corp#13945
Change-Id: Ic327071d2e37de262931b9b390cae32084811919
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds the ability to "peek" at the value of a SyncValue, so that
it's possible to observe a value without computing this.
Updates tailscale/corp#17122
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I06f88c22a1f7ffcbc7ff82946335356bb0ef4622
This is implemented via GetBestInterfaceEx. Should we encounter errors
or fail to resolve a valid, non-Tailscale interface, we fall back to
returning the index for the default interface instead.
Fixes#12551
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Timeouts could already be identified as NaN values on
stunstamp_derp_stun_rtt_ns, but we can't use NaN effectively with
promql to visualize them. So, this commit adds a timeouts metric that
we can use with rate/delta/etc promql functions.
Updates tailscale/corp#20689
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Changes "Accept" TCP logs to display in verbose logs only,
and removes lines from default logging behavior.
Updates #12158
Signed-off-by: Keli Velazquez <keli@tailscale.com>
This allows the SSH_AUTH_SOCK environment variable to work inside of
su and agent forwarding to succeed.
Fixes#12467
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This actually performs a Noise request in the 'debug ts2021' command,
instead of just exiting once we've dialed a connection. This can help
debug certain forms of captive portals and deep packet inspection that
will allow a connection, but will RST the connection when trying to send
data on the post-upgraded TCP connection.
Updates #1634
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I1e46ca9c9a0751c55f16373a6a76cdc24fec1f18
So that it can be later used in the 'tailscale debug ts2021' function in
the CLI, to aid in debugging captive portals/WAFs/etc.
Updates #1634
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Iec9423f5e7570f2c2c8218d27fc0902137e73909
Fix regression from bd93c3067e where I didn't notice the
32-bit test failure was real and not its usual slowness-related
regression. Yay failure blindness.
Updates #12526
Change-Id: I00e33bba697e2cdb61a0d76a71b62406f6c2eeb9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Looks like a DERPmap might not be available when we try to get the
name associated with a region ID, and that was causing an intermittent
panic in CI.
Fixes#12534
Change-Id: I4ace53681bf004df46c728cff830b27339254243
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
It was hex-ifying the String() form of key.NodePublic, which was already hex.
I noticed in some logs:
"client 6e6f64656b65793a353537353..."
And thought that 6x6x6x6x looked strange. It's "nodekey:" in hex.
Updates tailscale/corp#20844
Change-Id: Ib9f2d63b37e324420b86efaa680668a9b807e465
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The control plane hasn't sent it to clients in ages.
Updates tailscale/corp#20965
Change-Id: I1d71a4b6dd3f75010a05c544ee39827837c30772
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I meant to do this in the earlier change and had a git fail.
To atone, add a test too while I'm here.
Updates #12486
Updates #12507
Change-Id: I4943b454a2530cb5047636f37136aa2898d2ffc7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Fixestailscale/corp#20971
We added some Warnables for DERP failure situations, but their Text currently spits out the DERP region ID ("10") in the UI, which is super ugly. It would be better to provide the RegionName of the DERP region that is failing. We can do so by storing a reference to the last-known DERP map in the health package whenever we fetch one, and using it when generating the notification text.
This way, the following message...
> Tailscale could not connect to the relay server '10'. The server might be temporarily unavailable, or your Internet connection might be down.
becomes:
> Tailscale could not connect to the 'Seattle' relay server. The server might be temporarily unavailable, or your Internet connection might be down.
which is a lot more user-friendly.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Updates tailscale/corp#20969
Right now, when netcheck starts, it asks tailscaled for a copy of the DERPMap. If it doesn't have one, it makes a HTTPS request to controlplane.tailscale.com to fetch one.
This will always fail if you're on a network with a captive portal actively blocking HTTPS traffic. The code appears to hang entirely because the http.Client doesn't have a Timeout set. It just sits there waiting until the request succeeds or fails.
This adds a timeout of 10 seconds, and logs more details about the status of the HTTPS request.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This is useful during maintenance as a method for shedding home client
load.
Updates tailscale/corp#20689
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Updates #4136
Small PR to expose the health Warnables dependencies to the GUI via LocalAPI, so that we can only show warnings for root cause issues, and filter out unnecessary messages before user presentation.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
I noticed we were allocating these every time when they could just
share the same memory. Rather than document ownership, just lock it
down with a view.
I was considering doing all of the fields but decided to just do this
one first as test to see how infectious it became. Conclusion: not
very.
Updates #cleanup (while working towards tailscale/corp#20514)
Change-Id: I8ce08519de0c9a53f20292adfbecd970fe362de0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adds a new TailscaleProxyReady condition type for use in corev1.Service
conditions.
Also switch our CRDs to use metav1.Condition instead of
ConnectorCondition. The Go structs are seralized identically, but it
updates some descriptions and validation rules. Update k8s
controller-tools and controller-runtime deps to fix the documentation
generation for metav1.Condition so that it excludes comments and
TODOs.
Stop expecting the fake client to populate TypeMeta in tests. See
kubernetes-sigs/controller-runtime#2633 for details of the change.
Finally, make some minor improvements to validation for service hostnames.
Fixes#12216
Co-authored-by: Irbe Krumina <irbe@tailscale.com>
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
Previously, we were registering TCP and UDP connections in the same map,
which could result in erroneously removing a mapping if one of the two
connections completes while the other one is still active.
Add a "proto string" argument to these functions to avoid this.
Additionally, take the "proto" argument in LocalAPI, and plumb that
through from the CLI and add a new LocalClient method.
Updates tailscale/corp#20600
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I35d5efaefdfbf4721e315b8ca123f0c8af9125fb
We need to expand our enviornment information to include info about
the Windows store. Thinking about future plans, it would be nice
to include both the packaging mechanism and the distribution mechanism.
In this PR we change packageTypeWindows to check a new registry value
named MSIDist, and concatenate that value to "msi/" when present.
We also remove vestigial NSIS detection.
Updates https://github.com/tailscale/corp/issues/2790
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
The Add method derives a new ID by adding a signed integer
to the ID, treating it as an unsigned 256-bit big-endian integer.
We also add Less and Compare methods to PrivateID to provide
feature parity with existing methods on PublicID.
Updates tailscale/corp#11038
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
validate_udp_checksum was previously indeterminate (not zero) at
declaration, and IPv4 zero value UDP checksum packets were being passed
to the kernel.
Updates tailscale/corp#20689
Signed-off-by: Jordan Whited <jordan@tailscale.com>
* cmd/containerboot: store device ID before setting up proxy routes.
For containerboot instances whose state needs to be stored
in a Kubernetes Secret, we additonally store the device's
ID, FQDN and IPs.
This is used, between other, by the Kubernetes operator,
who uses the ID to delete the device when resources need
cleaning up and writes the FQDN and IPs on various kube
resource statuses for visibility.
This change shifts storing device ID earlier in the proxy setup flow,
to ensure that if proxy routing setup fails,
the device can still be deleted.
Updates tailscale/tailscale#12146
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* code review feedback
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
---------
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
We do not support specific version updates or track switching on macOS.
Do not populate the flag to avoid confusion.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Previously, we would only compare the current version to resolved latest
version for track. When running `tailscale update --track=stable` from
an unstable build, it would almost always fail because the stable
version is "older". But we should support explicitly switching tracks
like that.
Fixes#12347
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
For pprof cosmetic/confusion reasons more than performance, but it
might have tiny speed benefit.
Updates #12486
Change-Id: I40e03714f3afa3a7e7f5e1fa99b81c7e889b91b6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So profiles show more useful names than just func1, func2, func3, etc.
There will still be func1 on them all, but the symbol before will say
what the lookup type is.
Updates #12486
Change-Id: I910b024a7861394eb83d07f5a899eae338cb1f22
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This moves NewContainsIPFunc from tsaddr to new ipset package.
And wgengine/filter types gets split into wgengine/filter/filtertype,
so netmap (and thus the CLI, etc) doesn't need to bring in ipset,
bart, etc.
Then add a test making sure the CLI deps don't regress.
Updates #1278
Change-Id: Ia246d6d9502bbefbdeacc4aef1bed9c8b24f54d5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I noticed the not-local-v6 numbers were nowhere near the v4 numbers
(they should be identical) and then saw this. It meant the
Addr().Next() wasn't picking an IP that was no longer local, as
assumed.
Updates #12486
Change-Id: I18dfb641f00c74c6252666bc41bd2248df15fadd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
NewContainsIPFunc was previously documented as performing poorly if
there were many netip.Prefixes to search over. As such, we never it used it
in such cases.
This updates it to use bart at a certain threshold (over 6 prefixes,
currently), at which point the bart lookup overhead pays off.
This is currently kinda useless because we're not using it. But now we
can and get wins elsewhere. And we can remove the caveat in the docs.
goos: darwin
goarch: arm64
pkg: tailscale.com/net/tsaddr
│ before │ after │
│ sec/op │ sec/op vs base │
NewContainsIPFunc/empty-8 2.215n ± 11% 2.239n ± 1% +1.08% (p=0.022 n=10)
NewContainsIPFunc/cidr-list-1-8 17.44n ± 0% 17.59n ± 6% +0.89% (p=0.000 n=10)
NewContainsIPFunc/cidr-list-2-8 27.85n ± 0% 28.13n ± 1% +1.01% (p=0.000 n=10)
NewContainsIPFunc/cidr-list-3-8 36.05n ± 0% 36.56n ± 13% +1.41% (p=0.000 n=10)
NewContainsIPFunc/cidr-list-4-8 43.73n ± 0% 44.38n ± 1% +1.50% (p=0.000 n=10)
NewContainsIPFunc/cidr-list-5-8 51.61n ± 2% 51.75n ± 0% ~ (p=0.101 n=10)
NewContainsIPFunc/cidr-list-10-8 95.65n ± 0% 68.92n ± 0% -27.94% (p=0.000 n=10)
NewContainsIPFunc/one-ip-8 4.466n ± 0% 4.469n ± 1% ~ (p=0.491 n=10)
NewContainsIPFunc/two-ip-8 8.002n ± 1% 7.997n ± 4% ~ (p=0.697 n=10)
NewContainsIPFunc/three-ip-8 27.98n ± 1% 27.75n ± 0% -0.82% (p=0.012 n=10)
geomean 19.60n 19.07n -2.71%
Updates #12486
Change-Id: I2e2320cc4384f875f41721374da536bab995c1ce
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This abstraction provides a nicer way to work with
maps of slices without having to write out three long type
params.
This also allows it to provide an AsMap implementation which
copies the map and the slices at least.
Updates tailscale/corp#20910
Signed-off-by: Maisem Ali <maisem@tailscale.com>
NewContainsIPFunc returns a contains matcher optimized for its
input. Use that instead of what this did before, always doing a test
over each of a list of netip.Prefixes.
goos: darwin
goarch: arm64
pkg: tailscale.com/wgengine/filter
│ before │ after │
│ sec/op │ sec/op vs base │
FilterMatch/file1-8 32.60n ± 1% 18.87n ± 1% -42.12% (p=0.000 n=10)
Updates #12486
Change-Id: I8f902bc064effb431e5b46751115942104ff6531
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Without this rule, Windows 8.1 and newer devices issue parallel DNS requests to DNS servers
associated with all network adapters, even when "Override local DNS" is enabled and/or
a Mullvad exit node is being used, resulting in DNS leaks.
This also adds "disable-local-dns-override-via-nrpt" nodeAttr that can be used to disable
the new behavior if needed.
Fixestailscale/corp#20718
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Updates tailscale/tailscale#4136
This PR is the first round of work to move from encoding health warnings as strings and use structured data instead. The current health package revolves around the idea of Subsystems. Each subsystem can have (or not have) a Go error associated with it. The overall health of the backend is given by the concatenation of all these errors.
This PR polishes the concept of Warnable introduced by @bradfitz a few weeks ago. Each Warnable is a component of the backend (for instance, things like 'dns' or 'magicsock' are Warnables). Each Warnable has a unique identifying code. A Warnable is an entity we can warn the user about, by setting (or unsetting) a WarningState for it. Warnables have:
- an identifying Code, so that the GUI can track them as their WarningStates come and go
- a Title, which the GUIs can use to tell the user what component of the backend is broken
- a Text, which is a function that is called with a set of Args to generate a more detailed error message to explain the unhappy state
Additionally, this PR also begins to send Warnables and their WarningStates through LocalAPI to the clients, using ipn.Notify messages. An ipn.Notify is only issued when a warning is added or removed from the Tracker.
In a next PR, we'll get rid of subsystems entirely, and we'll start using structured warnings for all errors affecting the backend functionality.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Fixestailscale/corp#18366.
This PR provides serial number collection on iOS, by allowing system administrators to pass a `DeviceSerialNumber` MDM key which can be read by the `posture` package in Go.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
S4U logons do not automatically load the associated user profile. In this
PR we add UserProfile to handle that part. Windows docs indicate that
we should try to resolve a remote profile path when present, so we attempt
to do so when the local computer is joined to a domain.
Updates #12383
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
We do not intend to use this value for feature support communication in
the future, and have applied changes elsewhere that now fix the expected
value.
Updates tailscale/corp#19391
Updates tailscale/corp#20398
Signed-off-by: James Tucker <james@tailscale.com>
This commit introduces a userspace program for managing an experimental
eBPF XDP STUN server program. derp/xdp contains the eBPF pseudo-C along
with a Go pkg for loading it and exporting its metrics.
cmd/xdpderper is a package main user of derp/xdp.
Updates tailscale/corp#20689
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This refactors the logic for determining whether a packet should be sent
to the host or not into a function, and then adds tests for it.
Updates #11304
Updates #12448
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ief9afa98eaffae00e21ceb7db073c61b170355e5
Fix a bug where, for a subnet router that advertizes
4via6 route, all packets with a source IP matching
the 4via6 address were being sent to the host itself.
Instead, only send to host packets whose destination
address is host's local address.
Fixestailscale/tailscale#12448
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Andrew Dunham <andrew@du.nham.ca>
Checking in the incubator as this used to do fails because
the getenforce command is not on the PATH.
Updates #12442
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Fixestailscale/corp#20677
On macOS sleep/wake, we're encountering a condition where reconfigure the network
a little bit too quickly - before apple has set the nameservers for our interface.
This results in a persistent condition where we have no upstream resolver and
fail all forwarded DNS queries.
No upstream nameservers is a legitimate configuration, and we have no (good) way
of determining when Apple is ready - but if we need to forward a query, and we
have no nameservers, then something has gone badly wrong and the network is
very broken.
A simple fix here is to simply inject a netMon event, which will go through the
configuration dance again when we hit the SERVFAIL condition.
Tested by artificially/randomly returning [] for the list of nameservers in the bespoke
ipn-bridge code responsible for getting the nameservers.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
As an alterative to #11935 using #12003.
Updates #11935
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I05f643fe812ceeaec5f266e78e3e529cab3a1ac3
Add an additional RecorderAddrs field to tailscale.com/cap/kubernetes
capability. RecorderAddrs will only be populated by control
with the addresses of any tsrecorder tags set via Recorder.
Updates tailscale/corp#19821
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
When we're starting child processes on Windows that are CLI programs that
don't need to output to a console, we should pass in DETACHED_PROCESS as a
CreationFlag on SysProcAttr. This prevents the OS from even creating a console
for the child (and paying the associated time/space penalty for new conhost
processes). This is more efficient than letting the OS create the console
window and then subsequently trying to hide it, which we were doing at a few
callsites.
Fixes#12270
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
As quad-100 is an authoritative server for 4via6 domains, it should always return responses
with a response code of 0 (indicating no error) when resolving records for these domains.
If there's no resource record of the specified type (e.g. A), it should return a response
with an empty answer section rather than NXDomain. Such a response indicates that there
is at least one RR of a different type (e.g., AAAA), suggesting the Windows stub resolver
to look for it.
Fixestailscale/corp#20767
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This adds a variant for Connect that takes in a context.Context
which allows passing through cancellation etc by the caller.
Updates tailscale/corp#18266
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This is a variant of DoChan that supports context propagation, such that
the context provided to the inner function will only be canceled when
there are no more waiters for a given key. This can be used to
deduplicate expensive and cancelable calls among multiple callers
safely.
Updates #11935
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ibe1fb67442a854babbc6924fd8437b02cc9e7bcf
Add a new TS_EXPERIMENTAL_ENABLE_FORWARDING_OPTIMIZATIONS env var
that can be set for tailscale/tailscale container running as
a subnet router or exit node to enable UDP GRO forwarding
for improved performance.
See https://tailscale.com/kb/1320/performance-best-practices#linux-optimizations-for-subnet-routers-and-exit-nodes
This is currently considered an experimental approach;
the configuration support is partially to allow further experimentation
with containerized environments to evaluate the performance
improvements.
Updates tailscale/tailscale#12295
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Return empty response and NOERROR for AAAA record queries
for DNS names for which we have an A record.
This is to allow for callers that might be first sending an AAAA query and then,
if that does not return a response, follow with an A record query.
Previously we were returning NOTIMPL that caused some callers
to potentially not follow with an A record query or misbehave in different ways.
Also return NXDOMAIN for AAAA record queries for names
that we DO NOT have an A record for to ensure that the callers
do not follow up with an A record query.
Returning an empty response and NOERROR is the behaviour
that RFC 4074 recommends:
https://datatracker.ietf.org/doc/html/rfc4074
Updates tailscale/tailscale#12321
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
AllocateContiguousBuffer is for allocating structs with trailing buffers
containing additional data. It is to be used for various Windows structures
containing pointers to data located immediately after the struct.
SetNTString performs in-place setting of windows.NTString and
windows.NTUnicodeString.
Updates #12383
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This PR is in prep of adding logic to control to be able to parse
tailscale.com/cap/kubernetes grants in control:
- moves the type definition of PeerCapabilityKubernetes cap to a location
shared with control.
- update the Kubernetes cap rule definition with fields for granting
kubectl exec session recording capabilities.
- adds a convenience function to produce tailcfg.RawMessage from an
arbitrary cap rule and a test for it.
An example grant defined via ACLs:
"grants": [{
"src": ["tag:eng"],
"dst": ["tag:k8s-operator"],
"app": {
"tailscale.com/cap/kubernetes": [{
"recorder": ["tag:my-recorder"]
“enforceRecorder”: true
}],
},
}
]
This grant enforces `kubectl exec` sessions from tailnet clients,
matching `tag:eng` via API server proxy matching `tag:k8s-operator`
to be recorded and recording to be sent to a tsrecorder instance,
matching `tag:my-recorder`.
The type needs to be shared with control because we want
control to parse this cap and resolve tags to peer IPs.
Updates tailscale/corp#19821
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Add a new .spec.tailscale.acceptRoutes field to ProxyClass,
that can be optionally set to true for the proxies to
accept routes advertized by other nodes on tailnet (equivalent of
setting --accept-routes to true).
Updates tailscale/tailscale#12322,tailscale/tailscale#10684
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Also removes hardcoded image repo/tag from example DNSConfig resource
as the operator now knows how to default those.
Updates tailscale/tailscale#11019
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Add new fields TailnetIPs and Hostname to Connector Status. These
contain the addresses of the Tailscale node that the operator created
for the Connector to aid debugging.
Fixes#12214
Signed-off-by: Tom Proctor <tomhjp@users.noreply.github.com>
cmd/k8s-operator,k8s-operator,go.{mod,sum}: make individual proxy images/image pull policies configurable
Allow to configure images and image pull policies for individual proxies
via ProxyClass.Spec.StatefulSet.Pod.{TailscaleContainer,TailscaleInitContainer}.Image,
and ProxyClass.Spec.StatefulSet.Pod.{TailscaleContainer,TailscaleInitContainer}.ImagePullPolicy
fields.
Document that we have images in ghcr.io on the relevant Helm chart fields.
Updates tailscale/tailscale#11675
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The last suggested exit node needs to be incorporated in the decision
making process when a new suggestion is requested, but currently it is
not quite right: it'll be used if the suggestion code has an error or a
netmap is unavailable, but it won't be used otherwise.
Instead, this makes the last suggestion into a tiebreaker when making a
random selection between equally-good options. If the last suggestion
does not make it to the final selection pool, then a different
suggestion will be made.
Since LocalBackend.SuggestExitNode is back to being a thin shim that
sets up the parameters to suggestExitNode, it no longer needs a test.
Its test was unable to be comprehensive anyway as the code being tested
contains an uncontrolled random number generator.
Updates tailscale/corp#19681
Change-Id: I94ecc9a0d1b622de3df4ef90523f1d3e67b4bfba
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
We assume most containers are immutable and don't expect tailscale
running in them to auto-update. But there's no reason to prohibit it
outright.
Ignore the tailnet-wide default auto-update setting in containers, but
allow local users to turn on auto-updates via the CLI.
RELNOTE=Auto-updates are allowed in containers, but ignore the tailnet-wide default.
Fixes#12292
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Updates corp#15802.
Adds the ability for control to disable the recently added change that uses split DNS in more cases on iOS. This will allow us to disable the feature if it leads to regression in production. We plan to remove this knob once we've verified that the feature works properly.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
StartupInfoBuilder is a helper for constructing StartupInfoEx structures
featuring proc/thread attribute lists. Calling its setters triggers the
appropriate setting of fields, adjusting flags as necessary, and populating
the proc/thread attribute list as necessary. Currently it supports four
features: setting std handles, setting pseudo-consoles, specifying handles
for inheritance, and specifying jobs.
The conpty package simplifies creation of pseudo-consoles, their associated
pipes, and assignment of the pty to StartupInfoEx proc/thread attributes.
Updates #12383
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
To make it easier for people to monitor their custom DERP fleet.
Updates tailscale/corp#20654
Change-Id: Id8af22936a6d893cc7b6186d298ab794a2672524
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This bug was introduced in e6b84f215 (May 2020) but was only used in
tests when stringifying probeProto values on failure so it wasn't
noticed for a long time.
But then it was moved into non-test code in 8450a18aa (Jun 2024) and I
didn't notice during the code movement that it was wrong. It's still
only used in failure paths in logs, but having wrong/ambiguous
debugging information isn't the best.
Whoops.
Updates tailscale/corp#20654
Change-Id: I296c727ed1c292a04db7b46ecc05c07fc1abc774
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Evaluation of remote write errors was using errors.Is() where it should
have been using errors.As().
Updates tailscale/corp#20344
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This updates breakglass to use the now-upsteamed
https://github.com/gokrazy/breakglass/pull/18 change
so we're not using our fork now.
It also adds a gok wrapper tool, because doing it by hand
was tedious.
Updates #1866
Change-Id: Ifacbf5fbf0e377b3bd95c5f76c18751c2e1af7d7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is done in preparation for adding kubectl
session recording rules to this capability grant that will need to
be unmarshalled by control, so will also need to be
in a shared location.
Updates tailscale/corp#19821
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Rather than building a new suggested exit node set every time, compute
it once on first use. Currently, syspolicy ensures that values do not
change without a restart anyway.
Since the set is being constructed in a separate func now, the test code
that manipulates syspolicy can live there, and the TestSuggestExitNode
can now run in parallel with other tests because it does not have global
dependencies.
Updates tailscale/corp#19681
Change-Id: Ic4bb40ccc91b671f9e542bd5ba9c96f942081515
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
cmd/k8s-operator/deploy/chart: Support image 'repo' or 'repository' keys in helm values
Fixes#12100
Signed-off-by: Michael Long <michaelongdev@gmail.com>
Clean up the updater goroutine on shutdown, in addition to doing that on
backend state change. This fixes a goroutine leak on shutdown in tests.
Updates #cleanup
When the client is disconnected from control for any reason (typically
just turned off), we should still attempt to update if auto-updates are
enabled. This may help users who turn tailscale on infrequently for
accessing resources.
RELNOTE: Apply auto-updates even if the node is down or disconnected
from the coordination server.
Updates #12117
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This adds a new prototype `cmd/natc` which can be used
to expose a services/domains to the tailnet.
It requires the user to specify a set of IPv4 prefixes
from the CGNAT range. It advertises these as normal subnet
routes. It listens for DNS on the first IP of the first range
provided to it.
When it gets a DNS query it allocates an IP for that domain
from the v4 range. Subsequent connections to the assigned IP
are then tcp proxied to the domain.
It is marked as a WIP prototype and requires the use of the
`TAILSCALE_USE_WIP_CODE` env var.
Updates tailscale/corp#20503
Signed-off-by: Maisem Ali <maisem@tailscale.com>
A `*listener` implements net.Listener which breaks
a test in another repo.
Regressed in 42cfbf427c.
Updates #12182
Signed-off-by: Maisem Ali <maisem@tailscale.com>
In order to test the sticky last suggestion code, a test was written for
LocalBackend.SuggestExitNode but it contains a random number generator
which makes writing comprehensive tests very difficult. This doesn't
change how the last suggestion works, but it adds some infrastructure to
make that easier in a later PR.
This adds func parameters for the two randomized parts: breaking ties
between DERP regions and breaking ties between nodes. This way tests can
validate the entire list of tied options, rather than expecting a
particular outcome given a particular random seed.
As a result of this, the global random number generator can be used
rather than seeding a local one each time.
In order to see the tied nodes for the location based (i.e. Mullvad)
case, pickWeighted needed to return a slice instead of a single
arbitrary option, so there is a small change in how that works.
Updates tailscale/corp#19681
Change-Id: I83c48a752abdec0f59c58ccfd8bfb3f3f17d0ea8
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
stunstamp timestamping includes userspace and SO_TIMESTAMPING kernel
timestamping where available. Measurements are written locally to a
sqlite DB, exposed over an HTTP API, and written to prometheus
via remote-write protocol.
Updates tailscale/corp#20344
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This mostly removes a lot of repetition by predefining some nodes and
other data structures, plus adds some helpers for creating Peer entries
in the netmap. Several existing test cases were reworked to ensure
better coverage of edge cases, and several new test cases were added to
handle some additional responsibility that is in (or will be shortly
moving in) suggestExitNode().
Updates tailscale/corp#19681
Change-Id: Ie14c2988d7fd482f7d6a877f78525f7788669b85
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
A non-signing node can be allowed to re-sign its new node keys following
key renewal/rotation (e.g. via `tailscale up --force-reauth`). To be
able to do this, node's TLK is written into WrappingPubkey field of the
initial SigDirect signature, signed by a signing node.
The intended use of this field implies that, for each WrappingPubkey, we
typically expect to have at most one active node with a signature
tracing back to that key. Multiple valid signatures referring to the
same WrappingPubkey can occur if a client's state has been cloned, but
it's something we explicitly discourage and don't support:
https://tailscale.com/s/clone
This change propagates rotation details (wrapping public key, a list
of previous node keys that have been rotated out) to netmap processing,
and adds tracking of obsolete node keys that, when found, will get
filtered out.
Updates tailscale/corp#19764
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This adds a new ListenPacket function on tsnet.Server
which acts mostly like `net.ListenPacket`.
Unlike `Server.Listen`, this requires listening on a
specific IP and does not automatically listen on both
V4 and V6 addresses of the Server when the IP is unspecified.
To test this, it also adds UDP support to tsdial.Dialer.UserDial
and plumbs it through the localapi. Then an associated test
to make sure the UDP functionality works from both sides.
Updates #12182
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Alpine APK repos are versioned, and contain different package sets.
Older APK releases and repos don't have the latest tailscale package.
When we report "no update available", check whether pkgs.tailscale.com
has a newer tarball release. If it does, it's possible that the system
is on an older Alpine release. Print additional messages to suggest the
user to upgrade their OS.
Fixes#11309
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This fixes an issue where, on containerized environments an upgrade
1.66.3 -> 1.66.4 failed with default containerboot configuration.
This was because containerboot by default runs 'tailscale up'
that requires all previously set flags to be explicitly provided
on subsequent runs and we explicitly set --stateful-filtering
to true on 1.66.3, removed that settingon 1.66.4.
Updates tailscale/tailscale#12307
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Andrew Lytvynov <awly@tailscale.com>
In https://github.com/tailscale/tailscale/pull/11363
I changed the subnet router manifest to run in tun
mode (for performance reasons), but did not
change the security context to give it net_admin,
which is required to for the tailscale socket.
Updates tailscale/tailscale#12083
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The derp metrics got out of sync in 74eb99aed1 (2023-03).
They were fixed in 0380cbc90d (2024-05).
This adds some further guardrails (atop the previous fix) to make sure
they don't get out of sync again.
Updates #12288
Change-Id: I809061a81f8ff92f45054d0253bc13871fc71634
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change makes our access log record more consistent with the
new log/tslog package formatting of "time". Note that we can
change slog itself to call "time" "when" but we're chosing
to make this breaking change to be consistent with the std lib's
defaults.
Updates tailscale/corp#17071
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
- Add current node signature to `ipnstate.NetworkLockStatus`;
- Print current node signature in a human-friendly format as part
of `tailscale lock status`.
Examples:
```
$ tailscale lock status
Tailnet lock is ENABLED.
This node is accessible under tailnet lock. Node signature:
SigKind: direct
Pubkey: [OTB3a]
KeyID: tlpub:44a0e23cd53a4b8acc02f6732813d8f5ba8b35d02d48bf94c9f1724ebe31c943
WrappingPubkey: tlpub:44a0e23cd53a4b8acc02f6732813d8f5ba8b35d02d48bf94c9f1724ebe31c943
This node's tailnet-lock key: tlpub:44a0e23cd53a4b8acc02f6732813d8f5ba8b35d02d48bf94c9f1724ebe31c943
Trusted signing keys:
tlpub:44a0e23cd53a4b8acc02f6732813d8f5ba8b35d02d48bf94c9f1724ebe31c943 1 (self)
tlpub:6fa21d242a202b290de85926ba3893a6861888679a73bc3a43f49539d67c9764 1 (pre-auth key kq3NzejWoS11KTM59)
```
For a node created via a signed auth key:
```
This node is accessible under tailnet lock. Node signature:
SigKind: rotation
Pubkey: [e3nAO]
Nested:
SigKind: credential
KeyID: tlpub:6fa21d242a202b290de85926ba3893a6861888679a73bc3a43f49539d67c9764
WrappingPubkey: tlpub:3623b0412cab0029cb1918806435709b5947ae03554050f20caf66629f21220a
```
For a node that rotated its key a few times:
```
This node is accessible under tailnet lock. Node signature:
SigKind: rotation
Pubkey: [DOzL4]
Nested:
SigKind: rotation
Pubkey: [S/9yU]
Nested:
SigKind: rotation
Pubkey: [9E9v4]
Nested:
SigKind: direct
Pubkey: [3QHTJ]
KeyID: tlpub:44a0e23cd53a4b8acc02f6732813d8f5ba8b35d02d48bf94c9f1724ebe31c943
WrappingPubkey: tlpub:2faa280025d3aba0884615f710d8c50590b052c01a004c2b4c2c9434702ae9d0
```
Updates tailscale/corp#19764
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
The `--wait` flag for `systemd-run` was added in systemd 232. While it
is quite old, it doesn't hurt to special-case them and skip the `--wait`
flag. The consequence is that we lose the update command output in logs,
but at least auto-updates will work.
Fixes#12136
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This busybox fwmaskWorks check was added before we moved away from
using the "ip" command to using netlink directly.
So it's now just wasted work (and log spam on Gokrazy) to check the
"ip" command capabilities if we're never going to use it.
Do it lazily instead.
Updates #12277
Change-Id: I8ab9acf64f9c0d8240ce068cb9ec8c0f6b1ecee7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates https://github.com/tailscale/corp/issues/15802.
On iOS exclusively, this PR adds logic to use a split DNS configuration in more cases, with the goal of improving battery life. Acting as the global DNS resolver on iOS should be avoided, as it leads to frequent wakes of IPNExtension.
We try to determine if we can have Tailscale only handle DNS queries for resources inside the tailnet, that is, all routes in the DNS configuration do not require a custom resolver (this is the case for app connectors, for instance).
If so, we set all Routes as MatchDomains. This enables a split DNS configuration which will help preserve battery life. Effectively, for the average Tailscale user who only relies on MagicDNS to resolve *.ts.net domains, this means that Tailscale DNS will only be used for those domains.
This PR doesn't affect users with Override Local DNS enabled. For these users, there should be no difference and Tailscale will continue acting as a global DNS resolver.
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
This allows pam authentication to run for ssh sessions, triggering
automation like pam_mkhomedir.
Updates #11854
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This can be used to implement a persistent pool (i.e. one that isn't
cleared like sync.Pool is) of items–e.g. database connections.
Some benchmarks vs. a naive implementation that uses a single map
iteration show a pretty meaningful improvement:
$ benchstat -col /impl ./bench.txt
goos: darwin
goarch: arm64
pkg: tailscale.com/util/pool
│ Pool │ map │
│ sec/op │ sec/op vs base │
Pool_AddDelete-10 10.56n ± 2% 15.11n ± 1% +42.97% (p=0.000 n=10)
Pool_TakeRandom-10 56.75n ± 4% 1899.50n ± 20% +3246.84% (p=0.000 n=10)
geomean 24.49n 169.4n +591.74%
Updates tailscale/corp#19900
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie509cb65573c4726cfc3da9a97093e61c216ca18
We don't build a lot of tools with CGO, but we do build some, and it's
extremely valuable for production services in particular to have symbols
included - for perf and so on.
I tested various other builds that could be affected negatively, in
particular macOS/iOS, but those use split-dwarf already as part of their
build path, and Android which does not currently use gocross.
One binary which is normally 120mb only grew to 123mb, so the trade-off
is definitely worthwhile in context.
Updates tailscale/corp#20296
Signed-off-by: James Tucker <james@tailscale.com>
Palo Alto reported interpreting hairpin probes as LAND attacks, and the
firewalls may be responding to this by shutting down otherwise in use NAT sessions
prematurely. We don't currently make use of the outcome of the hairpin
probes, and they contribute to other user confusion with e.g. the
AirPort Extreme hairpin session workaround. We decided in response to
remove the whole probe feature as a result.
Updates #188
Updates tailscale/corp#19106
Updates tailscale/corp#19116
Signed-off-by: James Tucker <james@tailscale.com>
After some analysis, stateful filtering is only necessary in tailnets
that use `autogroup:danger-all` in `src` in ACLs. And in those cases
users explicitly specify that hosts outside of the tailnet should be
able to reach their nodes. To fix local DNS breakage in containers, we
disable stateful filtering by default.
Updates #12108
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This change updates the existing api.md TOC links to point at the new
publicapi folder/files. It also removes the body of the docs from the
file, to avoid the docs becoming out of sync.
This change also renames overview.md to readme.md.
Updates tailscale/corp#19526
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
It was requested by the first customer 4-5 years ago and only used
for a brief moment of time. We later added netmap visibility trimming
which removes the need for this.
It's been hidden by the CLI for quite some time and never documented
anywhere else.
This keeps the CLI flag, though, out of caution. It just returns an
error if it's set to anything but true (its default).
Fixes#12058
Change-Id: I7514ba572e7b82519b04ed603ff9f3bdbaecfda7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates #12172 (then need to update other repos)
Change-Id: I439f65e0119b09e00da2ef5c7a4f002f93558578
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change includes the device and user invites API docs in the
new publicapi documentation structure.
Updates tailscale/corp#19526
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Palo Alto firewalls have a typically hard NAT, but also have a mode
called Persistent DIPP that is supposed to provide consistent port
mapping suitable for STUN resolution of public ports. Persistent DIPP
works initially on most Palo Alto firewalls, but some models/software
versions have a bug which this works around.
The bug symptom presents as follows:
- STUN sessions resolve a consistent public IP:port to start with
- Much later netchecks report the same IP:Port for a subset of
sessions, most often the users active DERP, and/or the port related
to sustained traffic.
- The broader set of DERPs in a full netcheck will now consistently
observe a new IP:Port.
- After this point of observation, new inbound connections will only
succeed to the new IP:Port observed, and existing/old sessions will
only work to the old binding.
In this patch we now advertise the lowest latency global endpoint
discovered as we always have, but in addition any global endpoints that
are observed more than once in a single netcheck report. This should
provide viable endpoints for potential connection establishment across
a NAT with this behavior.
Updates tailscale/corp#19106
Signed-off-by: James Tucker <james@tailscale.com>
This change creates a new folder called publicapi that will become the
future home to the Tailscale public API docs.
This change also splits the existing API docs (still located in api.md)
into separate files, for easier reading and contribution.
Updates tailscale/corp#19526
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Fixestailscale/tailscale#10393Fixestailscale/corp#15412Fixestailscale/corp#19808
On Apple platforms, exit nodes and subnet routers have been unable to relay pings from Tailscale devices to non-Tailscale devices due to sandbox restrictions imposed on our network extensions by Apple. The sandbox prevented the code in netstack.go from spawning the `ping` process which we were using.
Replace that exec call with logic to send an ICMP echo request directly, which appears to work in userspace, and not trigger a sandbox violation in the syslog.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Tracking down the side effect can otherwise be a pain, for example on
Darwin an empty GOOS resulted in CGO being implicitly disabled. The user
intended for `export GOOS=` to act like unset, and while this is a
misunderstanding, the main toolchain would treat it this way.
Fixestailscale/corp#20059
Signed-off-by: James Tucker <james@tailscale.com>
This reverts commit e3dec086e6.
Going to reuse Meta instead as that is already exported.
Updates tailscale/corp#1297
Signed-off-by: Maisem Ali <maisem@tailscale.com>
In this commit I updated the Ipv6 range we use to generate Control D DOH ip, we were using the NextDNSRanges to generate Control D DOH ip, updated to use the correct range.
Updates: #7946
Signed-off-by: Kevin Liang <kevinliang@tailscale.com>
In a configuration where the local node (ip1) has a different IP (ip2)
that it uses to communicate with a peer (ip3) we would do UDP flow
tracking on the `ip2->ip3` tuple. When we receive the response from
the peer `ip3->ip2` we would dnat it back to `ip3->ip1` which would
then not match the flow track state and the packet would get dropped.
To fix this, we should do flow tracking on the `ip1->ip3` tuple instead
of `ip2->ip3` which requires doing SNAT after the running filterPacketOutboundToWireGuard.
Updates tailscale/corp#19971, tailscale/corp#8020
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Fixestailscale/corp#19979
A build with version number 275 was uploaded to the App Store without bumping OSS first. The presence of that build is causing any 274.* build to be rejected. To address this, added -1 to the year component, which means new builds will use the 275.* prefix.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Without changing behaviour, don't create a goroutine per connection that
sits and sleeps, but rather use a timer that wakes up and gathers
statistics on a regular basis.
Fixes#12127
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ibc486447e403070bdc3c2cd8ae340e7d02854f21
* util/linuxfw: fix IPv6 NAT availability check for nftables
When running firewall in nftables mode,
there is no need for a separate NAT availability check
(unlike with iptables, there are no hosts that support nftables, but not IPv6 NAT - see tailscale/tailscale#11353).
This change fixes a firewall NAT availability check that was using the no-longer set ipv6NATAvailable field
by removing the field and using a method that, for nftables, just checks that IPv6 is available.
Updates tailscale/tailscale#12008
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The previous LocalBackend & CLI 'up' changes improved some stuff, but
might've been too aggressive in some edge cases.
This simplifies the authURL vs authURLSticky distinction and removes
the interact field, which seemed to just just be about duplicate URL
suppression in IPN bus, back from when the IPN bus was a single client
at a time. This moves that suppression to a different spot.
Fixes#12119
Updates #12028
Updates #12042
Change-Id: I1f8800b1e82ccc1c8a0d7abba559e7404ddf41e4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This was a typo in 2e19790f61.
It should have been on `Map` and not on `*Map` as otherwise
it doesn't allow for chaining like `someView.SomeMap().AsMap()`
and requires first assigning it to a variable.
Updates #typo
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This adds a new `UserLogf` field to the `Server` struct.
When set this any logs generated by Server are logged using
`UserLogf` and all spammy backend logs are logged to `Logf`.
If it `UserLogf` is unset, we default to `log.Printf` and
if `Logf` is unset we discard all the spammy logs.
Fixes#12094
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Clients often perform a PROPFIND for the parent directory before
performing PROPFIND for specific children within that directory.
The PROPFIND for the parent directory is usually done at depth 1,
meaning that we already have information for all of the children.
By immediately adding that to the cache, we save a roundtrip to
the remote peer on the PROPFIND for the specific child.
Updates tailscale/corp#19779
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Turn off stateful filtering for egress proxies to allow cluster
traffic to be forwarded to tailnet.
Allow configuring stateful filter via tailscaled config file.
Deprecate EXPERIMENTAL_TS_CONFIGFILE_PATH env var and introduce a new
TS_EXPERIMENTAL_VERSIONED_CONFIG env var that can be used to provide
containerboot a directory that should contain one or more
tailscaled config files named cap-<tailscaled-cap-version>.hujson.
Containerboot will pick the one with the newest capability version
that is not newer than its current capability version.
Proxies with this change will not work with older Tailscale
Kubernetes operator versions - users must ensure that
the deployed operator is at the same version or newer (up to
4 version skew) than the proxies.
Updates tailscale/tailscale#12061
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Maisem Ali <maisem@tailscale.com>
When Docker is detected on the host and stateful filtering is enabled,
Docker containers may be unable to reach Tailscale nodes (depending on
the network settings of a container). Detect Docker when stateful
filtering is enabled and print a health warning to aid users in noticing
this issue.
We avoid printing the warning if the current node isn't advertising any
subnet routes and isn't an exit node, since without one of those being
true, the node wouldn't have the correct AllowedIPs in WireGuard to
allow a Docker container to connect to another Tailscale node anyway.
Updates #12070
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Idef538695f4d101b0ef6f3fb398c0eaafc3ae281
We were missing `snat-subnet-routes`, `stateful-filtering`
and `netfilter-mode`. Add those to set too.
Fixes#12061
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We are now publishing nameserver images to tailscale/k8s-nameserver,
so we can start defaulting the images if users haven't set
them explicitly, same as we already do with proxy images.
The nameserver images are currently only published for unstable
track, so we have to use the static 'unstable' tag.
Once we start publishing to stable, we can make the operator
default to its own tag (because then we'll know that for each
operator tag X there is also a nameserver tag X as we always
cut all images for a given tag.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Previously, a node that was advertising a 4via6 route wouldn't be able
to make use of that same route; the packet would be delivered to
Tailscale, but since we weren't accepting it in handleLocalPackets, the
packet wouldn't be delivered to netstack and would never hit the 4via6
logic. Let's add that support so that usage of 4via6 is consistent
regardless of where the connection is initiated from.
Updates #11304
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ic28dc2e58080d76100d73b93360f4698605af7cb
The CLI's "up" is kinda chaotic and LocalBackend.Start is kinda
chaotic and they both need to be redone/deleted (respectively), but
this fixes some buggy behavior meanwhile. We were previously calling
StartLoginInteractive (to start the controlclient's RegisterRequest)
redundantly in some cases, causing test flakes depending on timing and
up's weird state machine.
We only need to call StartLoginInteractive in the client if Start itself
doesn't. But Start doesn't tell us that. So cheat a bit and a put the
information about whether there's a current NodeKey in the ipn.Status.
It used to be accessible over LocalAPI via GetPrefs as a private key but
we removed that for security. But a bool is fine.
So then only call StartLoginInteractive if that bool is false and don't
do it in the WatchIPNBus loop.
Fixes#12028
Updates #12042
Change-Id: I0923c3f704a9d6afd825a858eb9a63ca7c1df294
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There was a small window in ipnserver after we assigned a LocalBackend
to the ipnserver's atomic but before we Start'ed it where our
initalization Start could conflict with API calls from the LocalAPI.
Simplify that a bit and lay out the rules in the docs.
Updates #12028
Change-Id: Ic5f5e4861e26340599184e20e308e709edec68b1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We used to Lock, Unlock, Lock, Unlock quite a few
times in Start resulting in all sorts of weird race
conditions. Simplify it all and only Lock/Unlock once.
Updates #11649
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This removes one of the Lock,Unlock,Lock,Unlock at least in
the Start function. Still has 3 more of these.
Updates #11649
Signed-off-by: Maisem Ali <maisem@tailscale.com>
It was documented as such but seems to have been dropped in a
refactor, restore the behavior. This brings down the time it
takes to run a single integration test by 2s which adds up
quite a bit.
Updates tailscale/corp#19786
Signed-off-by: Maisem Ali <maisem@tailscale.com>
I found this too hard to read before.
This is pulled out of #12033 as it's unrelated cleanup in retrospect.
Updates #12028
Change-Id: I727c47e573217e3d1973c5b66a76748139cf79ee
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This way the default gets populated on first start, when no existing
state exists to migrate. Also fix `ipn.PrefsFromBytes` to preserve empty
fields, rather than layering `NewPrefs` values on top.
Updates https://github.com/tailscale/corp/issues/19623
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This adds a new bool that can be sent down from control
to do jailing on the client side. Previously this would
only be done from control by modifying the packet filter
we sent down to clients. This would result in a lot of
additional work/CPU on control, we could instead just
do this on the client. This has always been a TODO which
we keep putting off, might as well do it now.
Updates tailscale/corp#19623
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This plumbs a packet filter for jailed nodes through to the
tstun.Wrapper; the filter for a jailed node is equivalent to a "shields
up" filter. Currently a no-op as there is no way for control to
tell the client whether a peer is jailed.
Updates tailscale/corp#19623
Co-authored-by: Andrew Dunham <andrew@du.nham.ca>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Change-Id: I5ccc5f00e197fde15dd567485b2a99d8254391ad
Now that tsdial.Dialer.UserDial has been updated to honor the configured routes
and dial external network addresses without going through Tailscale, while also being
able to dial a node/subnet router on the tailnet, we can start using UserDial to forward
DNS requests. This is primarily needed for DNS over TCP when forwarding requests
to internal DNS servers, but we also update getKnownDoHClientForProvider to use it.
Updates tailscale/corp#18725
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This refactors the peerConfig struct to allow storing more
details about a peer and not just the masq addresses. To be
used in a follow up change.
As a side effect, this also makes the DNAT logic on the inbound
packet stricter. Previously it would only match against the packets
dst IP, not it also takes the src IP into consideration. The beahvior
is at parity with the SNAT case.
Updates tailscale/corp#19623
Co-authored-by: Andrew Dunham <andrew@du.nham.ca>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Change-Id: I5f40802bebbf0f055436eb8824e4511d0052772d
The CLI "up" command is a historical mess, both on the CLI side and
the LocalBackend side. We're getting closer to cleaning it up, but in
the meantime it was again implicated in flaky tests.
In this case, the background goroutine running WatchIPNBus was very
occasionally running enough to get to its StartLoginInteractive call
before the original goroutine did its Start call. That meant
integration tests were very rarely but sometimes logging in with the
default control plane URL out on the internet
(controlplane.tailscale.com) instead of the localhost control server
for tests.
This also might've affected new Headscale etc users on initial "up".
Fixes#11960Fixes#11962
Change-Id: I36f8817b69267a99271b5ee78cb7dbf0fcc0bd34
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I noticed this while working on the following fix to #11962.
Updates #11962
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I4c5894d8899d1ae8c42f54ecfd4d05a4a7ac598c
We'd like to use tsdial.Dialer.UserDial instead of SystemDial for DNS over TCP.
This is primarily necessary to properly dial internal DNS servers accessible
over Tailscale and subnet routes. However, to avoid issues when switching
between Wi-Fi and cellular, we need to ensure that we don't retain connections
to any external addresses on the old interface. Therefore, we need to determine
which dialer to use internally based on the configured routes.
This plumbs routes and localRoutes from router.Config to tsdial.Dialer,
and updates UserDial to use either the peer dialer or the system dialer,
depending on the network address and the configured routes.
Updates tailscale/corp#18725
Fixes#4529
Signed-off-by: Nick Khyl <nickk@tailscale.com>
set.Of(1, 2, 3) is prettier than set.SetOf([]int{1, 2, 3}).
I was going to change the signature of SetOf but then I noticed its
name has stutter anyway, so I kept it for compatibility. People can
prefer to use set.Of for new code or slowly migrate.
Also add a lazy Make method, which I often find myself wanting,
without having to resort to uglier mak.Set(&set, k, struct{}{}).
Updates #cleanup
Change-Id: Ic6f3870115334efcbd65e79c437de2ad3edb7625
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The inflight request tracker only starts recording a new bucket after
the first non-error request. Unfortunately, it's written in such a way
that ONLY successful requests are ever marked as being finished. Once a
bucket has had at least one successful request and begun to be tracked,
all subsequent error cases are never marked finished and always appear
as in-flight.
This change ensures that if a request is recorded has having been
started, we also mark it as finished at the end.
Updates tailscale/corp#19767
Signed-off-by: Will Norris <will@tailscale.com>
Setting the field after-the-fact wasn't working because we could migrate
prefs on creation, which would set health status for auto updates.
Updates #11986
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I41d79ebd61d64829a3a9e70586ce56f62d24ccfd
While debugging a failing test in airplane mode on macOS, I noticed
netcheck logspam about ICMP socket creation permission denied errors.
Apparently macOS just can't do those, or at least not in airplane
mode. Not worth spamming about.
Updates #cleanup
Change-Id: I302620cfd3c8eabb25202d7eef040c01bd8a843c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The netcheck client, when no UDP is available, probes distance using
HTTPS.
Several problems:
* It probes using /derp/latency-check.
* But cmd/derper serves the handler at /derp/probe
* Despite the difference, it work by accident until c8f4dfc8c0
which made netcheck's probe require a 2xx status code.
* in tests, we only use derphttp.Handler, so the cmd/derper-installed
mux routes aren't preesnt, so there's no probe. That breaks
tests in airplane mode. netcheck.Client then reports "unexpected
HTTP status 426" (Upgrade Required)
This makes derp handle both /derp/probe and /derp/latency-check
equivalently, and in both cmd/derper and derphttp.Handler standalone
modes.
I notice this when wgengine/magicsock TestActiveDiscovery was failing
in airplane mode (no wifi). It still doesn't pass, but it gets
further.
Fixes#11989
Change-Id: I45213d4bd137e0f29aac8bd4a9ac92091065113f
Not buying wifi on a short flight is a good way to find tests
that require network. Whoops.
Updates #cleanup
Change-Id: Ibe678e9c755d27269ad7206413ffe9971f07d298
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for it being required in more places.
Updates #11874
Change-Id: Ib743205fc2a6c6ff3d2c4ed3a2b28cac79156539
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This prevents Mark-of-the-Web bypass attacks in case someone visits the
localhost WebDAV server directly.
Fixestailscale/corp#19592
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This prevents Mark-of-the-Web bypass attacks in case someone visits the
localhost WebDAV server directly.
Fixestailscale/corp#19592
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This prevents Mark-of-the-Web bypass attacks in case someone visits the
localhost WebDAV server directly.
Fixestailscale/corp#19592
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This prevents Mark-of-the-Web bypass attacks in case someone visits the
localhost WebDAV server directly.
Fixestailscale/corp#19592
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This prevents Mark-of-the-Web bypass attacks in case someone visits the
localhost WebDAV server directly.
Fixestailscale/corp#19592
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This prevents Mark-of-the-Web bypass attacks in case someone visits the
localhost WebDAV server directly.
Fixestailscale/corp#19592
Signed-off-by: Percy Wegmann <percy@tailscale.com>
To aid in debugging exactly what's going wrong, instead of the
not-particularly-useful "dns udp query: context deadline exceeded" error
that we currently get.
Updates #3786
Updates #10768
Updates #11620
(etc.)
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I76334bf0681a8a2c72c90700f636c4174931432c
cmd/k8s-operator: optionally update dnsrecords Configmap with DNS records for proxies.
This commit adds functionality to automatically populate
DNS records for the in-cluster ts.net nameserver
to allow cluster workloads to resolve MagicDNS names
associated with operator's proxies.
The records are created as follows:
* For tailscale Ingress proxies there will be
a record mapping the MagicDNS name of the Ingress
device and each proxy Pod's IP address.
* For cluster egress proxies, configured via
tailscale.com/tailnet-fqdn annotation, there will be
a record for each proxy Pod, mapping
the MagicDNS name of the exposed
tailnet workload to the proxy Pod's IP.
No records will be created for any other proxy types.
Records will only be created if users have configured
the operator to deploy an in-cluster ts.net nameserver
by applying tailscale.com/v1alpha1.DNSConfig.
It is user's responsibility to add the ts.net nameserver
as a stub nameserver for ts.net DNS names.
https://kubernetes.io/docs/tasks/administer-cluster/dns-custom-nameservers/#configuration-of-stub-domain-and-upstream-nameserver-using-corednshttps://cloud.google.com/kubernetes-engine/docs/how-to/kube-dns#upstream_nameservers
See also https://github.com/tailscale/tailscale/pull/11017
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
It's deprecated and using it gets us the old slow behavior
according to https://go.dev/blog/randv2.
> Having eliminated repeatability of the global output stream, Go 1.20
> was also able to make the global generator scale better in programs
> that don’t call rand.Seed, replacing the Go 1 generator with a very
> cheap per-thread wyrand generator already used inside the Go
> runtime. This removed the global mutex and made the top-level
> functions scale much better. Programs that do call rand.Seed fall
> back to the mutex-protected Go 1 generator.
Updates #7123
Change-Id: Ia5452e66bd16b5457d4b1c290a59294545e13291
Signed-off-by: Maisem Ali <maisem@tailscale.com>
In prep for making health warnings rich objects with metadata rather
than a bunch of strings, start moving it all into the same place.
We'll still ultimately need the stringified form for the CLI and
LocalAPI for compatibility but we'll next convert all these warnings
into Warnables that have severity levels and such, and legacy
stringification will just be something each Warnable thing can do.
Updates #4136
Change-Id: I83e189435daae3664135ed53c98627c66e9e53da
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So that we can use this for additional, non-NAT configuration without it
being confusing.
Updates #cleanup
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I1658d59c9824217917a94ee76d2d08f0a682986f
This was a holdover from the older, pre-BART days and is no longer
necessary.
Updates #cleanup
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I71b892bab1898077767b9ff51cef33d59c08faf8
Updates tailscale/corp#18960
Tests in corp called us using the wrong logging calls. Removed.
This is logged downstream anyway.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
This configures localClient correctly during flag parsing, so that the --socket
option is effective when generating tab-completion results. For example, the
following would not connect to the system Tailscale for tab-completion results:
tailscale --socket=/tmp/tailscaled.socket switch <TAB>
Updates #3793
Signed-off-by: Paul Scott <paul@tailscale.com>
Updates tailscale/corp#18960
iOS uses Apple's NetworkMonitor to track the default interface and
there's no reason we shouldn't also use this on macOS, for the same
reasons noted in the comments for why this change was made on iOS.
This eliminates the need to load and parse the routing table when
querying the defaultRouter() in almost all cases.
A slight modification here (on both platforms) to fallback to the default
BSD logic in the unhappy-path rather than making assumptions that
may not hold. If netmon is eventually parsing AF_ROUTE and able
to give a consistently correct answer for the default interface index,
we can fall back to that and eliminate the Swift dependency.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
cmd/k8s-operator/deploy/chart: allow users to configure additional labels for the operator's Pod via Helm chart values.
Fixes#11947
Signed-off-by: Gabe Gorelick <gabe@hightouch.io>
We had this in a different repo, but moving it here, as this a more
fitting package.
Updates #cleanup
Change-Id: I5fb9b10e465932aeef5841c67deba4d77d473d57
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Also, reset it in a few more places (e.g. logout, new blank profiles,
etc.) to avoid a few more cases where a pre-existing dialPlan can cause
a new Headscale server take 10+ seconds to connect.
Updates #11938
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I3095173a5a3d9720507afe4452548491e9e45a3e
If AtomicValue[T] is used with a T that is an interface kind,
then Store may panic if different concret types are ever stored.
Fix this by always wrapping in a concrete type.
Technically, this is only needed if T is an interface kind,
but there is no harm in doing it also for non-interface kinds.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
* cmd/k8s-nameserver,k8s-operator: add a nameserver that can resolve ts.net DNS names in cluster.
Adds a simple nameserver that can respond to A record queries for ts.net DNS names.
It can respond to queries from in-memory records, populated from a ConfigMap
mounted at /config. It dynamically updates its records as the ConfigMap
contents changes.
It will respond with NXDOMAIN to queries for any other record types
(AAAA to be implemented in the future).
It can respond to queries over UDP or TCP. It runs a miekg/dns
DNS server with a single registered handler for ts.net domain names.
Queries for other domain names will be refused.
The intended use of this is:
1) to allow non-tailnet cluster workloads to talk to HTTPS tailnet
services exposed via Tailscale operator egress over HTTPS
2) to allow non-tailnet cluster workloads to talk to workloads in
the same cluster that have been exposed to tailnet over their
MagicDNS names but on their cluster IPs.
DNSConfig CRD can be used to configure
the operator to deploy kube nameserver (./cmd/k8s-nameserver) to cluster.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
When switching profile, the server URL can change (e.g.
because of switching to a self-hosted headscale instance).
If it is not reset here, dial plans returned by old
server (e.g. tailscale control server) will be used to
connect to new server (e.g. self-hosted headscale server),
and the register request will be blocked by it until
timeout, leading to very slow profile switches.
Updates #11938 11938
Signed-off-by: Shaw Drastin <showier.drastic0a@icloud.com>
Certain device drivers (e.g. vxlan, geneve) do not properly handle
coalesced UDP packets later in the stack, resulting in packet loss.
Updates #11026
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Add documentation for GET/PATCH/PUT `api/v2/tailnet/<ID>/dns/split-dns`.
These endpoints allow for reading, partially updating, and replacing the
split DNS settings for a given tailnet.
Updates https://github.com/tailscale/corp/issues/19483
Signed-off-by: Mario Minardi <mario@tailscale.com>
Before attempting to enable IPv6 forwarding in the proxy init container
check if the relevant module is found, else the container crashes
on hosts that don't have it.
Updates#11860
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The tailscale package is in the community Alpine repo. Check if it's
commented out in `/etc/apk/repositories` and run `setup-apkrepos -c -1`
if it's not.
Fixes#11263
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Add node attribute to determine whether or not to show suggested exit
node in UI.
Updates tailscale/corp#19515
Signed-off-by: Claire Wang <claire@tailscale.com>
This fixes bugs where after using the cli to set AdvertiseRoutes users
were finding that they had to restart tailscaled before the app
connector would advertise previously learned routes again. And seems
more in line with user expectations.
Fixes#11006
Signed-off-by: Fran Bull <fran@tailscale.com>
If the controlknob to persist app connector routes is enabled, when
reconfiguring an app connector unadvertise routes that are no longer
relevant.
Updates #11008
Signed-off-by: Fran Bull <fran@tailscale.com>
If the controlknob is on.
This will allow us to remove discovered routes associated with a
particular domain.
Updates #11008
Signed-off-by: Fran Bull <fran@tailscale.com>
When an app connector is reconfigured and domains to route are removed,
we would like to no longer advertise routes that were discovered for
those domains. In order to do this we plan to store which routes were
discovered for which domains.
Add a controlknob so that we can enable/disable the new behavior.
Updates #11008
Signed-off-by: Fran Bull <fran@tailscale.com>
Lays the groundwork for the ability to persist app connectors discovered
routes, which will allow us to stop advertising routes for a domain if
the app connector no longer monitors that domain.
Updates #11008
Signed-off-by: Fran Bull <fran@tailscale.com>
Explicitly set `-H "Content-Type: application/json"` in CURL examples
for POST endpoints as the default content type used by CURL is otherwise
`application/x-www-form-urlencoded` and these endpoints expect JSON data.
Updates https://github.com/tailscale/tailscale/issues/11914
Signed-off-by: Mario Minardi <mario@tailscale.com>
cmd/containerboot,kube,ipn/store/kubestore: allow interactive login and empty state Secrets, check perms
* Allow users to pre-create empty state Secrets
* Add a fake internal kube client, test functionality that has dependencies on kube client operations.
* Fix an issue where interactive login was not allowed in an edge case where state Secret does not exist
* Make the CheckSecretPermissions method report whether we have permissions to create/patch a Secret if it's determined that these operations will be needed
Updates tailscale/tailscale#11170
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
In prep for most of the package funcs in net/interfaces to become
methods in a long-lived netmon.Monitor that can cache things. (Many
of the funcs are very heavy to call regularly, whereas the long-lived
netmon.Monitor can subscribe to things from the OS and remember
answers to questions it's asked regularly later)
Updates tailscale/corp#10910
Updates tailscale/corp#18960
Updates #7967
Updates #3299
Change-Id: Ie4e8dedb70136af2d611b990b865a822cd1797e5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
... in prep for merging the net/interfaces package into net/netmon.
This is a no-op change that updates a bunch of the API signatures ahead of
a future change to actually move things (and remove the type alias)
Updates tailscale/corp#10910
Updates tailscale/corp#18960
Updates #7967
Updates #3299
Change-Id: I477613388f09389214db0d77ccf24a65bff2199c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Modifies containerboot to wait on tailscaled process
only, not on any child process of containerboot.
Waiting on any subprocess was racing with Go's
exec.Cmd.Run, used to run iptables commands and
that starts its own subprocesses and waits on them.
Containerboot itself does not run anything else
except for tailscaled, so there shouldn't be a need
to wait on anything else.
Updates tailscale/tailscale#11593
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The goal is to move more network state accessors to netmon.Monitor
where they can be cheaper/cached. But first (this change and others)
we need to make sure the one netmon.Monitor is plumbed everywhere.
Some notable bits:
* tsdial.NewDialer is added, taking a now-required netmon
* because a tsdial.Dialer always has a netmon, anything taking both
a Dialer and a NetMon is now redundant; take only the Dialer and
get the NetMon from that if/when needed.
* netmon.NewStatic is added, primarily for tests
Updates tailscale/corp#10910
Updates tailscale/corp#18960
Updates #7967
Updates #3299
Change-Id: I877f9cb87618c4eb037cee098241d18da9c01691
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This has been a TODO for ages. Time to do it.
The goal is to move more network state accessors to netmon.Monitor
where they can be cheaper/cached.
Updates tailscale/corp#10910
Updates tailscale/corp#18960
Updates #7967
Updates #3299
Change-Id: I60fc6508cd2d8d079260bda371fc08b6318bcaf1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I'm working on moving all network state queries to be on
netmon.Monitor, removing old APIs.
Updates tailscale/corp#10910
Updates tailscale/corp#18960
Updates #7967
Updates #3299
Change-Id: If0de137e0e2e145520f69e258597fb89cf39a2a3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Fixestailscale/corp#19558
A request for the suggested exit nodes that occurs too early in the
VPN lifecycle would result in a null deref of the netmap and/or
the netcheck report. This checks both and errors out.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
Adds a new .spec.metrics field to ProxyClass to allow users to optionally serve
client metrics (tailscaled --debug) on <Pod-IP>:9001.
Metrics cannot currently be enabled for proxies that egress traffic to tailnet
and for Ingress proxies with tailscale.com/experimental-forward-cluster-traffic-via-ingress annotation
(because they currently forward all cluster traffic to their respective backends).
The assumption is that users will want to have these metrics enabled
continuously to be able to monitor proxy behaviour (as opposed to enabling
them temporarily for debugging). Hence we expose them on Pod IP to make it
easier to consume them i.e via Prometheus PodMonitor.
Updates tailscale/tailscale#11292
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This adds a health.Tracker to tsd.System, accessible via
a new tsd.System.HealthTracker method.
In the future, that new method will return a tsd.System-specific
HealthTracker, so multiple tsnet.Servers in the same process are
isolated. For now, though, it just always returns the temporary
health.Global value. That permits incremental plumbing over a number
of changes. When the second to last health.Global reference is gone,
then the tsd.System.HealthTracker implementation can return a private
Tracker.
The primary plumbing this does is adding it to LocalBackend and its
dozen and change health calls. A few misc other callers are also
plumbed. Subsequent changes will flesh out other parts of the tree
(magicsock, controlclient, etc).
Updates #11874
Updates #4136
Change-Id: Id51e73cfc8a39110425b6dc19d18b3975eac75ce
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for tsd.System Tracker plumbing throughout tailscaled,
defensively permit all methods on Tracker to accept a nil receiver
without crashing, lest I screw something up later. (A health tracking
system that itself causes crashes would be no good.) Methods on nil
receivers should not be called, so a future change will also collect
their stacks (and panic during dev/test), but we should at least not
crash in prod.
This also locks that in with a test using reflect to automatically
call all methods on a nil receiver and check they don't crash.
Updates #11874
Updates #4136
Change-Id: I8e955046ebf370ec8af0c1fb63e5123e6282a9d3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously it was both metadata about the class of warnable item as
well as the value.
Now it's only metadata and the value is per-Tracker.
Updates #11874
Updates #4136
Change-Id: Ia1ed1b6c95d34bc5aae36cffdb04279e6ba77015
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This moves most of the health package global variables to a new
`health.Tracker` type.
But then rather than plumbing the Tracker in tsd.System everywhere,
this only goes halfway and makes one new global Tracker
(`health.Global`) that all the existing callers now use.
A future change will eliminate that global.
Updates #11874
Updates #4136
Change-Id: I6ee27e0b2e35f68cb38fecdb3b2dc4c3f2e09d68
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This improves convenience and security.
* Convenience - no need to see nodes that can't share anything with you.
* Security - malicious nodes can't expose shares to peers that aren't
allowed to access their shares.
Updates tailscale/corp#19432
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Allows all users to read all files, and .sh/.cgi files to be
executable.
Updates tailscale/tailscale-qpkg#135
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
If seamless key renewal is enabled, we typically do not stop the engine
(deconfigure networking). However, if the node key has expired there is
no point in keeping the connection up, and it might actually prevent
key renewal if auth relies on endpoints routed via app connectors.
Fixestailscale/corp#5800
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Fixestailscale/corp#19459
This PR adds the ability for users of the syspolicy handler to read string arrays from the MDM solution configured on the system.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This change allows for the release/dist/qnap package to be used
outside of the tailscale repo (notably, will be used from corp),
by using an embedded file system for build files which gets
temporarily written to a new folder during qnap build runs.
Without this change, when used from corp, the release/dist/qnap
folder will fail to be found within the corp repo, causing
various steps of the build to fail.
The file renames in this change are to combine the build files
into a /files folder, separated into /scripts and /Tailscale.
Updates tailscale/tailscale-qpkg#135
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This helps reduce memory pressure on tailnets with large numbers
of routes.
Updates tailscale/corp#19332
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This PR bumps iptables to a newer version that has a function to detect
'NotExists' errors and uses that function to determine whether errors
received on iptables rule and chain clean up are because the rule/chain
does not exist- if so don't log the error.
Updates corp#19336
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/containerboot,util/linuxfw: support proxy backends specified by DNS name
Adds support for optionally configuring containerboot to proxy
traffic to backends configured by passing TS_EXPERIMENTAL_DEST_DNS_NAME env var
to containerboot.
Containerboot will periodically (every 10 minutes) attempt to resolve
the DNS name and ensure that all traffic sent to the node's
tailnet IP gets forwarded to the resolved backend IP addresses.
Currently:
- if the firewall mode is iptables, traffic will be load balanced
accross the backend IP addresses using round robin. There are
no health checks for whether the IPs are reachable.
- if the firewall mode is nftables traffic will only be forwarded
to the first IP address in the list. This is to be improved.
* cmd/k8s-operator: support ExternalName Services
Adds support for exposing endpoints, accessible from within
a cluster to the tailnet via DNS names using ExternalName Services.
This can be done by annotating the ExternalName Service with
tailscale.com/expose: "true" annotation.
The operator will deploy a proxy configured to route tailnet
traffic to the backend IPs that service.spec.externalName
resolves to. The backend IPs must be reachable from the operator's
namespace.
Updates tailscale/tailscale#10606
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Since the tailscaled binaries that we distribute are static and don't
link cgo, we previously wouldn't fetch group IDs that are returned via
NSS. Try shelling out to the 'id' command, similar to how we call
'getent', to detect such cases.
Updates #11682
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I9bdc938bd76c71bc130d44a97cc2233064d64799
There is an undocumented 16KiB limit for text log messages.
However, the limit for JSON messages is 256KiB.
Even worse, logging JSON as text results in significant overhead
since each double quote needs to be escaped.
Instead, use logger.Logf.JSON to explicitly log the info as JSON.
We also modify osdiag to return the information as structured data
rather than implicitly have the package log on our behalf.
This gives more control to the caller on how to log.
Updates #7802
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Prior to
1613b18f82 (diff-314ba0d799f70c8998940903efb541e511f352b39a9eeeae8d475c921d66c2ac),
nodes could set AutoUpdate.Apply=true on unsupported platforms via
`EditPrefs`. Specifically, this affects tailnets where default
auto-updates are on.
Fix up those invalid prefs on profile reload, as a migration.
Updates #11544
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Creates new QNAP builder target, which builds go binaries then uses
docker to build into QNAP packages. Much of the docker/script code
here is pulled over from https://github.com/tailscale/tailscale-qpkg,
with adaptation into our builder structures.
The qnap/Tailscale folder contains static resources needed to build
Tailscale qpkg packages, and is an exact copy of the existing folder
in the tailscale-qpkg repo.
Builds can be run with:
```
sudo ./tool/go run ./cmd/dist build qnap
```
Updates tailscale/tailscale-qpkg#135
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Since we already track active SSH connections, it's not hard to
proactively reject updates until those finish. We attempt to do the same
on the control side, but the detection latency for new connections is in
the minutes, which is not fast enough for common short sessions.
Handle a `force=true` query parameter to override this behavior, so that
control can still trigger an update on a server where some long-running
abandoned SSH session is open.
Updates https://github.com/tailscale/corp/issues/18556
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
It was only obviously unused after the previous change, c39cde79d.
Updates #19334
Change-Id: I9896d5fa692cb4346c070b4a339d0d12340c18f7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We were storing server-side lots of:
"Auth":{"Provider":"","LoginName":"","Oauth2Token":null,"AuthKey":""},
That was about 7% of our total storage of pending RegisterRequest
bodies.
Updates tailscale/corp#19327
Change-Id: Ib73842759a2b303ff5fe4c052a76baea0d68ae7d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If this happens, it results in us pessimistically closing more
connections than might be necessary, but is more correct since we won't
"miss" a change to the default route interface and keep trying to send
data over a nonexistent interface, or one that can't reach the internet.
Updates tailscale/corp#19124
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ia0b8b04cb8cdcb0da0155fd08751c9dccba62c1a
The Network Location Awareness service identifies networks authenticated against
an Active Directory domain and categorizes them as "Domain Authenticated".
This includes the Tailscale network if a Domain Controller is reachable through it.
If a network is categories as NLM_NETWORK_CATEGORY_DOMAIN_AUTHENTICATED,
it is not possible to override its category, and we shouldn't attempt to do so.
Additionally, our Windows Firewall rules should be compatible with both private
and domain networks.
This fixes both issues.
Fixes#11813
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Containers are typically immutable and should be updated as a whole (and
not individual packages within). Deny enablement of auto-updates in
containers.
Also, add the missing check in EditPrefs in LocalAPI, to catch cases
like tailnet default auto-updates getting enabled for nodes that don't
support it.
Updates #11544
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
We don't always have the same latest version for all platforms (like
with 1.64.2 is only Synology+Windows), so we should use the OS-specific
result from pkgs JSON response instead of the main Version field.
Updates #11795
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Kubernetes cluster domain defaults to 'cluster.local', but can also be customized.
We need to determine cluster domain to set up in-cluster forwarding to our egress proxies.
This was previously hardcoded to 'cluster.local', so was the egress proxies were not usable in clusters with custom domains.
This PR ensures that we attempt to determine the cluster domain by parsing /etc/resolv.conf.
In case the cluster domain cannot be determined from /etc/resolv.conf, we fall back to 'cluster.local'.
Updates tailscale/tailscale#10399,tailscale/tailscale#11445
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
peerapi does not want these, but rclone includes them.
Removing them allows rclone to work with Taildrive configured
as a WebDAV remote.
Updates #cleanup
Signed-off-by: Percy Wegmann <percy@tailscale.com>
peerapi does not want these, but rclone includes them.
Stripping them out allows rclone to work with Taildrive configured
as a WebDAV remote.
Updates #cleanup
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This ensures that MOVE, LOCK and any other verbs that use the Location
header work correctly.
Fixes#11758
Signed-off-by: Percy Wegmann <percy@tailscale.com>
-Move Android impl into interfaces_android.go
-Instead of using ip route to get the interface name, use the one passed in by Android (ip route is restricted in Android 13+ per termux/termux-app#2993)
Follow-up will be to do the same for router
Fixestailscale/corp#19215Fixestailscale/corp#19124
Signed-off-by: kari-ts <kari@tailscale.com>
Some editions of Windows server share the same build number as their
client counterpart; we must use an additional field found in the OS
version information to distinguish between them.
Even though "Distro" has Linux connotations, it is the most appropriate
hostinfo field. What is Windows Server if not an alternate distribution
of Windows? This PR populates Distro with "Server" when applicable.
Fixes#11785
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This change is safe (self is still safe, by
definition), and makes the code match the comment.
Updates #cleanup
Signed-off-by: Chris Palmer <cpalmer@tailscale.com>
Most of the magicsock tests fake the network, simulating packets going
out and coming in. There's no reason to actually hit your router to do
UPnP/NAT-PMP/PCP during in tests. But while debugging thousands of
iterations of tests to deflake some things, I saw it slamming my
router. This stops that.
Updates #11762
Change-Id: I59b9f48f8f5aff1fa16b4935753d786342e87744
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Turns out, profileManager is not safe for concurrent use and I missed
all the locking infrastructure in LocalBackend, oops.
I was not able to reproduce the race even with `go test -count 100`, but
this seems like an obvious fix.
Fixes#11773
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This ensures that we close the underlying connection(s) when a major
link change happens. If we don't do this, on mobile platforms switching
between WiFi and cellular can result in leftover connections in the
http.Client's connection pool which are bound to the "wrong" interface.
Updates #10821
Updates tailscale/corp#19124
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ibd51ce2efcaf4bd68e14f6fdeded61d4e99f9a01
The approach is lifted from cobra: `tailscale completion bash` emits a bash
script for configuring the shell's autocomplete:
. <( tailscale completion bash )
so that typing:
tailscale st<TAB>
invokes:
tailscale completion __complete -- st
RELNOTE=tailscale CLI now supports shell tab-completion
Fixes#3793
Signed-off-by: Paul Scott <paul@tailscale.com>
This removes AWS and Kubernetes support from Linux binaries by default
on GOARCH values where people don't typically run on AWS or use
Kubernetes, such as 32-bit mips CPUs.
It primarily focuses on optimizing for the static binaries we
distribute. But for people building it themselves, they can set
ts_kube or ts_aws (the opposite of ts_omit_kube or ts_omit_aws) to
force it back on.
Makes tailscaled binary ~2.3MB (~7%) smaller.
Updates #7272, #10627 etc
Change-Id: I42a8775119ce006fa321462cb2d28bc985d1c146
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This wasn't previously handling the case where an interface in s2 was
removed and not present in s1, and would cause the Equal method to
incorrectly return that the states were equal.
Updates tailscale/corp#19124
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I3af22bc631015d1ddd0a1d01bfdf312161b9532d
It should've been deleted in 11ece02f52.
Updates #9040
Change-Id: If8a136bdb6c82804af658c9d2b0a8c63ce02d509
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates tailscale/corp#18724
When localAPI clients directly set ExitNodeID to "", the expected behaviour is that the prior exit node also gets zero'd - effectively setting the UI state back to 'no exit node was ever selected'
The IntenalExitNodePrior has been changed to be a non-opaque type, as it is read by the UI to render the users last selected exit node, and must be concrete. Future-us can either break this, or deprecate it and replace it with something more interesting.
Signed-off-by: Jonathan Nobels <jonathan@tailscale.com>
Seems to deflake tstest/integration tests. I can't reproduce it
anymore on one of my VMs that was consistently flaking after a dozen
runs before. Now I can run hundreds of times.
Updates #11649Fixes#7036
Change-Id: I2f7d4ae97500d507bdd78af9e92cd1242e8e44b8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We haven't needed this hack for quite some time Andrea says.
Updates #11649
Change-Id: Ie854b7edd0a01e92495669daa466c7c0d57e7438
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I'm on a mission to simplify LocalBackend.Start and its locking
and deflake some tests.
I noticed this hasn't been used since March 2023 when it was removed
from the Windows client in corp 66be796d33c.
So, delete.
Updates #11649
Change-Id: I40f2cb75fb3f43baf23558007655f65a8ec5e1b2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We have seen in macOS client logs that the "operation not permitted", a
syscall.EPERM error, is being returned when traffic is attempted to be
sent. This may be caused by security software on the client.
This change will perform a rebind and restun if we receive a
syscall.EPERM error on clients running darwin. Rebinds will only be
called if we haven't performed one specifically for an EPERM error in
the past 5 seconds.
Updates #11710
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
The gliderlabs/ssh license is actually already included in the standard
package listing. I'm not sure why I thought it wasn't.
Updates tailscale/corp#5780
This reverts commit 11dca08e93.
Signed-off-by: Will Norris <will@tailscale.com>
Trying to run iptables/nftables on Synology pauses for minutes with
lots of errors and ultimately does nothing as it's not used and we
lack permissions.
This fixes a regression from db760d0bac (#11601) that landed
between Synology testing on unstable 1.63.110 and 1.64.0 being cut.
Fixes#11737
Change-Id: Iaf9563363b8e45319a9b6fe94c8d5ffaecc9ccef
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adds new ProxyClass.spec.statefulSet.pod.{tailscaleContainer,tailscaleInitContainer}.Env field
that allow users to provide key, value pairs that will be set as env vars for the respective containers.
Allow overriding all containerboot env vars,
but warn that this is not supported and might break (in docs + a warning when validating ProxyClass).
Updates tailscale/tailscale#10709
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
It was broken with the move to dist in 32e0ba5e68 which doesn't accept
amd64 anymore.
Updates #cleanup
Change-Id: Iaaaba2d73c6a09a226934fe8e5c18b16731ee7a6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We have tstest/integration nowadays.
And this test was one of the lone holdouts using the to-be-nuked
SetControlClientGetterForTesting.
Updates #11649
Change-Id: Icf8a6a2e9b8ae1ac534754afa898c00dc0b7623b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
cc vs ccAuto is a mess. It needs to go. But this is a baby step towards
getting there.
Updates #11649
Change-Id: I34f33934844e580bd823a7d8f2b945cf26c87b3b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The new Android app and its libtailscale don't use this anymore;
it uses LocalAPI like other clients now.
Updates #11649
Change-Id: Ic9f42b41e0e0280b82294329093dc6c275f41d50
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
At least in userspace-networking mode.
Fixes#11361
Change-Id: I78d33f0f7e05fe9e9ee95b97c99b593f8fe498f2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Changes made:
* Avoid "encoding/json" for JSON processing, and instead use
"github.com/go-json-experiment/json/jsontext".
Use jsontext.Value.IsValid for validation, which is much faster.
Use jsontext.AppendQuote instead of our own JSON escaping.
* In drainPending, use a different maxLen depending on lowMem.
In lowMem mode, it is better to perform multiple uploads
than it is to construct a large body that OOMs the process.
* In drainPending, if an error is encountered draining,
construct an error message in the logtail JSON format
rather than something that is invalid JSON.
* In appendTextOrJSONLocked, use jsontext.Decoder to check
whether the input is a valid JSON object. This is faster than
the previous approach of unmarshaling into map[string]any and
then re-marshaling that data structure.
This is especially beneficial for network flow logging,
which produces relatively large JSON objects.
* In appendTextOrJSONLocked, enforce maxSize on the input.
If too large, then we may end up in a situation where the logs
can never be uploaded because it exceeds the maximum body size
that the Tailscale logs service accepts.
* Use "tailscale.com/util/truncate" to properly truncate a string
on valid UTF-8 boundaries.
* In general, remove unnecessary spaces in JSON output.
Performance:
name old time/op new time/op delta
WriteText 776ns ± 2% 596ns ± 1% -23.24% (p=0.000 n=10+10)
WriteJSON 110µs ± 0% 9µs ± 0% -91.77% (p=0.000 n=8+8)
name old alloc/op new alloc/op delta
WriteText 448B ± 0% 0B -100.00% (p=0.000 n=10+10)
WriteJSON 37.9kB ± 0% 0.0kB ± 0% -99.87% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
WriteText 1.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
WriteJSON 1.08k ± 0% 0.00k ± 0% -99.91% (p=0.000 n=10+10)
For text payloads, this is 1.30x faster.
For JSON payloads, this is 12.2x faster.
Updates #cleanup
Updates tailscale/corp#18514
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We were being too aggressive when deciding whether to write our NRPT rules
to the local registry key or the group policy registry key.
After once again reviewing the document which calls itself a spec
(see issue), it is clear that the presence of the DnsPolicyConfig subkey
is the important part, not the presence of values set in the DNSClient
subkey. Furthermore, a footnote indicates that the presence of
DnsPolicyConfig in the GPO key will always override its counterpart in
the local key. The implication of this is important: we may unconditionally
write our NRPT rules to the local key. We copy our rules to the policy
key only when it contains NRPT rules belonging to somebody other than us.
Fixes https://github.com/tailscale/corp/issues/19071
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This package is included in the tempfork directory, rather than as a go
module dependency, so is not included in the normal package list.
Updates tailscale/corp#5780
Signed-off-by: Will Norris <will@tailscale.com>
Just because we don't have known endpoints for a peer does not mean that
the peer should become unreachable. If we know the peers key, it should
be able to call us, then we can talk back via whatever path it called us
on. First step - don't drop the packet in this context.
Updates tailscale/corp#19106
Signed-off-by: James Tucker <james@tailscale.com>
Extend the `zypper` install to import importing the GPG key used to sign
the repository packages.
Updates #11635
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Request ID generation appears prominently in some services cumulative
allocation rate, and while this does not eradicate this issue (the API
still makes UUID objects), it does improve the overhead of this API and
reduce the amount of garbage that it produces.
Updates tailscale/corp#18266
Updates tailscale/corp#19054
Signed-off-by: James Tucker <james@tailscale.com>
This still generates github.com/google/uuid UUID objects, but does so
using a ChaCha8 CSPRNG from the stdlib rand/v2 package. The public API
is backed by a sync.Pool to provide good performance in highly
concurrent operation.
Under high load the read API produces a lot of extra garbage and
overhead by way of temporaries and syscalls. This implementation reduces
both to minimal levels, and avoids any long held global lock by
utilizing sync.Pool.
Updates tailscale/corp#18266
Updates tailscale/corp#19054
Signed-off-by: James Tucker <james@tailscale.com>
This removes a potentially increased boot delay for certain boot
topologies where they block on ExecStartPre that may have socket
activation dependencies on other system services (such as
systemd-resolved and NetworkManager).
Also rename cleanup to clean up in affected/immediately nearby places
per code review commentary.
Fixes#11599
Signed-off-by: James Tucker <james@tailscale.com>
Package winenv provides information about the current Windows environment.
This includes details such as whether the device is a server or workstation,
and if it is AD domain-joined, MDM-registered, or neither.
Updates tailscale/corp#18342
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Also capitalises the start of all ShortHelp, allows subcommands to be hidden
with a "HIDDEN: " prefix in their ShortHelp, and adds a TS_DUMP_HELP envknob
to look at all --help messages together.
Fixes#11664
Signed-off-by: Paul Scott <paul@tailscale.com>
Buffer.Write has the exact same signature of io.Writer.Write.
The latter requires that implementations to never retain
the provided input buffer, which is an expectation that most
users will have when they see a Write signature.
The current behavior of Buffer.Write where it does retain
the input buffer is a risky precedent to set.
Switch the behavior to match io.Writer.Write.
There are only two implementations of Buffer in existence:
* logtail.memBuffer
* filch.Filch
The former can be fixed by cloning the input to Write.
This will cause an extra allocation in every Write,
but we can fix that will pooling on the caller side
in a follow-up PR.
The latter only passes the input to os.File.Write,
which does respect the io.Writer.Write requirements.
Updates #cleanup
Updates tailscale/corp#18514
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Updates ENG-2776
Updates the .admx and .adml files to include the new ManagedByOrganizationName, ManagedByCaption and ManagedByURL system policies, added in Tailscale v1.62 for Windows.
Co-authored-by: Andrea Gottardo <andrea@gottardo.me>
Signed-off-by: Nick Khyl <nickk@tailscale.com>
The derphttp.Client mutex is held during connects (for up to 10
seconds) so this LocalAddr method (blocking on said mutex) could also
block for up to 10 seconds, causing a pileup upstream in
magicsock/wgengine and ultimately a watchdog timeout resulting in a
crash.
Updates #11519
Change-Id: Idd1d94ee00966be1b901f6899d8b9492f18add0f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And add a test.
Regression from a5e1f7d703Fixestailscale/corp#19036
Change-Id: If90984049af0a4820c96e1f77ddf2fce8cb3043f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
cmd/tailscale/cli: respect $KUBECONFIG
* `$KUBECONFIG` is a `$PATH`-like: it defines a *list*.
`tailscale config kubeconfig` works like the rest of the
ecosystem so that if $KUBECONFIG is set it will write to the first existant file in the list, if none exist then
the final entry in the list.
* if `$KUBECONFIG` is an empty string, the old logic takes over.
Notes:
* The logic for file detection is inlined based on what `kind` does.
Technically it's a race condition, since the file could be removed/added
in between the processing steps, but the fallout shouldn't be too bad.
https://github.com/kubernetes-sigs/kind/blob/v0.23.0-alpha/pkg/cluster/internal/kubeconfig/internal/kubeconfig/paths.go
* The sandboxed (App Store) variant relies on a specific temporary
entitlement to access the ~/.kube/config file.
The entitlement is only granted to specific files, and so is not
applicable to paths supplied by the user at runtime.
While there may be other ways to achieve this access to arbitrary
kubeconfig files, it's out of scope for now.
Updates #11645
Signed-off-by: Chloé Vulquin <code@toast.bunkerlabs.net>
After:
bradfitz@book1pro tailscale.com % ./tool/go test -c ./cmd/tailscale/cli
bradfitz@book1pro tailscale.com % ./cli.test
bradfitz@book1pro tailscale.com %
Before:
bradfitz@book1pro tailscale.com % ./tool/go test -c ./cmd/tailscale/cli
bradfitz@book1pro tailscale.com % ./cli.test
Warning: funnel=on for foo.test.ts.net:443, but no serve config
run: `tailscale serve --help` to see how to configure handlers
Warning: funnel=on for foo.test.ts.net:443, but no serve config
run: `tailscale serve --help` to see how to configure handlers
USAGE
funnel <serve-port> {on|off}
funnel status [--json]
Funnel allows you to publish a 'tailscale serve'
server publicly, open to the entire internet.
Turning off Funnel only turns off serving to the internet.
It does not affect serving to your tailnet.
SUBCOMMANDS
status show current serve/funnel status
error: path must be absolute
error: invalid TCP source "localhost:5432": missing port in address
error: invalid TCP source "tcp://somehost:5432"
must be one of: localhost or 127.0.0.1
tcp://somehost:5432error: invalid TCP source "tcp://somehost:0"
must be one of: localhost or 127.0.0.1
tcp://somehost:0error: invalid TCP source "tcp://somehost:65536"
must be one of: localhost or 127.0.0.1
tcp://somehost:65536error: path must be absolute
error: cannot serve web; already serving TCP
You don't have permission to enable this feature.
This also moves the color handling up to a generic spot so it's
not just one subcommand doing it itself. See
https://github.com/tailscale/tailscale/issues/11626#issuecomment-2041795129Fixes#11643
Updates #11626
Change-Id: I3a49e659dcbce491f4a2cb784be20bab53f72303
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
- Wrap each prober function into a probe class that allows associating
metric labels and custom metrics with a given probe;
- Make sure all existing probe classes set a `class` metric label;
- Move bandwidth probe size from being a metric label to a separate
gauge metric; this will make it possible to use it to calculate
average used bandwidth using a PromQL query;
- Also export transfer time for the bandwidth prober (more accurate than
the total probe time, since it excludes connection establishment
time).
Updates tailscale/corp#17912
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
At least in the case of dialing a Tailscale IP.
Updates #4529
Change-Id: I9fd667d088a14aec4a56e23aabc2b1ffddafa3fe
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is primarily for GUIs, so they don't need to remember the most
recently used exit node themselves.
This adds some CLI commands, but they're disabled and behind the WIP
envknob, as we need to consider naming (on/off is ambiguous with
running an exit node, etc) as well as automatic exit node selection in
the future. For now the CLI commands are effectively developer debug
things to test the LocalAPI.
Updates tailscale/corp#18724
Change-Id: I9a32b00e3ffbf5b29bfdcad996a4296b5e37be7e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was used when we only supported subnet routers on linux
and would nil out the SubnetRoutes slice as no other router
worked with it, but now we support subnet routers on ~all platforms.
The field it was setting to nil is now only used for network logging
and nowhere else, so keep the field but drop the SubnetRouterWrapper
as it's not useful.
Updates #cleanup
Change-Id: Id03f9b6ec33e47ad643e7b66e07911945f25db79
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Updates #7946
[@bradfitz fixed up version of #8417]
Change-Id: I1dbf6fa8d525b25c0d7ad5c559a7f937c3cd142a
Signed-off-by: alexelisenko <39712468+alexelisenko@users.noreply.github.com>
Signed-off-by: Alex Paguis <alex@windscribe.com>
This names the func() that Once-unlocked LocalBackend.mu. It does so
both for docs and because it can then have a method: Unlock, for the
few points that need to explicitly unlock early (the cause of all this
mess). This makes those ugly points easy to find, and also can then
make them stricter, panicking if the mutex is already unlocked. So a
normal call to the func just once-releases the mutex, returning false
if it's already done, but the Unlock method is the strict one.
Then this uses it more, so most the b.mu.Unlock calls remaining are
simple cases and usually defers.
Updates #11649
Change-Id: Ia070db66c54a55e59d2f76fdc26316abf0dd4627
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
A number of methods in LocalBackend (with suffixed "LockedOnEntry")
require b.mu be held but unlock it on the way out. That's asymmetric
and atypical and error prone.
This adds a helper method to LocalBackend that locks the mutex and
returns a sync.OnceFunc that unlocks the mutex. Then we pass around
that unlocker func down the chain to make it explicit (and somewhat
type check the passing of ownership) but also let the caller defer
unlock it, in the case of errors/panics that happen before the callee
gets around to calling the unlock.
This revealed a latent bug in LocalBackend.DeleteProfile which double
unlocked the mutex.
Updates #11649
Change-Id: I002f77567973bd77b8906bfa4ec9a2049b89836a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The output was changing randomly per run, due to range over a map.
Then some misc style tweaks I noticed while debugging.
Fixes#11629
Change-Id: I67aef0e68566994e5744d4828002f6eb70810ee1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The netcheck package and the magicksock package coordinate via the
health package, but both sides have time based heuristics through
indirect dependencies. These were misaligned, so the implemented
heuristic aimed at reducing DERP moves while there is active traffic
were non-operational about 3/5ths of the time.
It is problematic to setup a good test for this integration presently,
so instead I added comment breadcrumbs along with the initial fix.
Updates #8603
Signed-off-by: James Tucker <james@tailscale.com>
This change makes the normalizeShareName function public, so it can be
used for validation in control.
Updates tailscale/corp#16827
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
And make NewMultiLabelMap panic earlier (at construction time)
if the comparable struct type T violates the documented rules,
rather than panicking at Add time.
Updates #cleanup
Change-Id: Ib1a03babdd501b8d699c4f18b1097a56c916c6d5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Only on Gokrazy, set sysctls to enable IP forwarding so subnet routing
and advertised exit node works.
Fixes#11405
Signed-off-by: Joonas Kuorilehto <joneskoo@derbian.fi>
There are no mutations to the input,
so we can support both ~string and ~[]byte just fine.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This change switches the api to /drive, rather than the previous /tailfs
as well as updates the log lines to reflect the new value. It also
cleans up some existing tailfs references.
Updates tailscale/corp#16827
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This allows clients to avoid establishing their VPN multiple times when
both routes and DNS are changing in rapid succession.
Updates tailscale/corp#18928
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Specifying a smaller window size during compression
provides a knob to tweak the tradeoff between memory usage
and the compression ratio.
Updates tailscale/corp#18514
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
So that we can e.g. check TLS on multiple ports for a given IP.
Updates tailscale/corp#16367
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I81d840a4c88138de1cbb2032b917741c009470e6
This allows us to check all IP addresses (and address families) for a
given DNS hostname while dynamically discovering new IPs and removing
old ones as they're no longer valid.
Also add a testable example that demonstrates how to use it.
Alternative to #11610
Updates tailscale/corp#16367
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I6d6f39bafc30e6dfcf6708185d09faee2a374599
This change updates all tailfs functions and the majority of the tailfs
variables to use the new drive naming.
Updates tailscale/corp#16827
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
I originally came to update this to match the documented behavior, but
the code is deliberately avoiding this behavior currently, making it
hard to decide how to update this. For now just align the documentation
to the behavior.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
This change updates the tailfs file and package names to their new
naming convention.
Updates #tailscale/corp#16827
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Refactor the interaction between caller/library when establishing the
HTTP to HTTPS redirects by moving the call to http.Serve into safeweb.
This makes linting for other uses of http.Serve easier without having to
account for false positives created by the old interface.
Updates https://github.com/tailscale/corp/issues/8027
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
We now allow some more ICMP errors to flow, specifically:
- ICMP parameter problem in both IPv4 and IPv6 (corrupt headers)
- ICMP Packet Too Big (for IPv6 PMTU)
Updates #311
Updates #8102
Updates #11002
Signed-off-by: James Tucker <james@tailscale.com>
MSS clamping for nftables was mostly not ran due to to an earlier rule in the FORWARD chain issuing accept verdict.
This commit places the clamping rule into a chain of its own to ensure that it gets ran.
Updates tailscale/tailscale#11002
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This is based on empirical testing using actual logs data.
FastestCompression only incurs a marginal <1% compression ratio hit
for a 2.25x reduction in memory use for small payloads
(which are common if log uploads happen at a decently high frequency).
The memory savings for large payloads is much lower
(less than 1.1x reduction).
LowMemory only incurs a marginal <5% hit on performance
for a 1.6-2.0x reduction in memory use for small or large payloads.
The memory gains for both settings justifies the loss of benefits,
which are arguably minimal.
tailscale/corp#18514
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We're tracking down a new instance of memory usage, and excessive memory usage
from sockstats is definitely not going to help with debugging, so disable it by
default on mobile.
Updates tailscale/corp#18514
Signed-off-by: James Tucker <james@tailscale.com>
When both muxes match, and one of them is a wildcard "/" pattern (which
is common in browser muxes), choose the more specific pattern.
If both are non-wildcard matches, there is a pattern overlap, so return
an error.
Updates https://github.com/tailscale/corp/issues/8027
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
We have hosts that support IPv6, but not IPv6 firewall configuration
in iptables mode.
We also have hosts that have some support for IPv6 firewall
configuration in iptables mode, but do not have iptables filter table.
We should:
- configure ip rules for all hosts that support IPv6
- only configure firewall rules in iptables mode if the host
has iptables filter table.
Updates tailscale/tailscale#11540
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Allow the use of inline styles with safeweb via an opt-in configuration
item. This will append `style-src "self" "unsafe-inline"` to the default
CSP. The `style-src` directive will be used in lieu of the fallback
`default-src "self"` directive.
Updates tailscale/corp#8027
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Some of our labels contain UTF-8 and get mojibaked in the browser
right now.
Updates tailscale/corp#18687
Change-Id: I6069cffd6cc8813df415f06bb308bc2fc3ab65c4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The initial control client request can get stuck in the event that a
connection is established but then lost part way through, without any
ICMP or RST. Ensure that the control client will be restarted by timing
out that initial request as well.
Fixes#11542
Signed-off-by: James Tucker <james@tailscale.com>
* cmd/k8s-nameserver,k8s-operator: add a nameserver that can resolve ts.net DNS names in cluster.
Adds a simple nameserver that can respond to A record queries for ts.net DNS names.
It can respond to queries from in-memory records, populated from a ConfigMap
mounted at /config. It dynamically updates its records as the ConfigMap
contents changes.
It will respond with NXDOMAIN to queries for any other record types
(AAAA to be implemented in the future).
It can respond to queries over UDP or TCP. It runs a miekg/dns
DNS server with a single registered handler for ts.net domain names.
Queries for other domain names will be refused.
The intended use of this is:
1) to allow non-tailnet cluster workloads to talk to HTTPS tailnet
services exposed via Tailscale operator egress over HTTPS
2) to allow non-tailnet cluster workloads to talk to workloads in
the same cluster that have been exposed to tailnet over their
MagicDNS names but on their cluster IPs.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator/deploy/crds,k8s-operator: add DNSConfig CustomResource Definition
DNSConfig CRD can be used to configure
the operator to deploy kube nameserver (./cmd/k8s-nameserver) to cluster.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator,k8s-operator: optionally reconcile nameserver resources
Adds a new reconciler that reconciles DNSConfig resources.
If a DNSConfig is deployed to cluster,
the reconciler creates kube nameserver resources.
This reconciler is only responsible for creating
nameserver resources and not for populating nameserver's records.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/{k8s-operator,k8s-nameserver}: generate DNSConfig CRD for charts, append to static manifests
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
---------
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Updates #cleanup
Change the return type of the safeweb.RedirectHTTP method to a handler
that can be passed directly to http.Serve without any http.HandlerFunc
wrapping necessary.
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
This CONNECT client doesn't match what Go's net/http.Transport does
(making the two values match). This makes it match.
This is all pretty unspecified but most clients & doc examples show
these matching. And some proxy implementations (such as Zscaler) care.
Updates tailscale/corp#18716
Change-Id: I135c5facbbcec9276faa772facbde1bb0feb2d26
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates https://github.com/tailscale/corp/issues/8027
Safeweb is a wrapper around http.Server & tsnet that encodes some
application security defaults.
Safeweb asks developers to split their HTTP routes into two
http.ServeMuxs for serving browser and API-facing endpoints
repsectively. It then wraps these HTTP routes with the
context-appropriate security controls.
safeweb.Server#Serve will serve the HTTP muxes over the provided
listener. Caller are responsible for creating and tearing down their
application's listeners. Applications being served over HTTPS that wish
to implement HTTP redirects can use the Server#HTTPRedirect handler to
do so.
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
This allows sending multiple files via Taildrop in one request.
Progress is tracked via ipn.Notify.
Updates tailscale/corp#18202
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This allows sending multiple files via Taildrop in one request.
Progress is tracked via ipn.Notify.
Updates tailscale/corp#18202
Signed-off-by: Percy Wegmann <percy@tailscale.com>
For example, if we get a 404 when downloading a file, we'll report access.
Also, to reduce verbosty of logs, this elides 0 length files.
Updates tailscale/corp#17818
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This change introduces some basic logging into the access and share
pathways for tailfs.
Updates tailscale/corp#17818
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Rather than pass around a scratch buffer, put it on the Logger.
This is a baby step towards removing the background uploading
goroutine and starting it as needed.
Updates tailscale/corp#18514 (insofar as it led me to look at this code)
Change-Id: I6fd94581c28bde40fdb9fca788eb9590bcedae1b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Including the double quotes (`"`) around the value made it appear like the helm chart should expect a string value for `installCRDs`.
Signed-off-by: Chris Milson-Tokunaga <chris.w.milson@gmail.com>
This implementation uses less memory than tempfork/device,
which helps avoid OOM conditions in the iOS VPN extension when
switching to a Tailnet with ExitNode routing enabled.
Updates tailscale/corp#18514
Signed-off-by: Percy Wegmann <percy@tailscale.com>
There's a vulnerability https://pkg.go.dev/vuln/GO-2024-2659 that
govulncheck flags, even though it's only reachable from tests and
cmd/sync-containers and cannot be exploited there.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
First we had Capabilities []string. Then
https://tailscale.com/blog/acl-grants (#4217) brought CapMap, a
superset of Capabilities. Except we never really finished the
transition inside the codebase to go all-in on CapMap. This does so.
Notably, this coverts Capabilities on the wire early to CapMap
internally so the code can only deal in CapMap, even against an old
control server.
In the process, this removes PeerChange.Capabilities support, which no
known control plane sent anyway. They can and should use
PeerChange.CapMap instead.
Updates #11508
Updates #4217
Change-Id: I872074e226b873f9a578d9603897b831d50b25d9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
From a problem we hit with how badger registers expvars; it broke
trunkd's exported metrics.
Updates tailscale/corp#1297
Change-Id: I42e1552e25f734c6f521b6e993d57a82849464b2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When node attributes were super rare, the O(n) slice scans looking for
node attributes was more acceptable. But now more code and more users
are using increasingly more node attributes. Time to make it a map.
Noticed while working on tailscale/corp#17879
Updates #cleanup
Change-Id: Ic17c80341f418421002fbceb47490729048756d2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In the recent 20e9f3369 we made HealthChangeRequest machine requests
include a NodeKey, as it was the oddball machine request that didn't
include one. Unfortunately, that code was sometimes being called (at
least in some of our integration tests) without a node key due to its
registration with health.RegisterWatcher(direct.ReportHealthChange).
Fortunately tests in corp caught this before we cut a release. It's
possible this only affects this particular integration test's
environment, but still worth fixing.
Updates tailscale/corp#1297
Change-Id: I84046779955105763dc1be5121c69fec3c138672
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Use the zstdframe package where sensible instead of plumbing
around our own zstd.Encoder just for stateless operations.
This causes logtail to have a dependency on zstd,
but that's arguably okay since zstd support is implicit
to the protocol between a client and the logging service.
Also, virtually every caller to logger.NewLogger was
manually setting up a zstd.Encoder anyways,
meaning that zstd was functionally always a dependency.
Updates #cleanup
Updates tailscale/corp#18514
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The Go zstd package is not friendly for stateless zstd compression.
Passing around multiple zstd.Encoder just for stateless compression
is a waste of memory since the memory is never freed and seldom
used if no compression operations are happening.
For performance, we pool the relevant Encoder/Decoder
with the specific options set.
Functionally, this package is a wrapper over the Go zstd package
with a more ergonomic API for stateless operations.
This package can be used to cleanup various pre-existing zstd.Encoder
pools or one-off handlers spread throughout our codebases.
Performance:
BenchmarkEncode/Best 1690 610926 ns/op 25.78 MB/s 1 B/op 0 allocs/op
zstd_test.go:137: memory: 50.336 MiB
zstd_test.go:138: ratio: 3.269x
BenchmarkEncode/Better 10000 100939 ns/op 156.04 MB/s 0 B/op 0 allocs/op
zstd_test.go:137: memory: 20.399 MiB
zstd_test.go:138: ratio: 3.131x
BenchmarkEncode/Default 15775 74976 ns/op 210.08 MB/s 105 B/op 0 allocs/op
zstd_test.go:137: memory: 1.586 MiB
zstd_test.go:138: ratio: 3.064x
BenchmarkEncode/Fastest 23222 53977 ns/op 291.81 MB/s 26 B/op 0 allocs/op
zstd_test.go:137: memory: 599.458 KiB
zstd_test.go:138: ratio: 2.898x
BenchmarkEncode/FastestLowMemory 23361 50789 ns/op 310.13 MB/s 15 B/op 0 allocs/op
zstd_test.go:137: memory: 334.458 KiB
zstd_test.go:138: ratio: 2.898x
BenchmarkEncode/FastestNoChecksum 23086 50253 ns/op 313.44 MB/s 26 B/op 0 allocs/op
zstd_test.go:137: memory: 599.458 KiB
zstd_test.go:138: ratio: 2.900x
BenchmarkDecode/Checksum 70794 17082 ns/op 300.96 MB/s 4 B/op 0 allocs/op
zstd_test.go:163: memory: 316.438 KiB
BenchmarkDecode/NoChecksum 74935 15990 ns/op 321.51 MB/s 4 B/op 0 allocs/op
zstd_test.go:163: memory: 316.438 KiB
BenchmarkDecode/LowMemory 71043 16739 ns/op 307.13 MB/s 0 B/op 0 allocs/op
zstd_test.go:163: memory: 79.347 KiB
We can see that the options are taking effect where compression ratio improves
with higher levels and compression speed diminishes.
We can also see that LowMemory takes effect where the pooled coder object
references less memory than other cases.
We can see that the pooling is taking effect as there are 0 amortized allocations.
Additional performance:
BenchmarkEncodeParallel/zstd-24 1857 619264 ns/op 1796 B/op 49 allocs/op
BenchmarkEncodeParallel/zstdframe-24 1954 532023 ns/op 4293 B/op 49 allocs/op
BenchmarkDecodeParallel/zstd-24 5288 197281 ns/op 2516 B/op 49 allocs/op
BenchmarkDecodeParallel/zstdframe-24 6441 196254 ns/op 2513 B/op 49 allocs/op
In concurrent usage, handling the pooling in this package
has a marginal benefit over the zstd package,
which relies on a Go channel as the pooling mechanism.
In particular, coders can be freed by the GC when not in use.
Coders can be shared throughout the program if they use this package
instead of multiple independent pools doing the same thing.
The allocations are unrelated to pooling as they're caused by the spawning of goroutines.
Updates #cleanup
Updates tailscale/corp#18514
Updates tailscale/corp#17653
Updates tailscale/corp#18005
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This can be used to reload a value periodically, whether from disk or
another source, while handling jitter and graceful shutdown.
Updates tailscale/corp#1297
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Iee2b4385c9abae59805f642a7308837877cb5b3f
This allows the UI to distinguish between 'no shares' versus
'not being notified about shares'.
Updates ENG-2843
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Instead of just checking if a peer capmap is nil, compare the previous
state peer capmap with the new peer capmap.
Updates tailscale/corp#17516
Signed-off-by: Claire Wang <claire@tailscale.com>
To mimic sync.Map.Swap, sync/atomic.Value.Swap, etc.
Updates tailscale/corp#1297
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If7627da1bce8b552873b21d7e5ebb98904e9a650
Fixes tailscale/corp#18441
For a few days, IsMacAppStore() has been returning `false` on App Store builds (IPN-macOS target in Xcode).
I regressed this in #11369 by introducing logic to detect the sandbox by checking for the APP_SANDBOX_CONTAINER_ID environment variable. I thought that was a more robust approach instead of checking the name of the executable. However, it appears that on recent macOS versions this environment variable is no longer getting set, so we should go back to the previous logic that checks for the executable path, or HOME containing references to macsys.
This PR also adds additional checks to the logic by also checking XPC_SERVICE_NAME in addition to HOME where possible. That environment variable is set inside the network extension, either macos or macsys and is good to look at if for any reason HOME is not set.
Mostly inconsequential minor fixes for consistency. A couple of changes
to actual JSON examples, but all still very readable, so I think it's
fine.
Updates #cleanup
Signed-off-by: Will Norris <will@tailscale.com>
Fix a bug where all proxies got configured with --accept-routes set to true.
The bug was introduced in https://github.com/tailscale/tailscale/pull/11238.
Updates#cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
In control there are conditions where the leaf functions are not being
optimized away (i.e. At is not inlined), resulting in undesirable time
spent copying during SliceContains. This optimization is likely
irrelevant to simpler code or smaller structures.
Updates #optimization
Signed-off-by: James Tucker <james@tailscale.com>
Enable the web client over 100.100.100.100 by default. Accepting traffic
from [tailnet IP]:5252 still requires setting the `webclient` user pref.
Updates https://github.com/tailscale/tailscale/issues/10261
Signed-off-by: Mario Minardi <mario@tailscale.com>
This was originally built for testing node expiration flows, but is also
useful for customers to force device re-auth without actually deleting
the device from the tailnet.
Updates tailscale/corp#18408
Signed-off-by: Will Norris <will@tailscale.com>
Add a disable-web-client node attribute and add handling for disabling
the web client when this node attribute is set.
Updates https://github.com/tailscale/tailscale/issues/10261
Signed-off-by: Mario Minardi <mario@tailscale.com>
This PR fixes a panic that I saw in the mac app where
parsing the env file fails but we don't get to see the
error due to the panic of using f.Name()
Fixes#11425
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Updates ENG-2848
We can safely disable the App Sandbox for our macsys GUI, allowing us to use `tailscale ssh` and do a few other things that we've wanted to do for a while. This PR:
- allows Tailscale SSH to be used from the macsys GUI binary when called from a CLI
- tweaks the detection of client variants in prop.go, with new functions `IsMacSys()`, `IsMacSysApp()` and `IsMacAppSandboxEnabled()`
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
When a user deletes the last cluster/user/context from their
kubeconfig via 'kubectl delete-[cluster|user|context] command,
kubectx sets the relevant field in kubeconfig to 'null'.
This was breaking our conversion logic that was assuming that the field
is either non-existant or is an array.
Updates tailscale/corp#18320
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
I was running all tests while preparing a recent stable release, and
this was failing because my computer is connected to a fairly large
tailnet.
```
--- FAIL: TestGetRouteTable (0.01s)
routetable_linux_test.go:32: expected at least one default route;
...
```
```
$ ip route show table 52 | wc -l
1051
```
Updates #cleanup
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
If the client uses the default Tailscale control URL, validate that all
PopBrowserURLs are under tailscale.com or *.tailscale.com. This reduces
the risk of a compromised control plane opening phishing pages for
example.
The client trusts control for many other things, but this is one easy
way to reduce that trust a bit.
Fixes#11393
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
According to
https://learn.microsoft.com/en-us/windows/win32/msi/standard-installer-command-line-options#promptrestart,
`/promptrestart` is ignored with `/quiet` is set, so msiexec.exe can
sometimes silently trigger a reboot. The best we can do to reduce
unexpected disruption is to just prevent restarts, until the user
chooses to do it. Restarts aren't normally needed for Tailscale updates,
but there seem to be some situations where it's triggered.
Updates #18254
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This fixes a bug that was introduced in #11258 where the handling of the
per-client limit didn't properly account for the fact that the gVisor
TCP forwarder will return 'true' to indicate that it's handled a
duplicate SYN packet, but not launch the handler goroutine.
In such a case, we neither decremented our per-client limit in the
wrapper function, nor did we do so in the handler function, leading to
our per-client limit table slowly filling up without bound.
Fix this by doing the same duplicate-tracking logic that the TCP
forwarder does so we can detect such cases and appropriately decrement
our in-flight counter.
Updates tailscale/corp#12184
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ib6011a71d382a10d68c0802593f34b8153d06892
To force the problem in its worst case scenario before fixing it.
Updates tailscale/corp#17859
Change-Id: I2c8b8e5f15c7801e1ab093feeafac52ec175a763
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There are container environments such as GitHub codespaces that have
partial IPv6 support - routing support is enabled at the kernel level,
but lacking IPv6 filter support in the iptables module.
In the specific example of the codespaces environment, this also has
pre-existing legacy iptables rules in the IPv4 tables, as such the
nascent firewall mode detection will always pick iptables.
We would previously fault trying to install rules to the filter table,
this catches that condition earlier, and disables IPv6 support under
these conditions.
Updates #5621
Updates #11344
Updates #11354
Signed-off-by: James Tucker <james@tailscale.com>
build_docker, update-flake: cleanup and apply shellcheck fixes
Was editing this file to match my needs while shellcheck warnings
bugged me out.
REV isn't getting used anywhere. Better remove it.
Updates #cleanup
Signed-off-by: Panchajanya1999 <kernel@panchajanya.dev>
Signed-off-by: James Tucker <james@tailscale.com>
- Updates API to support renaming TailFS shares.
- Adds a CLI rename subcommand for renaming a share.
- Renames the CLI subcommand 'add' to 'set' to make it clear that
this is an add or update.
- Adds a unit test for TailFS in ipnlocal
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Previously, the configuration of which folders to share persisted across
profile changes. Now, it is tied to the user's profile.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This pretty much always results in an outage because peers won't
discover our new home region and thus won't be able to establish
connectivity.
Updates tailscale/corp#18095
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ic0d09133f198b528dd40c6383b16d7663d9d37a7
Synology requires version numbers are within int32 range. This
change updates the version logic to keep things closer within the
range, and errors on building when the range is exceeded.
Updates #cleanup
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
bump version for adding NodeAttrSuggestExitNode
remove extra s from NodeAttrSuggestExitNode
Updates tailscale/corp#17516
Signed-off-by: Claire Wang <claire@tailscale.com>
Run yarn-deduplicate on yarn.lock to dedupe packages. This is being done
to reduce the number of redundant packages fetched by yarn when existing
versions in the lockfile satisfy the version dependency we need.
See https://github.com/scinos/yarn-deduplicate for details on the tool
used to perform this deduplication.
Updates #cleanup
Signed-off-by: Mario Minardi <mario@tailscale.com>
So we can use it in trunkd to quiet down the logs there.
Updates #5563
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie3177dc33f5ad103db832aab5a3e0e4f128f973f
This test could hang because the subprocess was blocked on writing to
the stdout pipe if we find the address we're looking for early in the
output.
Updates #cleanup
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I68d82c22a5d782098187ae6d8577e43063b72573
The `stack.PacketBufferPtr` type no longer exists; replace it with
`*stack.PacketBuffer` instead.
Updates #8043
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ib56ceff09166a042aa3d9b80f50b2aa2d34b3683
In case we want to change the format to something opaque later.
Updates tailscale/corp#2549
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie2eac8b885b694be607e9d5101d24b650026d89c
This eliminates unnecessary map.Clone() calls and also eliminates
repetitive notifications about the same set of shares.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Updates tailscale/corp#17859
Provides a local API endpoint to be called from the GUI to inform the backend when the client menu is opened or closed.
cc @bradfitz
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
This is a temporary solution to at least omit Mullvad exit nodes
from the list of TailFS peers. Once we can identify peers that are
actually sharing via TailFS, we can remove this, but for alpha it'll
be sufficient to just omit Mullvad.
Updates tailscale/corp#17766
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Moving logic that manipulates a ServeConfig into recievers on the
ServeConfig in the ipn package. This is setup work to allow the
web client and cli to both utilize these shared functions to edit
the serve config.
Any logic specific to flag parsing or validation is left untouched
in the cli command. The web client will similarly manage its
validation of user's requested changes. If validation logic becomes
similar-enough, we can make a serve util for shared functionality,
which likely does not make sense in ipn.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Since link-local addresses are definitionally more likely to be a direct
(lower-latency, more reliable) connection than a non-link-local private
address, give those a bit of a boost when selecting endpoints.
Updates #8097
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I93fdeb07de55ba39ba5fcee0834b579ca05c2a4e
In preparation for changes to allow configuration of serve/funnel
from the web client, this commit moves some functionality that will
be shared between the CLI and web client to the ipn package's
serve.go file, where some other util funcs are already defined.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Update docs for static Tailscale deployments on kube
to always use firewall mode autodection when in non-userspace.
Also add a note about running multiple replicas and a few suggestions how folks could do that.
Updates#cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Anton Tolchanov <1687799+knyar@users.noreply.github.com>
When serving TailFS shares, tailscaled executes another tailscaled to act as a
file server. It attempts to execute this child process as an unprivileged user
using sudo -u. This is important to avoid accessing files as root, which would
result in potential privilege escalation.
Previously, tailscaled assumed that it was running as someone who can sudo -u,
and would fail if it was unable to sudo -u.
With this commit, if tailscaled is unable to sudo -u as the requested user, and
tailscaled is not running as root, then tailscaled executes the the file server
process under the same identity that ran tailscaled, since this is already an
unprivileged identity.
In the unlikely event that tailscaled is running as root but is unable to
sudo -u, it will refuse to run the child file server process in order to avoid
privilege escalation.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
The package info output can list multiple package versions, and not in
descending order. Find the newest version in the output, instead of the
first one.
Fixes#11309
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Ensure that the latest DNATNonTailscaleTraffic rule
gets inserted on top of any pre-existing rules.
Updates tailscale/tailscale#11281
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This allows the Mac application to regain access to restricted
folders after restarts.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This allows the sandboxed Mac application to store security-
scoped URL bookmarks in order to maintain access to restricted
folders across restarts.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This was just added in 69f4b459 which doesn't yet use it. This still
doesn't yet use it. It just pushes it down deeper into magicsock where
it'll used later.
Updates #7617
Change-Id: If2f8fd380af150ffc763489e1ff4f8ca2899fac6
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We used a HandleSet before when we didn't have a unique handle. But a
sessionID is a unique handle, so use that instead. Then that replaces
the other map we had.
And now we'll have a way to look up an IPN session by sessionID for
later.
Updates tailscale/corp#17859
Change-Id: I5f647f367563ec8783c643e49f93817b341d9064
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This fixes a regression introduced with 993acf4 and released in
v1.60.0.
The regression caused us to intercept all userspace traffic to port
8080 which prevented users from exposing their own services to their
tailnet at port 8080.
Now, we only intercept traffic to port 8080 if it's bound for
100.100.100.100 or fd7a:115c:a1e0::53.
Fixes#11283
Signed-off-by: Percy Wegmann <percy@tailscale.com>
(cherry picked from commit 17cd0626f3)
Starting in Vite 5, Vite now issues a deprecation warning when using
a CJS-based Vite config file. This commit fixes it by adding the
`"type": "module"` to our package.json to opt our files into ESM module
behaviours.
Fixes #cleanup
Signed-off-by: Ross Zurowski <ross@rosszurowski.com>
This adds a method to wgengine.Engine and plumbed down into magicsock
to add a way to get a type-safe Tailscale-safe wrapper around a
wireguard-go device.Peer that only exposes methods that are safe for
Tailscale to use internally.
It also removes HandshakeAttempts from PeerStatusLite that was just
added as it wasn't needed yet and is now accessible ala cart as needed
from the Peer type accessor.
None of this is used yet.
Updates #7617
Change-Id: I07be0c4e6679883e6eeddf8dbed7394c9e79c5f4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This server recently had a common ansible applied, which added a
periodic /tmp cleaner, as is needed on other CI machines to deal with
test tempfile leakage. The setting of $HOME to /tmp means that the go
toolchain in there was regularly getting pruned by the tmp cleaner, but
often incompletely, because it was also in use.
Move HOME to a runner owned directory.
Updates #11248
Signed-off-by: James Tucker <james@tailscale.com>
... rather than 1970. Code was using IsZero against the 1970 team
(which isn't a zero value), but fortunately not anywhere that seems to
have mattered.
Updates #cleanup
Change-Id: I708a3f2a9398aaaedc9503678b4a8a311e0e019e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Update typescript to 5.3.3. This is a major bump from the previous
version of 4.8.3. This also requires adding newer versions of
@typescript-eslint/eslint-plugin and @typescript-eslint/parser to our
resolutions as eslint-config-react-app pulls in versions that otherwise
do not support typescript 5.x.
eslint-config-react-app has not been updated in 2 years and is seemingly
abandoned, so we may wish to fork it or move to a different eslint config
in the future.
Updates https://github.com/tailscale/corp/issues/17810
Signed-off-by: Mario Minardi <mario@tailscale.com>
This is a fun one. Right now, when a client is connecting through a
subnet router, here's roughly what happens:
1. The client initiates a connection to an IP address behind a subnet
router, and sends a TCP SYN
2. The subnet router gets the SYN packet from netstack, and after
running through acceptTCP, starts DialContext-ing the destination IP,
without accepting the connection¹
3. The client retransmits the SYN packet a few times while the dial is
in progress, until either...
4. The subnet router successfully establishes a connection to the
destination IP and sends the SYN-ACK back to the client, or...
5. The subnet router times out and sends a RST to the client.
6. If the connection was successful, the client ACKs the SYN-ACK it
received, and traffic starts flowing
As a result, the notification code in forwardTCP never notices when a
new connection attempt is aborted, and it will wait until either the
connection is established, or until the OS-level connection timeout is
reached and it aborts.
To mitigate this, add a per-client limit on how many in-flight TCP
forwarding connections can be in-progress; after this, clients will see
a similar behaviour to the global limit, where new connection attempts
are aborted instead of waiting. This prevents a single misbehaving
client from blocking all other clients of a subnet router by ensuring
that it doesn't starve the global limiter.
Also, bump the global limit again to a higher value.
¹ We can't accept the connection before establishing a connection to the
remote server since otherwise we'd be opening the connection and then
immediately closing it, which breaks a bunch of stuff; see #5503 for
more details.
Updates tailscale/corp#12184
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I76e7008ddd497303d75d473f534e32309c8a5144
This is so that if a backend Service gets created after the Ingress, it gets picked up by the operator.
Updates tailscale/tailscale#11251
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Anton Tolchanov <1687799+knyar@users.noreply.github.com>
Containerboot container created for operator's ingress and egress proxies
are now always configured by passing a configfile to tailscaled
(tailscaled --config <configfile-path>.
It does not run 'tailscale set' or 'tailscale up'.
Upgrading existing setups to this version as well as
downgrading existing setups at this version works.
Updates tailscale/tailscale#10869
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Add logic to autogenerate CRD docs.
.github/workflows/kubemanifests.yaml CI workflow will fail if the doc is out of date with regard to the current CRDs.
Docs can be refreshed by running make kube-generate-all.
Updates tailscale/tailscale#11023
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
On Alpine, we add the tailscale service but fail to call start.
This means that tailscale does not start up until the user reboots the machine.
Fixes#11161
Signed-off-by: Keli Velazquez <keli@tailscale.com>
Not yet used. This is being made available so magicsock/wgengine can
use it to ignore certain sends (UDP + DERP) later on at least mobile,
letting wireguard-go think it's doing its full attempt schedule, but
we can cut it short conditionally based on what we know from the
control plane.
Updates #7617
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: Ia367cf6bd87b2aeedd3c6f4989528acdb6773ca7
Otherwise on OS retransmits, we'd make redundant timers in Go's timer
heap that upon firing just do nothing (well, grab a mutex and check a
map and see that there's nothing to do).
Updates #cleanup
Change-Id: Id30b8b2d629cf9c7f8133a3f7eca5dc79e81facb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
No need to hold wgLock while using the device to LookupPeer;
that has its own mutex already.
Updates #cleanup
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: Ib56049fcc7163cf5a2c2e7e12916f07b4f9d67cb
It's unnecessary. Returning an array value is already a copy.
Updates #cleanup
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: If7f350b61003ea08f16a531b7b4e8ae483617939
When reverse path filtering is in strict mode on Linux, using an exit
node blocks all network connectivity. This change adds a warning about
this to `tailscale status` and the logs.
Example in `tailscale status`:
```
- not connected to home DERP region 22
- The following issues on your machine will likely make usage of exit nodes impossible: [interface "eth0" has strict reverse-path filtering enabled], please set rp_filter=2 instead of rp_filter=1; see https://github.com/tailscale/tailscale/issues/3310
```
Example in the logs:
```
2024/02/21 21:17:07 health("overall"): error: multiple errors:
not in map poll
The following issues on your machine will likely make usage of exit nodes impossible: [interface "eth0" has strict reverse-path filtering enabled], please set rp_filter=2 instead of rp_filter=1; see https://github.com/tailscale/tailscale/issues/3310
```
Updates #3310
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Tailscaled becomes inoperative if the Tailscale Tunnel wintun adapter is abruptly removed.
wireguard-go closes the device in case of a read error, but tailscaled keeps running.
This adds detection of a closed WireGuard device, triggering a graceful shutdown of tailscaled.
It is then restarted by the tailscaled watchdog service process.
Fixes#11222
Signed-off-by: Nick Khyl <nickk@tailscale.com>
The WinTun adapter may have been removed by the time we're closing
the dns.windowsManager, and its associated interface registry key might
also have been deleted. We shouldn't use winutil.OpenKeyWait and wait
for the interface key to appear when performing a cleanup as a part of
the windowsManager shutdown.
Updates #11222
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Starts using peer capabilities to restrict the management client
on a per-view basis. This change also includes a bulky cleanup
of the login-toggle.tsx file, which was getting pretty unwieldy
in its previous form.
Updates tailscale/corp#16695
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This change adds a new apiHandler struct for use from serveAPI
to aid with restricting endpoints to specific peer capabilities.
Updates tailscale/corp#16695
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
- add a clientmetric with a counter of TCP forwarder drops due to the
max attempts;
- fix varz metric types, as they are all counters.
Updates #8210
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Instead of modeling remote WebDAV servers as actual
webdav.FS instances, we now just proxy traffic to them.
This not only simplifies the code, but it also allows
WebDAV locking to work correctly by making sure locks are
handled by the servers that need to (i.e. the ones actually
serving the files).
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
That's already the default. Avoid the overhead of writing it on one
side and reading it on the other to do nothing.
Updates #cleanup (noticed while researching something else)
Change-Id: I449c88a022271afb9be5da876bfaf438fe5d3f58
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If a client socket is remotely lost but the client is not sent an RST in
response to the next request, the socket might sit in RTO for extended
lengths of time, resulting in "no internet" for users. Instead, timeout
after 10s, which will close the underlying socket, recovering from the
situation more promptly.
Updates #10967
Signed-off-by: James Tucker <james@tailscale.com>
I missed a case in the earlier patch, and so we're still sending 15s TCP
keepalive for TLS connections, now adjusted there too.
Updates tailscale/corp#17587
Updates #3363
Signed-off-by: James Tucker <james@tailscale.com>
This appears to be one of the contributors to this CI target regularly
entering a bad state with a partially written toolchain.
Updates #self
Signed-off-by: James Tucker <james@tailscale.com>
We don't need a log line every time defaultRoute is read in the good
case, and we now only log default interface updates that are actually
changes.
Updates #3363
Signed-off-by: James Tucker <james@tailscale.com>
Update vite to 5.1.4, and vitest to 1.3.1 (their latest versions). Also
remove vite-plugin-rewrite-all as this is no longer necessary with vite
5.x and has a dependency on vite 4.x.
Updates https://github.com/tailscale/corp/issues/17715
Signed-off-by: Mario Minardi <mario@tailscale.com>
This adds details on how to configure node attributes to allow
sharing and accessing shares.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
An increasing number of users have very large subnet route
configurations, which can produce very large amounts of log data when
WireGuard is reconfigured. The logs don't contain the actual routes, so
they're largely useless for diagnostics, so we'll just suppress them.
Fixestailscale/corp#17532
Signed-off-by: James Tucker <james@tailscale.com>
Update plugin-react-swc to the latest version (3.6.0) ahead of updating vite to 5.x.
Updates https://github.com/tailscale/corp/issues/17715
Signed-off-by: Mario Minardi <mario@tailscale.com>
Update vite-plugin-svgr to the latest version (4.2.0) ahead of updating
vite to 5.x. This is a major version bump from our previous 3.x, and
requires changing the import paths used for SVGs.
Updates https://github.com/tailscale/corp/issues/17715
Signed-off-by: Mario Minardi <mario@tailscale.com>
The derper sends an in-protocol keepalive every 60-65s, so frequent TCP
keepalives are unnecessary. In this tuning TCP keepalives should never
occur for a DERP client connection, as they will send an L7 keepalive
often enough to always reset the TCP keepalive timer. If however a
connection does not receive an ACK promptly it will now be shutdown,
which happens sooner than it would with a normal TCP keepalive tuning.
This re-tuning reduces the frequency of network traffic from derp to
client, reducing battery cost.
Updates tailscale/corp#17587
Updates #3363
Signed-off-by: James Tucker <james@tailscale.com>
Updates ENG-2133. Adds the ResetToDefaults visibility policy currently only available on macOS, so that the Windows client can read its value.
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
So derpers can check an external URL for whether to permit access
to a certain public key.
Updates tailscale/corp#17693
Change-Id: I8594de58f54a08be3e2dbef8bcd1ff9b728ab297
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This allows coverage from tests that hit multiple packages at once
to be reflected in all those packages' coverage.
Updates #cleanup
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Setting a user timeout will be a more practical tuning knob for a number
of endpoints, this provides a way to set it.
Updates tailscale/corp#17587
Signed-off-by: James Tucker <james@tailscale.com>
So we can probe load balancers by their unique DNS name but without
asking for that cert name.
Updates tailscale/corp#13050
Change-Id: Ie4c0a2f951328df64281ed1602b4e624e3c8cf2e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
From a packet trace we have seen log connections being closed
prematurely by the client, resulting in unnecessary extra TLS setup
traffic.
Updates #3363
Updates tailscale/corp#9230
Updates tailscale/corp#8564
Signed-off-by: James Tucker <james@tailscale.com>
This fixes an infinite loop caused by the configuration of
systemd-resolved on Amazon Linux 2023 and how that interacts with
Tailscale's "direct" mode. We now drop the Tailscale service IP from the
OS's "base configuration" when we detect this configuration.
Updates #7816
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I73a4ea8e65571eb368c7e179f36af2c049a588ee
Adds logic in gocross to detect environment variables and pass the right flags so that the backend can be built with the visionOS SDK.
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Instead of constructing the `ip:port` string ourselves, use
netip.AddrPortFrom which handles IPv6 correctly.
Updates #11164
Signed-off-by: Will Norris <will@tailscale.com>
Small fix to make sure doctor API endpoint returns correctly - I spotted it when checking my tailscaled node and noticed it was handled slightly different compare to the rest
Signed-off-by: San <santrancisco@users.noreply.github.com>
Updates #cleanup
NixOS packages are immutable and attempts to update via our tarball
mechanism will always fail as a result. Instead we now direct users to
update their nix channel or nixpkgs flake input to receive the latest
Tailscale release.
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
This package uses a count-min sketch and a heap to track the top K items
in a stream of data. Tracking a new item and adding a count to an
existing item both require no memory allocations and is at worst
O(log(k)) complexity.
Change-Id: I0553381be3fef2470897e2bd806d43396f2dbb36
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Looking at profiles, we spend a lot of time in winipcfg.LUID.DeleteRoute
looking up the routing table entry for the provided RouteData.
But we already have the row! We previously obtained that data via the full
table dump we did in getInterfaceRoutes. We can make this a lot faster by
hanging onto a reference to the wipipcfg.MibIPforwardRow2 and executing
the delete operation directly on that.
Fixes#11123
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
* tsweb: update ServeMux matching to 1.22.0 syntax
Updates #cleanup
Go 1.22.0 introduced the ability to use more expressive routing patterns
that include HTTP method when constructing ServeMux entries.
Applications that attempted to use these patterns in combination with
the old `tsweb.Debugger` would experience a panic as Go would not permit
the use of matching rules with mixed level of specificity. We now
specify the method for each `/debug` handler to prevent
incompatibilities.
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
* cmd/k8s-operator,k8s-operator: introduce proxy configuration mechanism via ProxyClass custom resource.
ProxyClass custom resource can be used to specify customizations
for the proxy resources created by the operator.
Add a reconciler that validates ProxyClass resources
and sets a Ready condition to True or False with a corresponding reason and message.
This is required because some fields (labels and annotations)
require complex validations that cannot be performed at custom resource apply time.
Reconcilers that use the ProxyClass to configure proxy resources are expected to
verify that the ProxyClass is Ready and not proceed with resource creation
if configuration from a ProxyClass that is not yet Ready is required.
If a tailscale ingress/egress Service is annotated with a tailscale.com/proxy-class annotation, look up the corresponding ProxyClass and, if it is Ready, apply the configuration from the ProxyClass to the proxy's StatefulSet.
If a tailscale Ingress has a tailscale.com/proxy-class annotation
and the referenced ProxyClass custom resource is available and Ready,
apply configuration from the ProxyClass to the proxy resources
that will be created for the Ingress.
Add a new .proxyClass field to the Connector spec.
If connector.spec.proxyClass is set to a ProxyClass that is available and Ready,
apply configuration from the ProxyClass to the proxy resources created for the Connector.
Ensure that when Helm chart is packaged, the ProxyClass yaml is added to chart templates. Ensure that static manifest generator adds ProxyClass yaml to operator.yaml. Regenerate operator.yaml
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
For a second we thought this was allocating but we were looking
at a CPU profile (which showed calls to mallocgc view makeslice)
instead of the alloc profile.
Updates golang/go#65685 (which if fixed wouldn't have confused us)
Change-Id: Ic0132310d52d8a65758a516142525339aa23b1ed
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
FileSystemForLocal was listening on the node's Tailscale address,
which potentially exposes the user's view of TailFS shares to other
Tailnet users. Remote nodes should connect to exported shares via
the peerapi.
This removes that code so that FileSystemForLocal is only avaialable
on 100.100.100.100:8080.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
As part of #10631, we stopped using function pointers for subcommands,
preventing us from registering platform-specific installSystemDaemon
and uninstallSystemDaemon subcommands.
Fixes#11099
Signed-off-by: Percy Wegmann <percy@tailscale.com>
Adds support for node attribute tailfs:access. If this attribute is
not present, Tailscale will not accept connections to the local TailFS
server at 100.100.100.100:8080.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
The new math/rand/v2 package includes an m-local global random number
generator that can not be reseeded by the user, which is suitable for
most uses without the RNG pools we have in a number of areas of the code
base.
The new API still does not have an allocation-free way of performing a
seeded operations, due to the long term compiler bug around interface
parameter escapes, and the Source interface.
This change introduces the two APIs that math/rand/v2 can not yet
replace efficiently: seeded Perm() and Shuffle() operations. This
implementation chooses to use the PCG random source from math/rand/v2,
as with sufficient compiler optimization, this source should boil down
to only two on-stack registers for random state under ideal conditions.
Updates #17243
Signed-off-by: James Tucker <james@tailscale.com>
For user-owned nodes, only the owner is ever allowed to manage the
node.
Updates tailscale/corp#16695
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This reverts commit 291f91d164.
Updates #cleanup
This PR needs additional changes to the registration of child handlers under /debug
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
Updates #cleanup
Go 1.22.0 introduced the ability to use more expressive routing patterns
that include HTTP method when constructing ServeMux entries.
Applications that attempted to use these patterns in combination with
the old `tsweb.Debugger` would experience a panic as Go would not permit
the use of matching rules with mixed level of specificity.
Signed-off-by: Patrick O'Doherty <patrick@tailscale.com>
`os.LookupEnv` may return true if the variable is present in
the environment but an empty string. We should only attempt
to set OAuth Config if thsoe values are non-empty.
Updates gitops-acl-action#33
Signed-off-by: Jenny Zhang <jz@tailscale.com>
Add a WebDAV-based folder sharing mechanism that is exposed to local clients at
100.100.100.100:8080 and to remote peers via a new peerapi endpoint at
/v0/tailfs.
Add the ability to manage folder sharing via the new 'share' CLI sub-command.
Updates tailscale/corp#16827
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This change fixes the format of tailscale status output when location
based exit nodes are present.
Fixes#11065
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Fixestailscale/support-escalations#23.
authURLs returned by control expire after 1 hour from creation. Customer reported that the Tailscale client on macOS would sending users to a stale authentication page when clicking on the `Login...` menu item. This can happen when clicking on Login after leaving the device unattended for several days. The device key expires, leading to the creation of a new authURL, however the client doesn't keep track of when the authURL was created. Meaning that `login-interactive` would send the user to an authURL that had expired server-side a long time before.
This PR ensures that whenever `login-interactive` is called via LocalAPI, an authURL that is too old won't be used. We force control to give us a new authURL whenever it's been more than 30 minutes since the last authURL was sent down from control.
Apply suggestions from code review
Set interval to 6 days and 23 hours
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
Update logs for synology builds to more clearly callout which variant
is being built. The two existing variants are:
1. Sideloaded (can be manual installed on a device by anyone)
2. Package center distribution (by the tailscale team)
Updates #cleanup
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
add the curly-quotes eslint plugin (same that we use for the admin
panel), and fix existing straight quotes in the current web UI.
Updates #cleanup
Signed-off-by: Will Norris <will@tailscale.com>
The new read-only mode is only accessible when running `tailscale web`
by passing a new `-readonly` flag. This new mode is identical to the
existing login mode with two exceptions:
- the management client in tailscaled is not started (though if it is
already running, it is left alone)
- the client does not prompt the user to login or switch to the
management client. Instead, a message is shown instructing the user
to use other means to manage the device.
Updates #10979
Signed-off-by: Will Norris <will@tailscale.com>
* cmd/containerboot,cmd/k8s-operator/deploy/manifests: optionally forward cluster traffic via ingress proxy.
If a tailscale Ingress has tailscale.com/experimental-forward-cluster-traffic-via-ingress annotation, configure the associated ingress proxy to have its tailscale serve proxy to listen on Pod's IP address. This ensures that cluster traffic too can be forwarded via this proxy to the ingress backend(s).
In containerboot, if EXPERIMENTAL_PROXY_CLUSTER_TRAFFIC_VIA_INGRESS is set to true
and the node is Kubernetes operator ingress proxy configured via Ingress,
make sure that traffic from within the cluster can be proxied to the ingress target.
Updates tailscale/tailscale#10499
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Advertise DNS discovered addresses as a single preference update rather
than one at a time.
Sort the list of observed addresses and use binary search to consult the
list.
Updates tailscale/corp#16636
Signed-off-by: James Tucker <james@tailscale.com>
views.Slice are meant to be immutable, and if used as such it
is at times desirable to use them as a key in a map. For non-viewed
slices it was kinda doable by creating a custom key struct but views.Slice
didn't allow for the same so add a method to create that struct here.
Updates tailscale/corp#17122
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Providing a hash.Block512 is an implementation detail of how deephash
works today, but providing an opaque type with mostly equivalent API
(i.e., HashUint8, HashBytes, etc. methods) is still sensible.
Thus, define a public Hasher type that exposes exactly the API
that an implementation of SelfHasher would want to call.
This gives us freedom to change the hashing algorithm of deephash
at some point in the future.
Also, this type is likely going to be called by types that are
going to memoize their own hash results, we additionally add
a HashSum method to simplify this use case.
Add documentation to SelfHasher on how a type might implement it.
Updates: corp#16409
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
If an app connector is also configured as an exit node, it should still
advertise discovered routes that are not covered by advertised routes,
excluding the exit node routes.
Updates tailscale/corp#16928
Signed-off-by: James Tucker <james@tailscale.com>
If any domain along a CNAME chain matches any of the routed domains, add
routes for the discovered domains.
Fixestailscale/corp#16928
Signed-off-by: James Tucker <james@tailscale.com>
The API on the DNS record parser is slightly subtle and requires
explicit handling of unhandled records. Failure to advance previously
resulted in an infinite loop in the pretty responder for any reply that
contains a record other than A/AAAA/TXT.
Updates tailscale/corp#16928
Signed-off-by: James Tucker <james@tailscale.com>
When reporting ssh host keys to control, log a warning
if we're unable to get the SSH host keys.
Updates tailscale/escalations#21
Signed-off-by: Percy Wegmann <percy@tailscale.com>
gitops-pusher supports authenticating with an API key or OAuth
credentials (added in #7393). You shouldn't ever use both of those
together, so we error if both are set.
In tailscale/gitops-acl-action#24, OAuth support is being added to the
GitHub action. In that environment, both the TS_API_KEY and OAuth
variables will be set, even if they are empty values. This causes an
error in gitops-pusher which expects only one to be set.
Update gitops-pusher to check that only one set of environment variables
are non-empty, rather than just checking if they are set.
Updates #7393
Signed-off-by: Will Norris <will@tailscale.com>
When running as non-root non-operator user, you get this error:
```
$ tailscale serve 8080
Access denied: watch IPN bus access denied, must set ipn.NotifyNoPrivateKeys when not running as admin/root or operator
Use 'sudo tailscale serve 8080' or 'tailscale up --operator=$USER' to not require root.
```
It should fail, but the error message is confusing.
With this fix:
```
$ tailscale serve 8080
sending serve config: Access denied: serve config denied
Use 'sudo tailscale serve 8080' or 'tailscale up --operator=$USER' to not require root.
```
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
expvarx.SafeFunc wraps an expvar.Func with a time limit. On reaching the
time limit, calls to Value return nil, and no new concurrent calls to
the underlying expvar.Func will be started until the call completes.
Updates tailscale/corp#16999
Signed-off-by: James Tucker <james@tailscale.com>
These are functionally the same as the "urn:schemas-upnp-org" services
with a few minor changes, and are still used by older devices. Support
them to improve our ability to obtain an external IP on such networks.
Updates #10911
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I05501fad9d6f0a3b8cf19fc95eee80e7d16cc2cf
Don't append a trailing slash to a request path
to the reverse proxy that matches the mount point exactly.
Updates tailscale/tailscale#10730
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This commit implements probing of UDP path lifetime on the tail end of
an active direct connection. Probing configuration has two parts -
Cliffs, which are various timeout cliffs of interest, and
CycleCanStartEvery, which limits how often a probing cycle can start,
per-endpoint. Initially a statically defined default configuration will
be used. The default configuration has cliffs of 10s, 30s, and 60s,
with a CycleCanStartEvery of 24h. Probing results are communicated via
clientmetric counters. Probing is off by default, and can be enabled
via control knob. Probing is purely informational and does not yet
drive any magicsock behaviors.
Updates #540
Signed-off-by: Jordan Whited <jordan@tailscale.com>
If control advised the connector to advertise a route that had already
been discovered by DNS it would be incorrectly removed. Now those routes
are preserved.
Updates tailscale/corp#16833
Signed-off-by: James Tucker <james@tailscale.com>
This change allows us to perform batch modification for new route
advertisements and route removals. Additionally, we now handle the case
where newly added routes are covered by existing ranges.
This change also introduces a new appctest package that contains some
shared functions used for testing.
Updates tailscale/corp#16833
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Do not provision resources for a tailscale Ingress that has no valid backends.
Updates tailscale/tailscale#10910
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This no longer results in a nil pointer exception when we get a valid
UPnP response with no supported clients.
Updates #10911
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I6e3715a49a193ff5261013871ad7fff197a4d77e
The new 'toolchain' directive in go.mod can sometimes force
the use of an upstream toolchain against our wishes. Concurrently,
some of our dependencies have added the 'toolchain' directive, which
transitively adds it to our own go.mod. Force all uses of gocross to
ignore that directive and stick to our customized toolchain.
Updates #cleanup
Signed-off-by: David Anderson <danderson@tailscale.com>
We issue redirects in a few different places, it's time to have
a common helper to do target validation.
Updates tailscale/corp#16875
Signed-off-by: David Anderson <danderson@tailscale.com>
* VERSION.txt: this is v1.58.0
Signed-off-by: kari-ts <kari@tailscale.com>
* VERSION.txt: this is v1.59.0
---------
Signed-off-by: kari-ts <kari@tailscale.com>
Plan9 CI is disabled. 3p dependencies do not build for the target.
Contributor enthusiasm appears to have ceased again, and no usage has
been made.
Skipped gvisor, nfpm, and k8s.
Updates #5794
Updates #8043
Signed-off-by: James Tucker <james@tailscale.com>
When tailscaled is run with "-debug 127.0.0.1:12345", these metrics are
available at:
http://localhost:12345/debug/metrics
Updates #8210
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I19db6c445ac1f8344df2bc1066a3d9c9030606f8
For use in corp, where we appear to have re-implemented this in a few
places with varying signatures.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Id863a87e674f3caa87945519be8e09650e9c1d76
If there are routes changes as a side effect of an app connector
configuration update, the connector configuration may want to reenter a
lock, so must be started asynchronously.
Updates tailscale/corp#16833
Signed-off-by: James Tucker <james@tailscale.com>
This is a useful primitive for asynchronous execution of ordered work I
want to use in another change.
Updates tailscale/corp#16833
Signed-off-by: James Tucker <james@tailscale.com>
Control can now send down a set of routes along with the domains, and
the routes will be advertised, with any newly overlapped routes being
removed to reduce the size of the routing table.
Fixestailscale/corp#16833
Signed-off-by: James Tucker <james@tailscale.com>
Also perform minor cleanups on the ctxkey package itself.
Provide guidance on when to use ctxkey.Key[T] over ctxkey.New.
Also, allow for interface kinds because the value wrapping trick
also happens to fix edge cases with interfaces in Go.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
To reduce the likelihood of breaking users,
if we implement stricter Exact path type matching in the future.
Updates tailscale/tailscale#10730
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
So that users have predictable label values to use when configuring network policies.
Updates tailscale/tailscale#10854
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
* cmd/k8s-operator/deploy: deploy a Tailscale IngressClass resource.
Some Ingress validating webhooks reject Ingresses with
.spec.ingressClassName for which there is no matching IngressClass.
Additionally, validate that the expected IngressClass is present,
when parsing a tailscale `Ingress`.
We currently do not utilize the IngressClass,
however we might in the future at which point
we might start requiring that the right class
for this controller instance actually exists.
Updates tailscale/tailscale#10820
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Anton Tolchanov <anton@tailscale.com>
The lack of type-safety in context.WithValue leads to the common pattern
of defining of package-scoped type to ensure global uniqueness:
type fooKey struct{}
func withFoo(ctx context, v Foo) context.Context {
return context.WithValue(ctx, fooKey{}, v)
}
func fooValue(ctx context) Foo {
v, _ := ctx.Value(fooKey{}).(Foo)
return v
}
where usage becomes:
ctx = withFoo(ctx, foo)
foo := fooValue(ctx)
With many different context keys, this can be quite tedious.
Using generics, we can simplify this as:
var fooKey = ctxkey.New("mypkg.fooKey", Foo{})
where usage becomes:
ctx = fooKey.WithValue(ctx, foo)
foo := fooKey.Value(ctx)
See https://go.dev/issue/49189
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
When establishing connections to the ipnserver, we validate that the
local user is allowed to connect. If Tailscale is currently being
managed by a different user (primarily for multi-user Windows installs),
we don't allow the connection.
With the new device web UI, the inbound connection is coming from
tailscaled itself, which is often running as "NT AUTHORITY\SYSTEM".
In this case, we still want to allow the connection, even though it
doesn't match the user running the Tailscale GUI. The SYSTEM user has
full access to everything on the system anyway, so this doesn't escalate
privileges.
Eventually, we want the device web UI to run outside of the tailscaled
process, at which point this exception would probably not be needed.
Updates tailscale/corp#16393
Signed-off-by: Will Norris <will@tailscale.com>
See the field alignment lints for more information.
Reductions are 64->24 and 64->32 respectively.
Updates #self
Signed-off-by: James Tucker <james@tailscale.com>
This change adds a description to the exit-node CLI command. This
description will be displayed when using `tailscale -h` and `tailscale
exit-node -h`.
Fixes#10787
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
The manage client always listens on http (non-secure) port 5252. If the
login client is loaded over https, then the connectivity check to `/ok`
will fail with a mixed-content error. Mixed-content enforcement is a
browser setting that we have no control over, so there's no way around
this.
In this case of the login client being loaded over https, we skip the
connectivity check entirely. We will always render the sign-in button,
though we don't know for sure if the user has connectivity, so we
provide some additional help text in case they have trouble signing in.
Updates hassio-addons/addon-tailscale#314
Signed-off-by: Will Norris <will@tailscale.com>
Observed on one busy derp node, there were 600 goroutines blocked
writing to this channel, which represents not only more blocked routines
than we need, but also excess wake-ups downstream as the latent
goroutines writes represent no new work.
Updates #self
Signed-off-by: James Tucker <james@tailscale.com>
The configuration knob (that defaulted to Connector being disabled)
was added largely because the Connector CRD had to be installed in a separate step.
Now when the CRD has been added to both chart and static manifest, we can have it on by default.
Updates tailscale/tailscale#10878
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
cmd/k8s-operator: fix base truncating for extra long Service names
StatefulSet names for ingress/egress proxies are calculated
using Kubernetes name generator and the parent resource name
as a base.
The name generator also cuts the base, but has a higher max cap.
This commit fixes a bug where, if we get a shortened base back
from the generator, we cut off too little as the base that we
have cut will be passed into the generator again, which will
then itself cut less because the base is shorter- so we end up
with a too long name again.
Updates tailscale/tailscale#10807
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Irbe Krumina <irbekrm@gmail.com>
Sets up peer capability types for future use within the web client
views and APIs.
Updates tailscale/corp#16695
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This is in response to logs from a customer that show that we're unable
to run netsh due to the following error:
router: firewall: adding Tailscale-Process rule to allow UDP for "C:\\Program Files\\Tailscale\\tailscaled.exe" ...
router: firewall: error adding Tailscale-Process rule: exec: "netsh": cannot run executable found relative to current directory:
There's approximately no reason to ever dynamically look up the path of
a system utility like netsh.exe, so instead let's first look for it
in the System32 directory and only if that fails fall back to the
previous behaviour.
Updates #10804
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I68cfeb4cab091c79ccff3187d35f50359a690573
Build dev tailscale and k8s-operator images for linux/amd64 only by default,
make it possible to configure target build platform via PLATFORM var.
Updates#cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This is useful to build local binaries with custom versions to test
version-specific logic (like updates).
Updates https://github.com/tailscale/corp/issues/16703
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Use the helper method from the version package to detect that we are
running the macsys network extension. This method does the same check
for the HOME environment variable (which works fine in most cases) as
well as the name of the executable (which is needed for the web client).
Updates tailscale/corp#16393
Signed-off-by: Will Norris <will@tailscale.com>
cmd/k8s-operator: add CRD to chart and static manifest
Add functionality to insert CRD to chart at package time.
Insert CRD to static manifests as this is where they are currently consumed from.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Prints a helpful message with the web UI's address when running
tailscale set --webclient.
Updates tailscale/corp#16345
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Removes the avoidFinalRename logic and all associated code as it is no longer required by the Apple clients.
Enables resume logic to be usable for Apple clients.
Fixestailscale/corp#14772
Signed-off-by: Rhea Ghosh <rhea@tailscale.com>
The prefix has space for 32-bit site IDs, but the validateViaPrefix
function would previously have disallowed site IDs greater than 255.
Fixestailscale/corp#16470
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I4cdb0711dafb577fae72d86c4014cf623fa538ef
cmd/k8s-operator/deploy/crds,k8s-operator/apis/v1alpha1: allow to define an exit node via Connector CR.
Make it possible to define an exit node to be deployed to a Kubernetes cluster
via Connector Custom resource.
Also changes to Connector API so that one Connector corresponds
to one Tailnet node that can be either a subnet router or an exit
node or both.
The Kubernetes operator parses Connector custom resource and,
if .spec.isExitNode is set, configures that Tailscale node deployed
for that connector as an exit node.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Anton Tolchanov <anton@tailscale.com>
Add a standalone server for STUN that can be hosted independently of the
derper, and factor that back into the derper.
Fixes#8434Closes#8435Closes#10745
Signed-off-by: James Tucker <james@tailscale.com>
This is simply an extra check to prevent hypothetical issues if a prefix
such as `--prefix="javascript:alert(1)"` was provided. This isn't
really necessary since the prefix is a configuration flag provided by
the device owner, not user input. But it does enforce that we are
always interpreting the provided value as a path relative to the root.
Fixes: tailscale/corp#16268
Signed-off-by: Will Norris <will@tailscale.com>
For consistency w/ the CLI command. And to be more accurate to what
is actually happening on this action - node key is expired.
Also updates the disconnected view shown after logout.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
* cmd/containerboot: optionally configure tailscaled with a configfile.
If EXPERIMENTAL_TS_CONFIGFILE_PATH env var is set,
only run tailscaled with the provided config file.
Do not run 'tailscale up' or 'tailscale set'.
* cmd/containerboot: store containerboot accept_dns val in bool pointer
So that we can distinguish between the value being set to
false explicitly bs being unset.
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Unlike most prefs, the ControlURL policy needs to take effect before
login. This resolves an issue where on first start, even when the
ControlURL policy is set, it will generate a login URL to the Tailscale
SaaS server.
Updates tailscale/coral#118
Fixes#10736
Change-Id: I6da2a521f64028c15dbb6ac8175839fc3cc4e858
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
To make setting Windows policies easier, this adds ADMX policy
descriptions.
Fixes#6495
Updates ENG-2515
Change-Id: If4613c9d8ec734afec8bd781575e24b4aef9bb73
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
To make it easier to correlate the starting/ending log messages.
Updates #cleanup
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I2802d53ad98e19bc8914bc58f8c04d4443227b26
This will expand the unicode character categories that we allow for valid filenames to go from "L, M, N, P, S, and the ASCII space character" to "L, M, N, P, S, Zs"
Fixes#10105
Signed-off-by: Rhea Ghosh <rhea@tailscale.com>
This command allows observing whether a given dialer ("SystemDial",
"UserDial", etc.) will successfully obtain a connection to a provided
host, from inside tailscaled itself. This is intended to help debug a
variety of issues from subnet routers to split DNS setups.
Updates #9619
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie01ebb5469d3e287eac633ff656783960f697b84
This tripped me up when I was testing something and wrote:
if conn != nil {
conn.Close()
}
In netstack mode, when an error occurred we were getting a non-nil error
and a non-nil interface that contained a nil pointer. Instead, just
return a nil interface value.
Updates #cleanup
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Id9ef3dd24529e0e8c53adc60ed914c31fbb10cc4
ErrDenied was added in [our fork of
x/crypto/ssh](acc6f8fe8d)
to short-circuit auth attempts once one fails.
In the case of our callbacks, this error is returned when SSH policy
check determines that a connection should not be allowed. Both
`NoClientAuthCallback` and `PublicKeyHandler` check the policy and will
fail anyway. The `fakePasswordHandler` returns true only if
`NoClientAuthCallback` succeeds the policy check, so it checks it
indirectly too.
The difference here is that a client might attempt all 2-3 auth methods
instead of just `none` but will fail to authenticate regardless.
Updates #8593
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Updates #8022
Updates #6075
On iOS, we currently rely on delegated interface information to figure out the default route interface. The NetworkExtension framework in iOS seems to set the delegate interface only once, upon the *creation* of the VPN tunnel. If a network transition (e.g. from Wi-Fi to Cellular) happens while the tunnel is connected, it will be ignored and we will still try to set Wi-Fi as the default route because the delegated interface is not getting updated as connectivity transitions.
Here we work around this on the Swift side with a NWPathMonitor instance that observes the interface name of the first currently satisfied network path. Our Swift code will call into `UpdateLastKnownDefaultRouteInterface`, so we can rely on that when it is set.
If for any reason the Swift machinery didn't work and we don't get any updates, here we also have some fallback logic: we try finding a hardcoded Wi-Fi interface called en0. If en0 is down, we fall back to cellular (pdp_ip0) as a last resort. This doesn't handle all edge cases like USB-Ethernet adapters or multiple Ethernet interfaces, but it is good enough to ensure connectivity isn't broken.
I tested this on iPhones and iPads running iOS 17.1 and it appears to work. Switching between different cellular plans on a dual SIM configuration also works (the interface name remains pdp_ip0).
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
A Tailnet node can be told to stop advertise subnets by passing
an empty string to --advertise-routes flag.
Respect an explicitly passed empty value to TS_ROUTES env var
so that users have a way to stop containerboot acting as a subnet
router without recreating it.
Distinguish between TS_ROUTES being unset and empty.
Updates tailscale/tailscale#10708
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The service is only used as a watchdog and for piping logs from the child
process. We shouldn't be creating a network monitor in that case.
Fixes#10732
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
If the epoch that we see during a Probe is less than the existing epoch,
it means that the gateway has either restarted or reset its
configuration, and an existing mapping is no longer valid. Reset any
saved mapping(s) if we detect this case so that a future
createOrGetMapping will not attempt to re-use it.
Updates #10597
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie3cddaf625cb94a29885f7a1eeea25dbf6b97b47
plugin-types is deprecated, and setting object-src: 'none' is best
practice. This should result in no functional change.
Fixes#10718
Signed-off-by: Chris Palmer <cpalmer@tailscale.com>
Previously, for Windows clients only, a registry value named LogTarget
could override the log server, but only if the environment variable was
unset.
To allow administrators to enforce using a particular log server, switch
this to make the registry value take precedence over the environment
variable, and switch to the newer syspolicy.GetString so that the log
target can be specified by a GPO more easily.
Updates ENG-2515
Change-Id: Ia618986b0e07715d7db4c6df170a24d511c904c9
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
go get github.com/tailscale/mkctr@bf50773ba7349ced8de812c3d5437e8618bd4fa7
Updates tailscale/tailscale#9902
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
When the portable Monitor creates a winMon via newOSMon, we register
address and route change callbacks with Windows. Once a callback is hit,
it starts a goroutine that attempts to send the event into messagec and returns.
The newly started goroutine then blocks until it can send to the channel.
However, if the monitor is never started and winMon.Receive is never called,
the goroutines remain indefinitely blocked, leading to goroutine leaks and
significant memory consumption in the tailscaled service process on Windows.
Unlike the tailscaled subprocess, the service process creates but never starts
a Monitor.
This PR adds a check within the callbacks to confirm the monitor's active status,
and exits immediately if the monitor hasn't started.
Updates #9864
Signed-off-by: Nick Khyl <nickk@tailscale.com>
This type seems to be a migration shim for TCP tailscaled sockets
(instead of unix/windows pipes). The `port` field was never set, so it
was effectively used as a string (`path` field).
Remove the whole type and simplify call sites to pass the socket path
directly to `safesocket.Connect`.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Run `staticcheck` with `U1000` to find unused code. This cleans up about
a half of it. I'll do the other half separately to keep PRs manageable.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This logs additional information about what mapping(s) are obtained
during the creation process, including whether we return an existing
cached mapping.
Updates #10597
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I9ff25071f064c91691db9ab0b9365ccc5f948d6e
Currently, we get the "likely home router" gateway IP and then iterate
through all IPs for all interfaces trying to match IPs to determine the
source IP. However, on many platforms we know what interface the gateway
is through, and thus we don't need to iterate through all interfaces
checking IPs. Instead, use the IP address of the associated interface.
This better handles the case where we have multiple interfaces on a
system all connected to the same gateway, and where the first interface
that we visit (as iterated by ForeachInterfaceAddress) isn't also the
default internet route.
Updates #8992
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8632f577f1136930f4ec60c76376527a19a47d1f
Using reflect.MethodByName disables some linked deadcode optimizations
and makes our binaries much bigger.
Difference before/after this commit:
```
-rwxr-xr-x 1 awly awly 30M Dec 19 15:28 tailscaled.after*
-rwxr-xr-x 1 awly awly 43M Dec 19 15:27 tailscaled.before*
```
Fixes#10627
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
In this commit, we have updated the build process for our Windows DLLs
to link statically with libgcc, ensuring our Windows DLLs are self-contained.
Updates #10617
Signed-off-by: Nick Khyl <nickk@tailscale.com>
Individual route advertisements that are covered by existing routes are
no longer advertised. If an upstream returns 0.0.0.0, 127.x, and other
common unwanted addresses those are also rejected.
Updates #16425
Signed-off-by: James Tucker <james@tailscale.com>
The cmpx.Compare function (and associated interface) are now available
in the standard library as cmp.Compare. Remove our version of it and use
the version from the standard library.
Updates #cleanup
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I4be3ac63d466c05eb7a0babb25cb0d41816fbd53
When auto-update setting in local Prefs is unset, apply the tailnet
default value from control. This only happens once, when we apply the
default (or when the user manually overrides it), tailnet default no
longer affects the node.
Updates #16244
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Instead of taking the first UPnP response we receive and using that to
create port mappings, store all received UPnP responses, sort and
deduplicate them, and then try all of them to obtain an external
address.
Updates #10602
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I783ccb1834834ee2a9ecbae2b16d801f2354302f
connector-gen can initially generate connector ACL snippets and
advertise-routes flags for Github and AWS based on their public IP /
domain data.
Updates ENG-2425
Signed-off-by: James Tucker <james@tailscale.com>
Throughout the web UI, we present the tailscale addresses for the
self node. In the case of the node being shared out with a user
from another tailnet, the peer viewer may actually know the node
by a different IP than the node knows itself as (Tailscale IPs
can be configured as desired on a tailnet level). This change
includes two fixes:
1. Present the self node's addresses in the frontend as the addresses
the viewing node knows it as (i.e. the addresses the viewing node
uses to access the web client).
2. We currently redirect the viewer to the Tailscale IPv4 address if
viewing it by MagicDNS name, or any other name that maps to the
Tailscale node. When doing this redirect, which is primarily added
for DNS rebinding protection, we now check the address the peer
knows this node as, and redirect to specifically that IP.
Fixestailscale/corp#16402
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
The switch in Conn.runDerpReader() on the derp.ReceivedMessage type
contained cases other than derp.ReceivedPacket that fell through to
writing to c.derpRecvCh, which should only be reached for
derp.ReceivedPacket. This can result in the last/previous
derp.ReceivedPacket to be re-handled, effectively creating a duplicate
packet. If the last derp.ReceivedPacket happens to be a
disco.CallMeMaybe it may result in a disco ping scan towards the
originating peer on the endpoints contained.
The change in this commit moves the channel write on c.derpRecvCh and
subsequent select awaiting the result into the derp.ReceivedMessage
case, preventing it from being reached from any other case. Explicit
continue statements are also added to non-derp.ReceivedPacket cases
where they were missing, in order to signal intent to the reader.
Fixes#10586
Signed-off-by: Jordan Whited <jordan@tailscale.com>
* k8s-operator,cmd/k8s-operator,Makefile,scripts,.github/workflows: add Connector kube CRD.
Connector CRD allows users to configure the Tailscale Kubernetes operator
to deploy a subnet router to expose cluster CIDRs or
other CIDRs available from within the cluster
to their tailnet.
Also adds various CRD related machinery to
generate CRD YAML, deep copy implementations etc.
Engineers will now have to run
'make kube-generate-all` after changing kube files
to ensure that all generated files are up to date.
* cmd/k8s-operator,k8s-operator: reconcile Connector resources
Reconcile Connector resources, create/delete subnetrouter resources in response to changes to Connector(s).
Connector reconciler will not be started unless
ENABLE_CONNECTOR env var is set to true.
This means that users who don't want to use the alpha
Connector custom resource don't have to install the Connector
CRD to their cluster.
For users who do want to use it the flow is:
- install the CRD
- install the operator (via Helm chart or using static manifests).
For Helm users set .values.enableConnector to true, for static
manifest users, set ENABLE_CONNECTOR to true in the static manifest.
Updates tailscale/tailscale#502
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Ensure we don't create Location: header URLs that have leading //, which is a
schema-less reference to arbitrary 3rd-party sites. That is, //example.com/foo
redirects off-site, while /example.com/foo is an on-site path URL.
Fixestailscale/corp#16268
Signed-off-by: Chris Palmer <cpalmer@tailscale.com>
This uses the fact that we've received a frame from a given DERP region
within a certain time as a signal that the region is stil present (and
thus can still be a node's PreferredDERP / home region) even if we don't
get a STUN response from that region during a netcheck.
This should help avoid DERP flaps that occur due to losing STUN probes
while still having a valid and active TCP connection to the DERP server.
RELNOTE=Reduce home DERP flapping when there's still an active connection
Updates #8603
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If7da6312581e1d434d5c0811697319c621e187a0
Previously, we would select the first WANIPConnection2 (and related)
client from the root device, without any additional checks. However,
some routers expose multiple UPnP devices in various states, and simply
picking the first available one can result in attempting to perform a
portmap with a device that isn't functional.
Instead, mimic what the miniupnpc code does, and prefer devices that are
(a) reporting as Connected, and (b) have a valid external IP address.
For our use-case, we additionally prefer devices that have an external
IP address that's a public address, to increase the likelihood that we
can obtain a direct connection from peers.
Finally, we split out fetching the root device (getUPnPRootDevice) from
selecting the best service within that root device (selectBestService),
and add some extensive tests for various UPnP server behaviours.
RELNOTE=Improve UPnP portmapping when multiple UPnP services exist
Updates #8364
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I71795cd80be6214dfcef0fe83115a5e3fe4b8753
Was previously failing to redirect to the manage client when accessing
the login client with the Tailscale IP.
Updates #10261Fixestailscale/corp#16348
Co-authored-by: Will Norris <will@tailscale.com>
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Add a new "Debug" card at the bottom of the details page. It's maybe
premature to add a separate card for this, since all it currently lists
is whether the device is using TUN mode and (for Synology) the DSM
version. But I think it may be helpful to add client connectivity data
(like shown on admin console machine page) as well as a bug report
button. Those can come soon after the 1.56 launch.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
To be safe, use `prefs.ControlURLOrDefault()` rather than the current
`prefs.ControlURL` directly.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Ensure that if getOrCreateChain creates a new chain, it actually returns the created chain
Updates tailscale/tailscale#10399
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Calculate and set the hash of the one inline script we have in
index.html. That script is unlikely to change, so hardcoding the hash
seems fine for now.
Updates #10261
Updates tailscale/corp#16266
Signed-off-by: Will Norris <will@tailscale.com>
Completed testing of the new UI on the existing platforms that use
it. From testing, QNAP, Unraid, and Home Assistant (in addition to
Synology) all do not play well with using an exit node. For now,
we're disabling this setting from the UI. CLI should be updated to
also disallow selection of an exit node from these platforms.
All platforms still allow for advertising as an exit node.
Co-authored-by: Will Norris <will@tailscale.com>
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
When displaying the login client, we check for connectivity to the
management client by calling it's /ok handler. If that response is
non-200, then there is something wrong with the management client, so
don't render the login button.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
Initial implementation of a `tailscale whois` subcommand
which allows users to observe metadata associated with a
Tailscale IP. It also has a `--json` flag to allow consumption
programmatically.
Updates #4217
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Add visual indication when running as an exit node prior to receiving
admin approval.
Updates https://github.com/tailscale/tailscale/issues/10261
Signed-off-by: Mario Minardi <mario@tailscale.com>
Co-authored-by: Sonia Appasamy <sonia@tailscale.com>
Previously, we were only breaking out of iframes when accessing the
login client over a local IP address (where viewerIdentity is not set).
We need to also handle the case where the user is accessing the login
client over the Tailscale IP, and similarly break out of the iframe when
logging into the management client.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
I seem to recall I needed this for things to work properly with the vite
dev server, but that doesn't seem to be the case anymore? Everything
seems to work fine without it. If we still have issues, we'll need to
look into using a nonce or integrity attribute.
Updates #10261Fixestailscale/corp#16266
Signed-off-by: Will Norris <will@tailscale.com>
Previously were always setting `UseSocketOnly` because we were
comparing `args.socketpath != ""`, but `args.socketpath` flag
always gets filled with `paths.DefaultTailscaledSocket()` when
not provided. Rather than comparing to the empty string, compare
to the default value to determine if `UseSocketOnly` should be
set.
Should fix issue with web client being unreachable for Mac App
Store variant of the mac build.
Updates #16054
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Add an endpoint for logging the device detail click metric to allow for
this metric to be logged without having a valid session which is the
case when in readonly mode.
Updates https://github.com/tailscale/tailscale/issues/10261
Signed-off-by: Mario Minardi <mario@tailscale.com>
Instead of overloading the Version field, add an explicit Track field.
This fixes a bug where passing a track name in `args.Version` would keep
the track name in `updater.Version` and pass it down the code path to
commands like `apt-get install`. Now, `updater.Version` should always be
a version (or empty string).
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Bump alpine base image version used to build tailscale/tailscale
and tailscale/k8s-operator images 3.16 -> 3.18
Updates #cleanup
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
When running on Home Assistant, use the X-Ingress-Path header to set the
URLPrefix that is passed to the frontend.
Also fix handling of errNotUsingTailscale in the auth handler
(previously it falling through to a later case and returning a 500).
Instead, it's just a terminal state with no auth needed.
Also disable SSH on Home Assistant, since it causes problems on startup
and doesn't make much sense anyway for that platform.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
Add confirmation dialogs for disconnecting and stopping advertisement
of a subnet route.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Limit cookies to HTTP requests (not accessible from javascript).
Set SameSite to "Lax", which is similar to "Strict" but allows for
cookies to be included in requests that come from offsite links. This
will be necessary when we link to the web client from the admin console.
Updates #10261Fixestailscale/corp#16265
Signed-off-by: Will Norris <will@tailscale.com>
The client has changed a bit since we introduced the path prefix. It is
now used for two things:
- its original purpose, of ensuring that when the client is run in CGI
mode at arbitrary paths, then relative paths for assets continue to
work
- we also now pass the path to the frontend and use wouter to manage
routes for the various subpages of the client.
When the client is run behind a reverse proxy (as it is in Home
Assistant), it is common for the proxy to rewrite the request so that
the backend application doesn't see the path it's being served at. In
this case, we don't need to call enforcePrefix, since it's already
stripped before it reaches us. However, wouter (or react router
library) still sees the original path in the browser, and needs to know
what part of it is the prefix that needs to be stripped off.
We're handling this by now only calling enforcePrefix when run in CGI
mode. For Home Assistant, or any other platform that runs the client
behind a reverse proxy with a custom path, they will still need to pass
the `-prefix` flag to `tailscale web`, but we will only use it for route
handling in the frontend.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
In Login mode, must first run system auth. But once authorized,
should be able to reach rest of auth logic to check whether the
user can manage the node. This results in showing/hiding the
sign in button in the frontend login toggle.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Calling DebugPacketFilterRules fails when the node is not logged
in, which was causing 500 errors on the node data endpoint after
logging the node out.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Previously, the "RunExitNode" policy merely controlled the visibility of
the "run as exit node" menu item, not the setting itself. This migrates
that setting to a preference option named "AdvertiseExitNode".
Updates ENG-2138
Change-Id: Ia6a125beb6b4563d380c6162637ce4088f1117a0
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
Add logging of device management type for the web client auth flow. Namely,
this differentiates between viewing a node you do not own, viewing a local
tagged node, viewing a remote tagged node, managing a local node, and
managing a remote node.
Updates https://github.com/tailscale/tailscale/issues/10261
Signed-off-by: Mario Minardi <mario@tailscale.com>
`tailscaled` and `tailscale` expect the socket to be at
`/var/run/tailscale/tailscaled.sock`, however containerboot
would set up the socket at `/tmp/tailscaled.sock`. This leads to a
poor UX when users try to use any `tailscale` command as they
have to prefix everything with `--socket /tmp/tailscaled.sock`.
To improve the UX, this adds a symlink to
`/var/run/tailscale/tailscaled.sock` to point to `/tmp/tailscaled.sock`.
This approach has two benefits, 1 users are able to continue to use
existing scripts without this being a breaking change. 2. users are
able to use the `tailscale` CLI without having to add the `--socket` flag.
Fixes tailscale/corp#15902
Fixes#6849Fixes#10027
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Even if connected to the login client over tailscale, still check
platform auth so the browser can obtain the tokens it needs to make
platform requests complete successfully.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Some fields if `ipn.Prefs` are structs. `ipn.MaskedPrefs` has a single
level of boolean `*Set` flags, which doesn't map well to nested structs
within `ipn.Prefs`.
Change `MaskedPrefs` and `ApplyEdits` to support `FooSet` struct fields
that map to a nested struct of `ipn.Prefs` like `AutoUpdates`. Each
struct field in `MaskedPrefs` is just a bundle of more `Set` bool fields
or other structs. This allows you to have a `Set` flag for any
arbitrarily-nested field of `ipn.Prefs`.
Also, make `ApplyEdits` match fields between `Prefs` and `MaskedPrefs`
by name instead of order, to make it a bit less finicky. It's probably
slower but `ipn.ApplyEdits` should not be in any hot path.
As a result, `AutoUpdate.Check` and `AutoUpdate.Apply` fields don't
clobber each other when set individually.
Updates #16247
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Updates ENG-2513. Renames client metrics keys used on Windows for consistency with Apple platforms.
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
Updates:
* Card component used throughout instead of custom card class
* SSH toggle changed to non-editable text/status icon in readonly
* Red error text on subnet route input when route post failed
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Precompress webclient assets with precompress util. This cuts our
css and js build sizes to about 1/3 of non-compressed size. Similar
compression done on tsconnect and adminhttp assets.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit makes some restructural changes to how we handle api
posting from the web client frontend.
Now that we're using SWR, we have less of a need for hooks like
useNodeData that return a useSWR response alongside some mutation
callbacks. SWR makes it easy to mutate throughout the UI without
needing access to the original data state in order to reflect
updates. So, we can fetch data without having to tie it to post
callbacks that have to be passed around through components.
In an effort to consolidate our posting endpoints, and make it
easier to add more api handlers cleanly in the future, this change
introduces a new `useAPI` hook that returns a single `api` callback
that can make any changes from any component in the UI. The hook
itself handles using SWR to mutate the relevant data keys, which
get globally reflected throughout the UI.
As a concurrent cleanup, node types are also moved to their own
types.ts file, to consolidate data types across the app.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This package allows caching arbitrary key/value pairs in-memory, along
with an interface implemented by the cache types.
Extracted from #7493
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ic8ca820927c456721cf324a0c8f3882a57752cc9
Due to the Sparkle preference naming convention, macsys already has a
policy key named "ApplyUpdates" that merely shows or hides the menu
item that controls if auto updates are installed, rather than directly
controlling the setting.
For other platforms, we are going to use "InstallUpdates" instead
because it seemed better than the other options that were considered.
Updates ENG-2127
Updates tailscale/corp#16247
Change-Id: Ia6a125beb6b4563d380c6162637ce4088f1117a0
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
This adds support for enforcing exit node LAN access, DNS and subnet
routes.
Adding new preference policies was getting repetitive, so this turns
some of the boilerplate into a table.
Updates tailscale/corp#15585
Updates ENG-2240
Change-Id: Iabd3c42b0ae120b3145fac066c5caa7fc4d67824
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
Remove padding on top of search bar, remove rounded corners of
bottom border of earch bar, and add auto focus.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Previously, policies affected the default prefs for a new profile, but
that does not affect existing profiles. This change ensures that
policies are applied whenever preferences are loaded or changed, so a
CLI or GUI client that does not respect the policies will still be
overridden.
Exit node IP is dropped from this PR as it was implemented elsewhere
in #10172.
Fixestailscale/corp#15585
Change-Id: Ide4c3a4b00a64e43f506fa1fab70ef591407663f
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
Adds a footer to the device details page that mirrors license and
policy content on other Tailscale clients.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Add workflow to run yarn lint/test/format-check against the web
client on pull requests.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
The IP property in node data was renamed to IPv4 but refactoring the usage
of the property was missed in this file.
Updates https://github.com/tailscale/tailscale/issues/10261
Signed-off-by: Mario Minardi <mario@tailscale.com>
Unfortunately in the test we can't reproduce the failure seen
in the real system ("SOAP fault: UPnPError")
Updates https://github.com/tailscale/tailscale/issues/8364
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
* util/linuxfw, wgengine: allow ingress to magicsock UDP port on Linux
Updates #9084.
Currently, we have to tell users to manually open UDP ports on Linux when
certain firewalls (like ufw) are enabled. This change automates the process of
adding and updating those firewall rules as magicsock changes what port it
listens on.
Signed-off-by: Naman Sood <mail@nsood.in>
Updates the IP address on home view to open a copyable list of node
addresses on click. And makes various values on the details view
copyable text items, mirroring the machine admin panel table.
As part of these changes, pulls the AddressCard, NiceIP and QuickCopy
components from the admin panel, with the AddressCard slightly modified
to avoid needing to also pull in the CommandLine component.
A new toaster interface is also added, allowing us to display success
and failure toasts throughout the UI. The toaster code is slightly
modified from it's admin form to avoid the need for some excess
libraries.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This will enable the runner to be replaced as a configuration side
effect in a later change.
Updates tailscale/corp#14029
Signed-off-by: James Tucker <james@tailscale.com>
These keys were intended to match the Apple platforms, but accidentally
used the wrong name.
Updates ENG-2133
Change-Id: I9ed7a17919e34e2d8896a5c64efc4d0c0003166e
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
Add left and right padding around entire client so that the cards don't
run into the side of the screen. Also tighten up vertical spacing in
couple of places.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
Before this fix, LikelyHomeRouterIP could return a 'self' IP that
doesn't correspond to the gateway address, since it picks the first
private address when iterating over the set interfaces as the 'self' IP,
without checking that the address corresponds with the
previously-detected gateway.
This behaviour was introduced by accident in aaf2df7, where we deleted
the following code:
for _, prefix := range privatev4s {
if prefix.Contains(gateway) && prefix.Contains(ip) {
myIP = ip
ok = true
return
}
}
Other than checking that 'gateway' and 'ip' were private IP addresses
(which were correctly replaced with a call to the netip.Addr.IsPrivate
method), it also implicitly checked that both 'gateway' and 'ip' were a
part of the *same* prefix, and thus likely to be the same interface.
Restore that behaviour by explicitly checking pfx.Contains(gateway),
which, given that the 'ip' variable is derived from our prefix 'pfx',
ensures that the 'self' IP will correspond to the returned 'gateway'.
Fixes#10466
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Iddd2ee70cefb9fb40071986fefeace9ca2441ee6
Add metric logging logic for the web client frontend. This is an initial
pass of adding the base logic, plus a single point where it is used for
validation that the logging is working correctly. More metric logging
calls will follow in subsquent PRs.
Updates https://github.com/tailscale/tailscale/issues/10261
Signed-off-by: Mario Minardi <mario@tailscale.com>
If the login client is inside an iframe, open the management client in a
new window, since it can't be loaded in the frame.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
If the currently selected exit node is offline, render the exit node
selector in red with an error message. Update exit nodes in the dropdown
to indicate if they are offline, and don't allow them to be selected.
This also updates some older color values to use the new colors.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
Makes the following changes:
* Use “link” class in various spots
* Remove button appearance on Exit Node dropdown in readonly mode
* Update `-stone-` colors to `-gray-` (couple spots missed by
original color config commit)
* Pull full ui/button component from admin panel, and update
buttons throughout UI to use this component
* Remove various buttons in readonly view to match mocks
* Add route (and “pending approval”) highlights to Subnet router
settings card
* Delete legacy client button styles from index.css
* Fix overflow of IPv6 address on device details view
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
* cmd/k8s-operator: generate static manifests from Helm charts
This is done to ensure that there is a single source of truth
for the operator kube manifests.
Also adds linux node selector to the static manifests as
this was added as a default to the Helm chart.
Static manifests can now be generated by running
`go generate tailscale.com/cmd/k8s-operator`.
Updates tailscale/tailscale#9222
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
For use in ACL tests, we need a way to check whether a packet is allowed
not just with TCP, but any protocol.
Updates #3561
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Use the packet filter rules to determine if any device is allowed to
connect on port 5252. This does not check whether a specific device can
connect (since we typically don't know the source device when this is
used). Nor does it specifically check for wide-open ACLs, which is
something we may provide a warning about in the future.
Update the login popover content to display information when the src
device is unable to connect to the dst device over its Tailscale IP. If
we know it's an ACL issue, mention that, otherwise list a couple of
things to check. In both cases, link to a placeholder URL to get more
information about web client connection issues.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
This PR is all about adding functionality that will enable the installer's
upgrade sequence to terminate processes belonging to the previous version,
and then subsequently restart instances belonging to the new version within
the session(s) corresponding to the processes that were killed.
There are multiple parts to this:
* We add support for the Restart Manager APIs, which allow us to query the
OS for a list of processes locking specific files;
* We add the RestartableProcess and RestartableProcesses types that query
additional information about the running processes that will allow us
to correctly restart them in the future. These types also provide the
ability to terminate the processes.
* We add the StartProcessInSession family of APIs that permit us to create
new processes within specific sessions. This is needed in order to
properly attach a new GUI process to the same RDP session and desktop that
its previously-terminated counterpart would have been running in.
* I tweaked the winutil token APIs again.
* A lot of this stuff is pretty hard to test without a very elaborate
harness, but I added a unit test for the most complicated part (though it
requires LocalSystem to run).
Updates https://github.com/tailscale/corp/issues/13998
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
When updating on Windows, we make a copy of the tailscale.exe file in a
temp directory to perform the update, because the original tailscale.exe
gets deleted during the update.
This can eat up disk space if a machine is stuck doing repeated failed
update attempts. Clean up old copies explicitly before making a new one,
same as we do with MSIs.
Updates #10082
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
The recent addition of RequestID was only populated if the
HTTP Request had returned an error. This meant that the underlying
handler has no access to this request id and any logs it may have
emitted were impossible to correlate to that request id. Therefore,
this PR adds a middleware to generate request ids and pass them
through the request context. The tsweb.StdHandler automatically
populates this request id if the middleware is being used. Finally,
inner handlers can use the context to retrieve that same request id
and use it so that all logs and events can be correlated.
Updates #2549
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Adds policy keys ExitNodeID and ExitNodeIP.
Uses the policy keys to determine the exit node in preferences.
Fixestailscale/corp#15683
Signed-off-by: Claire Wang <claire@tailscale.com>
Fixes a TODO in web.authorizeRequest.
`getSession` calls `WhoIs` already. Call `getSession` earlier in
`authorizeRequest` so we can avoid the duplicate `WhoIs` check on
the same request.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Adds AllowedIPs to PeerStatus, allowing for easier lookup of the
routes allowed to be routed to a node. Will be using the AllowedIPs
of the self node from the web client interface to display approval
status of advertised routes.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
To be consistent with the formatting of other warnings, pass available
update health message instead of handling ClientVersion in he CLI.
Fixes#10312
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
client/web: skip check mode for non-tailscale.com control servers
Only enforce check mode if the control server URL ends in
".tailscale.com". This allows the web client to be used with headscale
(or other) control servers while we work with the project to add check
mode support (tracked in juanfont/headscale#1623).
Updates #10261
Co-authored-by: Sonia Appasamy <sonia@tailscale.com>
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Signed-off-by: Will Norris <will@tailscale.com>
6e30c9d1f added eslint to the web client. As a part of that change,
the existing yarn.lock file was removed and yarn install run to build
with a clean yarn dependencies set with latest versions. This caused
a change in the "vite-plugin-rewrite-all" package that fails at build
time with our existing vite config. This is a known bug with some
suggested fixes:
https://vitejs.dev/guide/troubleshooting.html#this-package-is-esm-only
Rather than editing our package.json type, this commit reverts back
the yarn.lock file to it's contents at the commit just before 6e30c9d1f
and then only runs yarn install to add the new eslint packages, rather
than installing the latest versions of all packages.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Add eslint to require stricter typescript rules, particularly around
required hook dependencies. This commit also updates any files that
were now throwing errors with eslint.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Enforcing inclusion of our OSS license at the top of .ts and .tsx
files. Also updates any relevant files in the repo that were
previously missing the license comment. An additional `@license`
comment is added to client/web/src/index.tsx to preserve the
license in generated Javascript.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Application code can call the tsnet s.CapturePcap(filename) method
to write all packets, sent and received, to a pcap file. The cleartext
packets are written, outside the Wireguard tunnel. This is expected
to be useful for debugging.
Updates https://github.com/tailscale/tailscale/issues/9707
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
We warn users about IP forwarding being disabled when using
`--avertise-routes` in `tailscale up`, this adds the same warnings
to `tailscale set`.
Updates tailscale/corp#9968
Signed-off-by: Jenny Zhang <jz@tailscale.com>
* cmd/containerboot: proxy traffic to tailnet target defined by FQDN
Add a new Service annotation tailscale.com/tailnet-fqdn that
users can use to specify a tailnet target for which
an egress proxy should be deployed in the cluster.
Updates tailscale/tailscale#10280
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
If I have to add a tail, or a scale, mate, I will add it.
Updates tailscale/corp#14698
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
It looks like `gitCommitStamp` is the new "entrypoint" for setting this
information.
Fixes#9996.
Signed-off-by: Cole Helbling <cole.helbling@determinate.systems>
This records test coverage for the amd64 no race tests and uploads the
results to coveralls.io.
Updates #cleanup
Signed-off-by: Ox Cart <ox.to.a.cart@gmail.com>
Kubernetes can generate StatefulSet names that are too long and result in invalid Pod revision hash label values.
Calculate whether a StatefulSet name generated for a Service or Ingress
will be too long and if so, truncate it.
Updates tailscale/tailscale#10284
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Marshal as a JSON list instead of a map. Because set elements are
`comparable` and not `cmp.Ordered`, we cannot easily sort the items
before marshaling.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
It's possible to do this with a combination of watch-ipn and jq, but looking
at the netmap while debugging is quite common, so it's nice to have a one-shot
command to get it.
Updates #cleanup
Signed-off-by: David Anderson <danderson@tailscale.com>
jq doens't like non-json output in the json stream, and works more happily
when the input stream EOFs at some point. Move non-json words to stderr, and
add a parameter to stop watching and exit after some number of objects.
Updates #cleanup
Signed-off-by: David Anderson <danderson@tailscale.com>
Config.singleResolverSet returns true if all routes have the same resolvers,
even if the routes have no resolvers. If none of the routes have a specific
resolver, the default should be used instead. Therefore, check for more than
0 instead of nil.
Signed-off-by: Ryan Petris <ryan@petris.net>
Depending on how the preemption will occur, in some scenarios sendc
would have blocked indefinitely even after cancelling the context.
Fixes#10315
Signed-off-by: Uri Gorelik <uri.gore@gmail.com>
This adds an expandable section of the login view to allow users to
specify an auth key and an alternate control URL.
Input and Collapsible components and accompanying styles were brought
over from the adminpanel.
Updates #10261
Signed-off-by: Will Norris <will@tailscale.com>
Adds Inter font and uses it as the default for the web UI.
Creates a new /assets folder to house the /fonts, and moves /icons
to live here too.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This PR starts to persist the NetMap tailnet name in SetPrefs so that tailscaled
clients can use this value to disambiguate fast user switching from one tailnet
to another that are under the same exact login. We will also try to backfill
this information during backend starts and profile switches so that users don't
have to re-authenticate their profile. The first client to use this new
information is the CLI in 'tailscale switch -list' which now uses text/tabwriter
to display the ID, Tailnet, and Account. Since account names are ambiguous, we
allow the user to pass 'tailscale switch ID' to specify the exact tailnet they
want to switch to.
Updates #9286
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Add exit node selector (in full management client only) that allows
for advertising as an exit node, or selecting another exit node on
the Tailnet for use.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This creates a new /api/up endpoint which is exposed in the login
client, and is solely focused on logging in. Login has been removed from
the nodeUpdate endpoint.
This also adds support in the LoginClientView for a stopped node that
just needs to reconnect, but not necessarily reauthenticate. This
follows the same pattern in `tailscale up` of just setting the
WantRunning user pref.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This takes advantage of existing functionality in ipn/ipnlocal to adjust
the local clock based on periodic time signals from the control server.
This way, when checking things like SSHRule expirations, calculations are
protected incorrectly set local clocks.
Fixestailscale/corp#15796
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This change removes the existing debug-web-client localapi endpoint
and replaces it with functions passed directly to the web.ServerOpts
when constructing a web.ManageServerMode client.
The debug-web-client endpoint previously handled making noise
requests to the control server via the /machine/webclient/ endpoints.
The noise requests must be made from tailscaled, which has the noise
connection open. But, now that the full client is served from
tailscaled, we no longer need to proxy this request over the localapi.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
So the control plane can delete TXT records more aggressively
after client's done with ACME fetch.
Updates tailscale/corp#15848
Change-Id: I4f1140305bee11ee3eee93d4fec3aef2bd6c5a7e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* cmd/containerboot: shut down cleanly on SIGTERM
Make sure that tailscaled watcher returns when
SIGTERM is received and also that it shuts down
before tailscaled exits.
Updates tailscale/tailscale#10090
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Previously we would return the full error from Stat or Open, possibily exposing the full file path. This change will log the error and return the generic error message "an error occurred reading the file or directory".
Updates tailscale/corp#15485
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
When the viewing user is accessing a webclient not over Tailscale,
they must connect over Tailscale before being able to log into the
full management client, which is served over TS. This change adds
a check that the user is able to access the node's tailscale IP.
If not able to, the signin button is disabled. We'll also be adding
Copy here to help explain to the user that they must connect to
Tailscale before proceeding.
Updates #10261
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This `go get` action has been running very slowly, and I'm pretty sure
it's because we're building gocross on the first `./tool/go` run, and
because we've set `GOPROXY=direct`, it's going directly to GitHub to
fetch all of the gocross dependencies.
Updates #cleanup
Signed-off-by: Will Norris <will@tailscale.com>
I don't believe this has ever worked, since we didn't allow POST
requests in the login client. But previously, we were primarily using
the legacy client, so it didn't really matter. Now that we've removed
the legacy client, we have no way to login.
This fixes the login client, allowing it to login, but it still needs to
be refactored to expose a dedicated login method, without exposing all
the node update functionality.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
In DERP homeless mode, a DERP home connection is not sought or
maintained and the local node is not reachable.
Updates #3363
Updates tailscale/corp#396
Change-Id: Ibc30488ac2e3cfe4810733b96c2c9f10a51b8331
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is gated behind the silent disco control knob, which is still in
its infancy. Prior to this change disco pong reception was the only
event that could move trustBestAddrUntil forward, so even though we
weren't heartbeating, we would kick off discovery pings every
trustUDPAddrDuration and mirror to DERP.
Updates #540
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Now that we have nftable support this works fine and force
it on gokrazy since 25a8daf405.
Updates gokrazy/gokrazy#209
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Adds a new sync.Mutex field to the webClient struct, rather than
using the general LocalBackend mutex. Since webClientGetOrInit
(previously WebClientInit) gets called on every connection, we
want to avoid holding the lock on LocalBackend just to check if
the server is initialized.
Moves all web_client.go funcs over to using the webClient.mu field.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
No longer using this! Readonly state fully managed via auth endpoint.
Also getting rid of old Legacy server mode.
A #cleanup
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
For consistency with the "WebClient" naming of the other functions
here. Also fixed a doc typo.
A #cleanup
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
The non-referential copy destination doesn't extend the map contents,
but also the read of a non-key is returning a zero value not bound to
the map contents in any way.
Updates tailscale/corp#15657
Signed-off-by: James Tucker <james@tailscale.com>
These policy keys are supported on Apple platforms in Swift code; in
order to support them on platforms using Go (e.g. Windows), they also
need to be recorded here.
This does not affect any code, it simply adds the constants for now.
Updates ENG-2240
Updates ENG-2127
Updates ENG-2133
Change-Id: I0aa9863a3641e5844479da3b162761452db1ef42
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
The Windows base registry key is already exported but the policy key was
not. util/osdiag currently replicates the string rather than the
preferred approach of reusing the constant.
Updates #cleanup
Change-Id: I6c1c45337896c744059b85643da2364fb3f232f2
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
This PR changes the internal getTokenInfo function to use generics.
I also removed our own implementations for obtaining a token's user
and primary group in favour of calling the ones now available in
x/sys/windows.
Furthermore, I added two new functions for working with tokens, logon
session IDs, and Terminal Services / RDP session IDs.
I modified our privilege enabling code to allow enabling of multiple
privileges via one single function call.
Finally, I added the ProcessImageName function and updated the code in
tailscaled_windows.go to use that instead of directly calling the
underlying API.
All of these changes will be utilized by subsequent PRs pertaining to
this issue.
Updates https://github.com/tailscale/corp/issues/13998
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
We currently disable the exit-node drop down selector when the user is
in read-only mode, but we missed disabling the "Disable" button also.
Previously, it would display an error when clicked.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
Now that 1.54 has released, and the new web client will be included in
1.56, we can remove the need for the node capability. This means that
all 1.55 unstable builds, and then eventually the 1.56 build, will work
without setting the node capability.
The web client still requires the "webclient" user pref, so this does
NOT mean that the web client will be on by default for all devices.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This removes the dev/unstable build check for the --webclient flag on
`tailscale set`, so that it will be included in the next major stable
release (1.56)
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This prevents running more than one recursive resolution for the same
hostname in parallel, which can use excessive amounts of CPU when called
in a tight loop. Additionally, add tests that hit the network (when
run with a flag) to test the lookup behaviour.
Updates tailscale/corp#15261
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I39351e1d2a8782dd4c52cb04b3bd982eb651c81e
Causing issues building a stable release. Getting rid of the flag
for now because it was only available in unstable, can still be
turned on through localapi.
A #cleanup
Co-authored-by: Will Norris <will@tailscale.com>
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
return early if handler is nil. Go ahead and return the error from
handler, though in this case the caller isn't doing anything with it
(which has always been the case).
Updates #10177
Updates #10251
Signed-off-by: Will Norris <will@tailscale.com>
Tailscale serve maintains a set of listeners so that serve traffic from
the local device can be properly served when running in kernel
networking mode. #10177 refactored that logic so that it could be reused
by the internal web client as well. However, in my refactoring I missed
actually calling the serve handler to handle the traffic.
Updates #10177
Signed-off-by: Will Norris <will@tailscale.com>
`winutil.WTSGetActiveConsoleSessionId` only works for physical desktop
logins and does not return the session ID for RDP logins. We need to
`windows.WTSEnumerateSessions` and find the active session.
Fixes https://github.com/tailscale/corp/issues/15772
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Move Header component inside Router so that links are relative to the
router base URL.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
In production, the asset handler is receiving requests for pages like
/details, which results in a 404. Instead, if we know the requested file
does not exist, serve the main index page and let wouter route it
appropriately on the frontend.
Updates tailscale/corp/#14335
Signed-off-by: Will Norris <will@tailscale.com>
After logging in, the `?check=now` query string is still present if it
was passed. Reloading the page causes a new check mode to be triggered,
even though the user has an active session. Only trigger the automatic
check mode if the user is not already able to manage the device.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This prevents a panic in some cases where WebClientShutdown is called
multiple times.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
When we run tailscled under systemd, restarting the unit kills all child
processes, including "tailscale update". And during update, the package
manager will restart the tailscaled unit. Specifically on Debian-based
distros, interrupting `apt-get install` can get the system into a wedged
state which requires the user to manually run `dpkg --configure` to
recover.
To avoid all this, use `systemd-run` where available to run the
`tailscale update` process. This launches it in a separate temporary
unit and doesn't kill it when parent unit is restarted.
Also, detect when `apt-get install` complains about aborted update and
try to restore the system by running `dpkg --configure tailscale`. This
could help if the system unexpectedly shuts down during our auto-update.
Fixes https://github.com/tailscale/corp/issues/15771
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Simply reading the taildrop directory can pop up security dialogs
on platforms like macOS. Avoid this by only performing garbage collection
of partial and deleted files after the first received taildrop file,
which would have prompted the security dialog window.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This change exposes SilentDisco as a control knob, and plumbs it down to
magicsock.endpoint. No changes are being made to magicsock.endpoint
disco behavior, yet.
Updates #540
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Use the `qpkg_cli` to check for updates and install them. There are a
couple special things about this compare to other updaters:
* qpkg_cli can tell you when upgrade is available, but not what the
version is
* qpkg_cli --add Tailscale works for new installs, upgrades and
reinstalling existing version; even reinstall of existing version
takes a while
Updates #10178
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Some conditional paths may otherwise skip the hostinfo update, so kick
it off asynchronously as other code paths do.
Updates tailscale/corp#15437
Signed-off-by: James Tucker <james@tailscale.com>
We were incrementing the sftp metric on regular sessions
too, not just sftp.
Updates #cleanup
Change-Id: I63027a39cffb3e03397c6e4829b1620c10fa3130
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On unix systems, the check involves executing sudo, which is slow.
Instead of doing it for every incoming request, move the logic into
localapi serveServeConfig handler and do it as needed.
Updates tailscale/corp#15405
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
The app connector matches a configuration of "*.example.com" to mean any
sub-domain of example.com.
Updates #15437
Signed-off-by: James Tucker <james@tailscale.com>
This package is a wrapper for os/user that handles non-cgo builds,
gokrazy and user shells.
Updates tailscale/corp#15405
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
The local web client has the same characteristic as tailscale serve, in
that it needs a local listener to allow for connections from the local
machine itself when running in kernel networking mode.
This change renames and adapts the existing serveListener to allow it to
be used by the web client as well.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This was mostly already fixed already indirectly in earlier
commits but add a last second length check to this slice so
it can't ever OOB.
Fixes#7860
Change-Id: I31ac17fc93b5808deb09ff34e452fe37c87ddf3a
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The c2n part was broken because we were not looking up the tailscale
binary for that GOOS. The rest of the update was failing at the `pkg
upgrade` confirmation prompt. We also need to manually restart
tailscaled after update.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Fills /details page with real values, passed back from the /data
endpoint.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
io.Writer says you need to write completely on err=nil. (the result
int should be the same as the input buffer length)
We weren't doing that. We used to, but at some point the verbose
filtering was modifying buf before the final return of len(buf).
We've been getting lucky probably, that callers haven't looked at our
results and turned us into a short write error.
Updates #cleanup
Updates tailscale/corp#15664
Change-Id: I01e765ba35b86b759819e38e0072eceb9d10d75c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
As part of tailnet-lock netmap processing, the LocalBackend mutex
is unlocked so we can potentially make a network call. Its possible
(during shutdown or while the control client is being reset) for
b.cc to become nil before the lock is picked up again.
Fixes: #9554
Signed-off-by: Tom DNetto <tom@tailscale.com>
App connectors handle DNS requests for app domains over PeerAPI,
but a safety check verifies the requesting peer has at least permission
to send traffic to 0.0.0.0:53 (or 2000:: for IPv6) before handling the DNS
request. The correct filter rules are synthesized by the coordination server
and sent down, but the address needs to be part of the 'local net' for the
filter package to even bother checking the filter rules, so we set them here.
See: https://github.com/tailscale/corp/issues/11961 for more information.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates: ENG-2405
This change introduces a c2n endpoint that returns a map of domains to a
slice of resolved IP addresses for the domain.
Fixestailscale/corp#15657
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Check for root early, before we fetch the pkgs index. This avoids
several seconds delay for the command to tell you to sudo.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
For an operator user, require them to be able to `sudo tailscale` to use
`tailscale serve`. This is similar to the Windows elevated token check.
Updates tailscale/corp#15405
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Initial addition of device details view on the frontend. A little
more backend piping work to come to fill all of the detail fields,
for now using placeholders.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
We render the readonly view in two situations:
- the client is in login mode, and the device is connected
- the client is in manage mode, but the user does not yet have a session
If the user is not authenticated, and they are not currently on the
Tailscale IP address, render a "Manage" button that will take them to
the Tailcale IP of the device and immediately start check mode.
Still to do is detecting if they have connectivity to the Tailscale IP,
and disabling the button if not.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This change updates log messaging when cleaning up wireguard only peers.
This change also stops us unnecessarily attempting to clean up disco
pings for wireguard only endpoints.
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Previously had HMR websocket set to run from a different port
than the http proxy server. This was an old setting carried over
from the corp repo admin panel config. It's messing with hot
reloads when run from the tailscaled web client, as it keeps
causing the full page to refresh each time a connection is made.
Switching back to the default config here fixes things.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
If the status request to check for the preview node cap fails,
continue with starting up the legacy client.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
To safely request and drop privileges, runtime.Lock/UnlockOSThread and
windows.Impersonate/RevertToSelf should be called. Add these calls to
winutil.EnableCurrentThreadPrivilege so that callers don't need to worry
about it.
Updates https://github.com/tailscale/corp/issues/15488
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
In prep for making mapSession's lifetime not be 1:1 with a single HTTP
response's lifetime, this moves the inactivity timer watchdog out of
mapSession and into the caller that owns the streaming HTTP response.
(This is admittedly closer to how it was prior to the mapSession type
existing, but that was before we connected some dots which were
impossible to even see before the mapSession type broke the code up.)
Updates #7175
Change-Id: Ia108dac84a4953db41cbd30e73b1de4a2a676c11
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was a really a mutable field owned by mapSession that we didn't move
in earlier commits.
Once moved, it's then possible to de-func-ify the code and turn it into
a regular method rather than an installed optional hook.
Noticed while working to move map session lifetimes out of
Direct.sendMapRequest's single-HTTP-connection scope.
Updates #7175
Updates #cleanup
Change-Id: I6446b15793953d88d1cabf94b5943bb3ccac3ad9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Don't return CSP headers in dev mode, since that includes a bunch of
extra things like the vite server.
Allow images from any source, which is needed to load user profile
images.
Allow 'unsafe-inline' for various inline scripts and style react uses.
We can eliminate this by using CSP nonce or hash values, but we'll need
to look into the best way to handle that. There appear to be several
react plugins for this, but I haven't evaluated any of them.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
3d7fb6c21d dropped the explicit called to (*Client).connect when
its (*Client).WatchConnectionChanges got removed+refactored.
This puts it back, but in RunWatchConnectionLoop, before the call
to the (*Client).ServerPublicKey accessor, which is documented to
return the zero value (which is what broke us) on an unconnected
connection.
Plus some tests.
Fixestailscale/corp#15604
Change-Id: I0f242816f5ee4ad3bb0bf0400abc961dbe9f5fc8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
After running `tailscale web`, only disable the user pref if it was not
already previously set.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
Require that requests to servers in manage mode are made to the
Tailscale IP (either ipv4 or ipv6) or quad-100. Also set various
security headers on those responses. These might be too restrictive,
but we can relax them as needed.
Allow requests to /ok (even in manage mode) with no checks. This will be
used for the connectivity check from a login client to see if the
management client is reachable.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
(*Token).IsAdministrator is supposed to return true even when the user is
running with a UAC limited token. The idea is that, for the purposes of
this check, we don't care whether the user is *currently* running with
full Admin rights, we just want to know whether the user can
*potentially* do so.
We accomplish this by querying for the token's "linked token," which
should be the fully-elevated variant, and checking its group memberships.
We also switch ipn/ipnserver/(*Server).connIsLocalAdmin to use the elevation
check to preserve those semantics for tailscale serve; I want the
IsAdministrator check to be used for less sensitive things like toggling
auto-update on and off.
Fixes#10036
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Splits auth session creation into two new endpoints:
/api/auth/session/new - to request a new auth session
/api/auth/session/wait - to block until user has completed auth url
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
if the user pref and nodecap for the new web client are enabled, serve
the client over requests to 100.100.100.100. Today, that is just a
static page that lists the local Tailcale IP addresses.
For now, this will render the readonly full management client, with an
"access" button that sends the user through check mode. After
completing check mode, they will still be in the read-only view, since
they are not accessing the client over Tailscale.
Instead, quad100 should serve the lobby client that has a "manage"
button that will open the management client on the Tailscale IP (and
trigger check mode). That is something we'll fix in a subsequent PR in
the web client code itself.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
There was pre-existing additional usage for Exit Node DNS resolution via
PeerAPI, as well as new usage just introduced for App Connectors.
Fixes ENG-2324
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
Avoids the need to pipe a web client dev flag through the tailscaled
command.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
The existing read permission check looks like an oversight. Write seems
more appropriate for sining new nodes.
Updates https://github.com/tailscale/corp/issues/15506
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Adds a new Mode to the web server, indicating the specific
scenario the constructed server is intended to be run in. Also
starts filling this from the cli/web and ipn/ipnlocal callers.
From cli/web this gets filled conditionally based on whether the
preview web client node cap is set. If not set, the existing
"legacy" client is served. If set, both a login/lobby and full
management client are started (in "login" and "manage" modes
respectively).
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
In case there's a wild symlink in one of the target paths, we don't want
to accidentally delete too much. Limit `cleanupOldDownloads` to deleting
individual files only.
Updates https://github.com/tailscale/tailscale/issues/10082
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This completes the migration to setting up authentication state in the
client first before fetching any node data or rendering the client view.
Notable changes:
- `authorizeRequest` is now only enforced on `/api/*` calls (with the
exception of /api/auth, which is handled early because it's needed to
initially setup auth, particularly for synology)
- re-separate the App and WebClient components to ensure that auth is
completed before moving on
- refactor platform auth (synology and QNAP) to fit into this new
structure. Synology no longer returns redirect for auth, but returns
authResponse instructing the client to fetch a SynoToken
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
The design changed during integration and testing, resulting in the
earlier implementation growing in the appc package to be intended now
only for the sniproxy implementation. That code is moved to it's final
location, and the current App Connector code is now renamed.
Updates tailscale/corp#15437
Signed-off-by: James Tucker <james@tailscale.com>
After we're done installing, clean up the temp files. This prevents temp
volumes from filling up on hosts that don't reboot often.
Fixes https://github.com/tailscale/tailscale/issues/10082
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Now uses webClientAtomicBool as the source of truth for whether the web
client should be running in tailscaled, with it updated when either the
RunWebClient pref or CapabilityPreviewWebClient node capability changes.
This avoids requiring holding the LocalBackend lock on each call to
ShouldRunWebClient to check for the CapabilityPreviewWebClient value.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Clients optionally request private key filtering. If they don't, we
should require Write access for the user.
Updates https://github.com/tailscale/corp/issues/15506
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
In corp PR #14970 I updated the installer to set a security mitigation that
always forces system32 to the front of the Windows dynamic linker's search
path.
Unfortunately there are other products out there that, partying like it's
1995, drop their own, older version of wintun.dll into system32. Since we
look there first, we end up loading that old version.
We can fix this by preloading wintun using a fully-qualified path. When
wintun-go then loads wintun, the dynamic linker will hand it the module
that was previously loaded by us.
Fixes#10023, #10025, #10052
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Updates tailscale/tailscale#9222
plain k8s-operator should have hostinfo.App set to 'k8s-operator', operator with proxy should have it set to 'k8s-operator-proxy'. In proxy mode, we were setting the type after it had already been set to 'k8s-operator'
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Noticed both while re-reading this code.
Updates #cleanup
Change-Id: I3b70f1d5dc372853fa292ae1adbdee8cfc6a9a7b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The AppConnector is now configured by the mapcap from the control plane.
Updates tailscale/corp#15437
Signed-off-by: James Tucker <james@tailscale.com>
An EmbeddedAppConnector is added that when configured observes DNS
responses from the PeerAPI. If a response is found matching a configured
domain, routes are advertised when necessary.
The wiring from a configuration in the netmap capmap is not yet done, so
while the connector can be enabled, no domains can yet be added.
Updates tailscale/corp#15437
Signed-off-by: James Tucker <james@tailscale.com>
WebClientShutdown tries to acquire the b.mu lock, so run it in a go
routine so that it can finish shutdown after setPrefsLockedOnEntry is
finished. This is the same reason b.sshServer.Shutdown is run in a go
routine.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
When the /api/auth response indicates that synology auth is needed,
fetch the SynoToken and store it for future API calls. This doesn't yet
update the server-side code to set the new SynoAuth field.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
For now this is effectively a noop, since only the ManagementClientView
uses the auth data. That will change soon.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
The other IP types don't appear to be imported anymore, and after a scan
through I couldn't see any substantial usage of other representations,
so I think this TODO is complete.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
API v1 is compatible with helm v2 and v2 is not.
However, helm v2 (the Tiller deployment mechanism) was deprecated in 2020
and no-one should be using it anymore.
This PR also adds a CI lint test for helm chart
Updates tailscale/tailscale#9222
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Not all users know about our tracks and versioning scheme. They can be
confused when e.g. 1.52.0 is out but 1.53.0 is available. Or when 1.52.0
is our but 1.53 has not been built yet and user is on 1.51.x.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
For consistency and clarity around what the LocalBackend.web field
is used for.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
The derphttp client automatically reconnects upon failure.
RunWatchConnectionLoop called derphttp.Client.WatchConnectionChanges
once, but that wrapper method called the underlying
derp.Client.WatchConnectionChanges exactly once on derphttp.Client's
currently active connection. If there's a failure, we need to re-subscribe
upon all reconnections.
This removes the derphttp.Client.WatchConnectionChanges method, which
was basically impossible to use correctly, and changes it to be a
boolean field on derphttp.Client alongside MeshKey and IsProber. Then
it moves the call to the underlying derp.Client.WatchConnectionChanges
to derphttp's client connection code, so it's resubscribed on any
reconnect.
Some paranoia is then added to make sure people hold the API right,
not calling derphttp.Client.RunWatchConnectionLoop on an
already-started Client without having set the bool to true. (But still
auto-setting it to true if that's the first method that's been called
on that derphttp.Client, as is commonly the case, and prevents
existing code from breaking)
Fixestailscale/corp#9916
Supercedes tailscale/tailscale#9719
Co-authored-by: Val <valerie@tailscale.com>
Co-authored-by: Irbe Krumina <irbe@tailscale.com>
Co-authored-by: Anton Tolchanov <anton@tailscale.com>
Signed-off-by: Brad Fitzpatrick <brad@danga.com>
* Implement missing tests for sniproxy
* Wire sniproxy to new appc package
* Add support to tsnet for routing subnet router traffic into netstack, so it can be handled
Updates: https://github.com/tailscale/corp/issues/15038
Signed-off-by: Tom DNetto <tom@tailscale.com>
instead of starting a separate server listening on a particular port,
use the TCPHandlerForDst method to intercept requests for the special
web client port (currently 5252, probably configurable later).
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This is not currently exposed as a user-settable preference through
`tailscale up` or `tailscale set`. Instead, the preference is set when
turning the web client on and off via localapi. In a subsequent commit,
the pref will be used to automatically start the web client on startup
when appropriate.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
This commit makes the following structural changes to the web
client interface. No user-visible changes.
1. Splits login, legacy, readonly, and full management clients into
their own components, and pulls them out into their own view files.
2. Renders the same Login component for all scenarios when the client
is not logged in, regardless of legacy or debug mode. Styling comes
from the existing legacy login, which is removed from legacy.tsx
now that it is shared.
3. Adds a ui folder to hold non-Tailscale-specific components,
starting with ProfilePic, previously housed in app.tsx.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Allows for serving the web interface from tailscaled, with the
ability to start and stop the server via localapi endpoints
(/web/start and /web/stop).
This will be used to run the new full management web client,
which will only be accessible over Tailscale (with an extra auth
check step over noise) from the daemon. This switch also allows
us to run the web interface as a long-lived service in environments
where the CLI version is restricted to CGI, allowing us to manage
certain auth state in memory.
ipn/ipnlocal/web is stubbed out in ipn/ipnlocal/web_stub for
ios builds to satisfy ios restriction from adding "text/template"
and "html/template" dependencies.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
* ipn/localapi: add endpoint to handle APNS payloads
Fixes#9971. This adds a new `handle-push-message` local API endpoint. When an APNS payload is delivered to the main app, this endpoint can be used to forward the JSON body of the message to the backend, making a POST request.
cc @bradfitz
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
* Address comments from code review
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
---------
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
As of 2023-11-27, the official IP addresses for b.root-servers.net will
change to a new set, with the older IP addresses supported for at least
a year after that date. These IPs are already active and returning
results, so update these in our recursive DNS resolver package so as to
be ready for the switchover.
See: https://b.root-servers.org/news/2023/05/16/new-addresses.htmlFixes#9994
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I29e2fe9f019163c9ec0e62bdb286e124aa90a487
Terminating traffic to IPs which are not the native IPs of the node requires
the netstack subsystem to intercept trafic to an IP it does not consider local.
This PR switches on such interception. In addition to supporting such termination,
this change will also enable exit nodes and subnet routers when running in
userspace mode.
DO NOT MERGE until 1.52 is cut.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates: https://github.com/tailscale/corp/issues/15038
Another solution would be to copy the `.defaults` file alongside the
service file, and set the `EnvironmentFile` to point to that, but it
would still be hardcoded (as the `.defaults` file would be stored in the
Nix store), so I figured that this is a good solution until there is a
proper NixOS module.
Fixes#9995.
Signed-off-by: Cole Helbling <cole.helbling@determinate.systems>
Since the tailscale derivation already has a `pkgs` binding, we can
use `pkgs.lib`. Alternatively, we could have used `nixpkgs.lib`, as
`fileContents` doesn't need a system to use (anymore?).
Signed-off-by: Cole Helbling <cole.helbling@determinate.systems>
We were inconsistent whether we checked if the feature was already
enabled which we could do cheaply using the locally available status.
We would do the checks fine if we were turning on funnel, but not serve.
This moves the cap checks down into enableFeatureInteractive so that
are always run.
Updates #9984
Co-authored-by: Tyler Smalley <tyler@tailscale.com>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
For a serve config with a path handler, ensure the caller is a local administrator on Windows.
updates #8489
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
The branch name selector "*" doesn't match branches with a "/" in their
name. The vast majority of our PRs are against the main (or previously,
master) branch anyway, so this will have minimal impact. But in the rare
cases that we want to open a PR against a branch with a "/" in the name,
tests should still run.
```
gh pr list --limit 9999 --state all --json baseRefName | \
jq -cs '.[] | group_by(.baseRefName) |
map({ base: .[0].baseRefName, count: map(.baseRefName) | length}) |
sort_by(-.count) | .[]'
{"base":"main","count":4593}
{"base":"master","count":226}
{"base":"release-branch/1.48","count":4}
{"base":"josh-and-adrian-io_uring","count":3}
{"base":"release-branch/1.30","count":3}
{"base":"release-branch/1.32","count":3}
{"base":"release-branch/1.20","count":2}
{"base":"release-branch/1.26","count":2}
{"base":"release-branch/1.34","count":2}
{"base":"release-branch/1.38","count":2}
{"base":"Aadi/speedtest-tailscaled","count":1}
{"base":"josh/io_uring","count":1}
{"base":"maisem/hi","count":1}
{"base":"rel-144","count":1}
{"base":"release-branch/1.18","count":1}
{"base":"release-branch/1.2","count":1}
{"base":"release-branch/1.22","count":1}
{"base":"release-branch/1.24","count":1}
{"base":"release-branch/1.4","count":1}
{"base":"release-branch/1.46","count":1}
{"base":"release-branch/1.8","count":1}
{"base":"web-client-main","count":1}
```
Updates #cleanup
Signed-off-by: Will Norris <will@tailscale.com>
On Windows, the idiomatic way to check access on a named pipe is for
the server to impersonate the client on its current OS thread, perform
access checks using the client's access token, and then revert the OS
thread's access token back to its true self.
The access token is a better representation of the client's rights than just
a username/userid check, as it represents the client's effective rights
at connection time, which might differ from their normal rights.
This patch updates safesocket to do the aforementioned impersonation,
extract the token handle, and then revert the impersonation. We retain
the token handle for the remaining duration of the connection (the token
continues to be valid even after we have reverted back to self).
Since the token is a property of the connection, I changed ipnauth to wrap
the concrete net.Conn to include the token. I then plumbed that change
through ipnlocal, ipnserver, and localapi as necessary.
I also added a PermitLocalAdmin flag to the localapi Handler which I intend
to use for controlling access to a few new localapi endpoints intended
for configuring auto-update.
Updates https://github.com/tailscale/tailscale/issues/755
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Currently the checklocks step is not configured to fail, as we do not
yet have the appropriate annotations.
Updates tailscale/corp#14381
Signed-off-by: James Tucker <james@tailscale.com>
We prevent shodow configs when starting a foreground when a background serve config already exists for the serve type and port. This PR improves the messaging to let the user know how to remove the previous config.
Updates #8489
ENG-2314
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
The `--http` flag can not be used with Funnel, so we should remove it to remove confusion.
Updates #8489
ENG-2316
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
This PR changes the -https, -http, -tcp, and -tls-terminated-tcp
flags from string to int and also updates the validation to ensure
they fit the uint16 size as the flag library does not have a Uint16Var
method.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
The TestServeDevConfigMutations test has 63 steps that all run
under the same scope. This tests breaks them out into isolated
subtests that can be run independently.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Previously returned errTaggedSource in the case that of any tagged
source. Now distinguishing whether the source was local or remote.
We'll be presenting the two cases with varying copy on the frontend.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
In addition to the new policy keys for the new options, some
already-in-use but missing policy keys are also being added to
util/syspolicy.
Updates ENG-2133
Change-Id: Iad08ca47f839ea6a65f81b76b4f9ef21183ebdc6
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
We currently print out "run tailscale serve --help" when the subcmd
might be funnel. This PR ensures the right subcmd is passed.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
On `tailscale set --auto-update`, set the Sparkle plist option for it.
Also make macsys report not supporting auto-updates over c2n, since they
will be triggered by Sparkle locally.
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
A few people have run into issues with understanding why `--set-path` started in background mode, and/or why they couldn't use a path in foreground mode. This change allows `--set-path` to be used in either case (foreground or background).
updates #8489
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
When trying to set up multiple derper instances meshing with each
other, it turned out that while one can specify an alternative
listening port using the -a flag, the TLS hostname gets incorrectly
determined and includes the set alternative listening port as part of
the hostname. Thus, the TLS hostname validation always fails when the
-mesh-with values have ports.
Updates #9949
Signed-off-by: Thomas Kosiewski <thomas.kosiewski@loft.sh>
TestNewConn now passes as root on Linux. It wasn't closing the BPF
listeners and their goroutines.
The code is still a mess of two Close overlapping code paths, but that
can be refactored later. For now, make the two close paths more similar.
Updates #9945
Change-Id: I8a3cf5fb04d22ba29094243b8e645de293d9ed85
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
clientupdate.Updater will have a non-nil Update func in a few cases
where it doesn't actually perform an update:
* on Arch-like distros, where it prints instructions on how to update
* on macOS app store version, where it opens the app store page
Add a new clientupdate.Arguments field to cause NewUpdater to fail when
we hit one of these cases. This results in c2n updates being "not
supported" and `tailscale set --auto-update` returning an error.
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Prior to an earlier netstack bump this code used a string conversion
path to cover multiple cases of behavior seemingly checking for
unspecified addresses, adding unspecified addresses to v6. The behavior
is now crashy in netstack, as it is enforcing address length in various
areas of the API, one in particular being address removal.
As netstack is now protocol specific, we must not create invalid
protocol addresses - an address is v4 or v6, and the address value
contained inside must match. If a control path attempts to do something
otherwise it is now logged and skipped rather than incorrect addressing
being added.
Fixestailscale/corp#15377
Signed-off-by: James Tucker <james@tailscale.com>
* Fixes issue with template string not being provided in help text
* Updates background information to provide full URL, including path, to make it clear the source and destination
* Restores some tests
* Removes AllowFunnel in ServeConfig if no proxy exists for that port.
updates #8489
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
This PR adds the same set-raw from the old flow into the new one
so that users can continue to use it when transitioning into the new
flow.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
This PR fixes the isLegacyInvocation to better catch serve and
funnel legacy commands. In addition, it now also returns a string
that translates the old command into the new one so that users
can have an easier transition story.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
It would end up resetting whatever hostinfo we had constructed
and leave the backend statemachine in a broken state.
This fixes that by storing the PushDeviceToken on the LocalBackend
and populating it on Hostinfo before passing it to controlclient.
Updates tailscale/corp#8940
Updates tailscale/corp#15367
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The value being passed was the same as whats on b.hostinfo, so just
use that directly.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Go has no way to explicitly identify Go struct as effectively a tuple,
so staticcheck assumes any external use of unkeyed literals is wrong.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This PR allows you to do "tailscale serve -bg -https:4545 off" and it
will delete all handlers under it. It will also prompt you for a y/n in case
you wanted to delete a single port.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
When updating via c2n, `tailscale.exe update` runs from `tailscaled.exe`
which runs as SYSTEM. The MSI installer does not start the GUI when
running as SYSTEM. This results in Tailscale just existing on
auto-update, which is ungood.
Instead, always ask the MSI installer to not launch the GUI (via
`TS_NOLAUNCH` argument) and launch it manually with a token from the
current logged in user. The token code was borrowed from
d9081d6ba2/net/dns/wsl_windows.go (L207-L232)
Also, make some logging changes so that these issues are easier to debug
in the future.
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Users should delete proxies by deleting or modifying the k8s cluster resources
that they used to tell the operator to create they proxy. With this flow,
the tailscale operator will delete the associated device from the control.
However, in some cases users might have already deleted the device from the control manually.
Updates tailscale/tailscale#9773
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This adds a check to prevent changes to ServeConfig if tailscaled
is run with a Locked config.
Missed in 1fc3573446.
Updates #1412
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We no longer build Windows releases with cgo enabled, which
automatically turned off certstore support. Rather than re-enabling cgo,
we updated our fork of the certstore package to no longer require cgo.
This updates the package, cleans up how the feature is configured, and
removes the cgo build tag requirement.
Fixestailscale/corp#14797Fixestailscale/coral#118
Change-Id: Iaea34340761c0431d759370532c16a48c0913374
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
This commit makes two changes to the web client auth flow error
handling:
1. Properly passes back the error code from the noise request from
the localapi. Previously we were using io.Copy, which was always
setting a 200 response status code.
2. Clean up web client browser sessions on any /wait endpoint error.
This avoids the user getting in a stuck state if something goes
wrong with their auth path.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
In the sandboxed app from the app store, we cannot check
`/Library/Preferences/com.apple.commerce.plist` or run `softwareupdate`.
We can at most print a helpful message and open the app store page.
Also, reenable macsys update function to mark it as supporting c2n
updates. macsys support in `tailscale update` was fixed.
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Ensure that when a userspace proxy config is reloaded,
connections for any removed proxies are safely closed
Updates tailscale/tailscale#9725
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Stores ID from tailcfg.WebClientAuthResponse in browser session
data, and uses ID to hit control server /wait endpoint.
No longer need the control url cached, so removed that from Server.
Also added optional timeNow field, initially to manage time from
tests.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
It is possible that upon a cold-start, we enqueue a partial file
for deletion that is resumed shortly after startup.
If the file transfer happens to last longer than deleteDelay,
we will delete the partial file, which is unfortunate.
The client spent a long time uploading a file,
only for it to be accidentally deleted.
It's a very rare race, but also a frustrating one
if it happens to manifest.
Fix the code to only delete partial files that
do not have an active puts against it.
We also fix a minor bug in ResumeReader
where we read b[:blockSize] instead of b[:cs.Size].
The former is the fixed size of 64KiB,
while the latter is usually 64KiB,
but may be less for the last block.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This change refactors & moves the bulk of the app connector logic from
./cmd/sniproxy.
A future change will delete the delta in sniproxy and wire it to this type.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates: https://github.com/tailscale/corp/issues/15038
The progress printer was buggy where it would not print correctly
and some of the truncation logic was faulty.
The progress printer now prints something like:
go1.21.3.linux-amd64.tar.gz 21.53MiB 13.83MiB/s 33.88% ETA 00:00:03
where it shows
* the number of bytes transferred so far
* the rate of bytes transferred
(using a 1-second half-life for an exponentially weighted average)
* the progress made as a percentage
* the estimated time
(as calculated from the rate of bytes transferred)
Other changes:
* It now correctly prints the progress for very small files
* It prints at a faster rate (4Hz instead of 1Hz)
* It uses IEC units for byte quantities
(to avoid ambiguities of "kb" being kilobits or kilobytes)
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The `serve` command for TCP has always required the scheme of the target to be specified. However, when it's omitted the error message reported is misleading
```
error: failed to apply TCP serve: invalid TCP target "localhost:5900": missing port in address
```
Since we know the target is TCP, we shouldn't require it to be specified. This aligns with the changes for HTTP proxies in https://github.com/tailscale/tailscale/issues/8489closes#9855
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
The `off` subcommand removes a serve/funnel for the corresponding type and port. Previously, we were not providing this which would result in an error if someone was using something than the default https=443.
closes#9858
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
Initiates http/h2c transport for userspace proxy
backend lazily and at most once.
Updates tailscale/tailscale#9725
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Connects serveTailscaleAuth to the localapi webclient endpoint
and pipes auth URLs and session cookies back to the browser to
redirect users from the frontend.
All behind debug flags for now.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Updates userspace proxy to detect plaintext grpc requests
using the preconfigured host prefix and request's content
type header and ensure that these will be proxied over h2c.
Updates tailscale/tailscale#9725
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
Don't assume Linux lacks UDP_GRO support if it lacks UDP_SEGMENT
support. This mirrors a similar change in wireguard/wireguard-go@177caa7
for consistency sake. We haven't found any issues here, just being
overly paranoid.
Updates #cleanup
Signed-off-by: Jordan Whited <jordan@tailscale.com>
Previously, the test simply relied on:
defer close()
to cleanup file handles.
This works fine on Unix-based systems,
but not on Windows, which dislikes deleting files
where an open file handle continues to exist.
Fix the test by explicitly closing the file handle
after we are done with the resource.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
It's required as of the recent 5297bd2cff.
Updates #7894
Updates #9394 (sure would be nice)
Change-Id: Id6672408dd8a6c82dba71022c8763e589d789fcd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The LoadFunc loads a value and calls a user-provided function.
The utility of this method is to ensure that the map lock is held
while executing user-provided logic.
This allows us to solve TOCTOU bugs that would be nearly imposible
to the solve without this API.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We were previously using the netlink API to see if there are chains/rules that
already exist. This works fine in environments where there is either full
nftable support or no support at all. However, we have identified certain
environments which have partial nftable support and the only feasible way of
detecting such an environment is to try to create some of the chains that we
need.
This adds a check to create a dummy postrouting chain which is immediately
deleted. The goal of the check is to ensure we are able to use nftables and
that it won't error out later. This check is only done in the path where we
detected that the system has no preexisting nftable rules.
Updates #5621
Updates #8555
Updates #8762
Signed-off-by: Maisem Ali <maisem@tailscale.com>
These tests were broken at HEAD. CI currently does not run these
as root, will figure out how to do that in a followup.
Updates #5621
Updates #8555
Updates #8762
Signed-off-by: Maisem Ali <maisem@tailscale.com>
WaitGroup.Wait should not be concurrently called WaitGroup.Add.
In other words, we should not start new goroutines after shutodwn is called.
Thus, add a conditional to check that shutdown has not been called
before starting off a new waitAndDelete goroutine.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
While the previous logic was correct, it did not perform well.
Resuming is a dance between the client and server, where
1. the client requests hashes for a partial file,
2. the server then computes those hashes,
3. the client computes hashes locally and compares them.
4. goto 1 while the partial file still has data
While step 2 is running, the client is sitting idle.
While step 3 is running, the server is sitting idle.
By streaming over the block hash immediately after the server
computes it, the client can start checking the hash,
while the server works on the next hash (in a pipelined manner).
This performs dramatically better and also uses less memory
as we don't need to hold a list of hashes, but only need to
handle one hash at a time.
There are two detriments to this approach:
* The HTTP API relies on a JSON stream,
which is not a standard REST-like pattern.
However, since we implement both client and server,
this is fine.
* While the stream is on-going, we hold an open file handle
on the server side while the file is being hashed.
On really slow streams, this could hold a file open forever.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
Minor fixes:
* The branch for listing or hashing partial files was inverted.
* The host for peerapi call needs to be real (rather than bogus).
* Handle remote peers that don't support resuming.
* Make resume failures non-fatal (since we can still continue).
This was tested locally, end-to-end system test is future work.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
Two bug fixes:
1. when tailscale update is executed as root, `os.UserCacheDir` may
return an error because `$XDG_CACHE_HOME` and `$HOME` are not set;
fallback to `os.TempDir` in those cases
2. on some weird distros (like my EndeavourOS), `/usr/sbin` is just a
symlink to `/usr/bin`; when we resolve `tailscale` binary path from
`tailscaled`, allow `tailscaled` to be in either directory
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Moves request authorization back into Server.serve to be run at
the start of any request. Fixes Synology unstable track bug where
client would get stuck unable to auth due to not rendering the
Synology redirect auth html on index.html load.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
File resumption requires keeping partial files around for some time,
but we must still eventually delete them if never resumed.
Thus, we implement asynchronous file deletion, which could
spawn a background goroutine to delete the files.
We also use the same mechanism for deleting files on Windows,
where a file can't be deleted if there is still an open file handle.
We can enqueue those with the asynchronous file deleter as well.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
* cmd/k8s-operator: users can configure operator to set firewall mode for proxies
Users can now pass PROXY_FIREWALL_MODE={nftables,auto,iptables} to operator to make it create ingress/egress proxies with that firewall mode
Also makes sure that if an invalid firewall mode gets configured, the operator will not start provisioning proxy resources, but will instead log an error and write an error event to the related Service.
Updates tailscale/tailscale#9310
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
The change is being kept to a minimum to make a revert easy if necessary. After the release, we will go back for a final cleanup.
updates #8489
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
Previously we were just smushing together args and not trying
to parse the values at all. This resulted in the args to testwrapper
being limited and confusing.
This makes it so that testwrapper parses flags in the exact format as `go test`
command and passes them down in the provided order. It uses tesing.Init to
register flags that `go test` understands, however those are not the only
flags understood by `go test` (such as `-exec`) so we register these separately.
Updates tailscale/corp#14975
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This partially reverts commits a61a9ab087
and 7538f38671 and fully reverts
4823a7e591.
The goal of that commit was to reapply known config whenever the
container restarts. However, that already happens when TS_AUTH_ONCE was
false (the default back then). So we only had to selectively reapply the
config if TS_AUTH_ONCE is true, this does exactly that.
This is a little sad that we have to revert to `tailscale up`, but it
fixes the backwards incompatibility problem.
Updates tailscale/tailscale#9539
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The old code would always retain value `true` if it was set once, even
if you then change `prefs.AutoUpdate.Apply` to `false`.
Instead of using the previous value, use the default (envknob) value to
OR with.
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This change:
* adds a partial files peerAPI endpoint to get a list of partial files
* adds a helper function to extract the basename of a file
* updates the peer put peerAPI endpoint
* updates the file put localapi endpoint to allow resume functionality
Updates #14772
Signed-off-by: Rhea Ghosh <rhea@tailscale.com>
It seems to be implicated in a CPU consumption bug that's not yet
understood. Disable it until we understand.
Updates tailscale/corp#15261
Change-Id: Ia6d0c310da6464dda79a70fc3c18be0782812d3f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The Sparkle-based update is not quite working yet. Make `NewUpdater`
return `ErrUnsupported` for it to avoid the proliferation of exceptions
up the stack.
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Debug endpoint for the web client's auth flow to talk back to the
control server. Restricted behind a feature flag on control.
We will either be removing this debug endpoint, or renaming it
before launching the web client updates.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This commit changes the PostureChecking syspolicy key to be a
PreferenceOption(user-defined, always, never) instead of Bool.
This aligns better with the defaults implementation on macOS allowing
CLI arguments to be read when user-defined or no defaults is set.
Updates #tailscale/tailscale/5902
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Endeavour OS, at least, uses NetworkManager 1.44.2 and does
not use systemd-resolved behind the scenes at all. If we
find ourselves in that situation, return "direct" not
"systemd-resolved"
Fixes https://github.com/tailscale/tailscale/issues/9687
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
Move the compilation of everything to its own job too, separate
from test execution.
Updates #7894
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
They're slow. Make them their own job that can run in parallel.
Also, only run them in race mode. No need to run them on 386
or non-race amd64.
Updates #7894
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Regression from c15997511d. The callback could be run multiple times
from different endpoints.
Fixes#9801
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Misc cleanups and things noticed while working on #7894 and pulled out
of a separate change. Submitting them on their own to not distract
from later changes.
Updates #7894
Change-Id: Ie9abc8b88f121c559aeeb7e74db2aa532eb84d3d
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds support for parsing Range and Content-Range headers
according to RFC 7230. The package could be extended in the future
to handle other headers.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Perform the same m==nil check in Manager.{PartialFiles,HashPartialFile}
as we do in the other methods.
Fix HashPartialFile is properly handle a length of -1.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We add the following API:
* type FileChecksums
* type Checksum
* func Manager.PartialFiles
* func Manager.HashPartialFile
* func ResumeReader
The Manager methods provide the ability to query for partial files
and retrieve a list of checksums for a given partial file.
The ResumeReader function is a helper that wraps an io.Reader
to discard content that is identical locally and remotely.
The FileChecksums type represents the checksums of a file
and is safe to JSON marshal and send over the wire.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
We were eagerly doing a synchronous renewal of the cert while
trying to serve traffic. Instead of that, just do the cert
renewal in the background and continue serving traffic as long
as the cert is still valid.
This regressed in c1ecae13ab when
we introduced ARI support and were trying to make the experience
of `tailscale cert` better. However, that ended up regressing
the experience for tsnet as it would not always doing the renewal
synchronously.
Fixes#9783
Signed-off-by: Maisem Ali <maisem@tailscale.com>
In almost every single use of Clock, there is a default behavior
we want to use when the interface is nil,
which is to use the the standard time package.
The Clock interface exists only for testing,
and so tests that care about mocking time
can adequately plumb the the Clock down the stack
and through various data structures.
However, the problem with Clock is that there are many
situations where we really don't care about mocking time
(e.g., measuring execution time for a log message),
where making sure that Clock is non-nil is not worth the burden.
In fact, in a recent refactoring, the biggest pain point was
dealing with nil-interface panics when calling tstime.Clock methods
where mocking time wasn't even needed for the relevant tests.
This required wasted time carefully reviewing the code to
make sure that tstime.Clock was always populated,
and even then we're not statically guaranteed to avoid a nil panic.
Ideally, what we want are default methods on Go interfaces,
but such a language construct does not exist.
However, we can emulate that behavior by declaring
a concrete type that embeds the interface.
If the underlying interface value is nil,
it provides some default behavior (i.e., use StdClock).
This provides us a nice balance of two goals:
* We can plumb tstime.DefaultClock in all relevant places
for use with mocking time in the tests that care.
* For all other logic that don't care about,
we never need to worry about whether tstime.DefaultClock
is nil or not. This is especially relevant in production code
where we don't want to panic.
Longer-term, we may want to perform a large-scale change
where we rename Clock to ClockInterface
and rename DefaultClock to just Clock.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Changes made:
* Move all HTTP related functionality from taildrop to ipnlocal.
* Add two arguments to taildrop.Manager.PutFile to specify
an opaque client ID and a resume offset (both unused for now).
* Cleanup the logic of taildrop.Manager.PutFile
to be easier to follow.
* Implement file conflict handling where duplicate files are renamed
(e.g., "IMG_1234.jpg" -> "IMG_1234 (2).jpg").
* Implement file de-duplication where "renaming" a partial file
simply deletes it if it already exists with the same contents.
* Detect conflicting active puts where a second concurrent put
results in an error.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
We were too strict and required the user not specify the host field at all
in the ingress rules, but that degrades compatibility with existing helm charts.
Relax the constraint so that rule.Host can either be empty, or match the tls.Host[0]
value exactly.
Fixes#9548
Signed-off-by: Maisem Ali <maisem@tailscale.com>
These birds have been visually identified as having tails. Science
prevails.
Updates tailscale/corp#9599
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Replace the deprecated var with the one in docs to avoid confusion.
Introduced in 335a5aaf9a.
Updates #8317Fixes#9764
Signed-off-by: Maisem Ali <maisem@tailscale.com>
IPProto has been being converted to and from string formats in multiple
locations with variations in behavior. TextMarshaller and JSONMarshaller
implementations are now added, along with defined accepted and preferred
formats to centralize the logic into a single cross compatible
implementation.
Updates tailscale/corp#15043Fixestailscale/corp#15141
Signed-off-by: James Tucker <james@tailscale.com>
These log paths were actually unexpected until the refactor in
fe95d81b43. This moves the logs
to the callsites where they are actually unexpected.
Fixes#9670
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The current structure meant that we were embedding netstack in
the tailscale CLI and in the GUIs. This removes that by isolating
the checksum munging to a different pkg which is only called from
`net/tstun`.
Fixes#9756
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This migrates containerboot to reuse the NetfilterRunner used
by tailscaled instead of manipulating iptables rule itself.
This has the added advantage of now working with nftables and
we can potentially drop the `iptables` command from the container
image in the future.
Updates #9310
Co-authored-by: Irbe Krumina <irbe@tailscale.com>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This allows using the fake runner in different packages
that need to manage filter rules.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
For the app connector use-case, it doesnt make sense to use listeners, because then you would
need to register thousands of listeners (for each proto/service/port combo) to handle ranges.
Instead, we plumb through the TCPHandlerForFlow abstraction, to avoid using the listeners
abstraction that would end up being a bit messy.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates: https://github.com/tailscale/corp/issues/15038
Tailscale attempts to determine if resolvconf or openresolv
is in use by running `resolvconf --version`, under the assumption
this command will error when run with Debian's resolvconf. This
assumption is no longer true and leads to the wrong commands being
run on newer versions of Debian with resolvconf >= 1.90. We can
now check if the returned version string starts with "Debian resolvconf"
if the command is successful.
Fixes#9218
Signed-off-by: Galen Guyer <galen@galenguyer.com>
Just a refactor to consolidate the firewall detection logic in a single
package so that it can be reused in a later commit by containerboot.
Updates #9310
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Add an explicit accept rule for input to the tun interface, as a mirror
to the explicit rule to accept output from the tun interface.
The rule matches any packet in to our tun interface and accepts it, and
the rule is positioned and prioritized such that it should be evaluated
prior to conventional ufw/iptables/nft rules.
Updates #391Fixes#7332
Updates #9084
Signed-off-by: James Tucker <james@tailscale.com>
This is only relevant for unstable releases and local builds. When local
version is newer than upstream, abort release.
Also, re-add missing newlines in output that were missed in
https://github.com/tailscale/tailscale/pull/9694.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This will be returned from the upcoming control endpoints for doing web
client session authentication.
Updates tailscale/corp#14335
Signed-off-by: Will Norris <will@tailscale.com>
The whois handler was documented as taking IP (e.g. 100.101.102.103)
or IP:port (e.g. usermode 127.0.0.1:1234) but that got broken at some point
and we started requiring a port always. Fix that.
Also, found in the process of adding tests: fix the CapMap lookup in
userspace mode (it was always returning the caps of 127.0.0.1 in
userspace mode). Fix and test that too.
Updates #9714
Change-Id: Ie9a59744286522fa91c4b70ebe89a1e94dbded26
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit adds support for getting serial numbers from SMBIOS
on Windows/Linux (and BSD) using go-smbios.
Updates #5902
Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
Record the number of MTU probes sent, the total bytes sent, the number of times
we got a successful return from an MTU probe of a particular size, and the max
MTU recorded.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Automatically probe the path MTU to a peer when peer MTU is enabled, but do not
use the MTU information for anything yet.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
The script depends on a sufficiently recent start-stop-daemon as to
provide the `-m` and `--remove-pidfile` flags.
Updates #9502
Signed-off-by: James Tucker <james@tailscale.com>
I was reviewing some code that was performing this by hand, and wanted
to suggest using syncs.Map, however as the code in question was
allocating a non-trivial structure this would be necessary to meet the
target.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
Changes made:
* Unexport declarations specific to internal taildrop functionality.
* Document all exported functionality.
* Move TestRedactErr to the taildrop package.
* Rename and invert Handler.DirectFileDoFinalRename as AvoidFinalRename.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
In case cli.Stdout/Stderr get overriden, all CLI output should use them
instead of os.Stdout/Stderr. Update the `update` command to follow this
pattern.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This is being moved to taildrop, so clean it up to stop depending
on so much unreleated functionality by removing a dependency
on peerAPIHandler.
Updates tailscale/corp#14772
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
Add available update message in "tailscale up" output. Also update the
message in "tailscale status" to match and mention auto-update.
Updates https://github.com/tailscale/tailscale/issues/755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Over time all taildrop functionality will be contained in the
taildrop package. This will include end to end unit tests. This is
simply the first smallest piece to move over.
There is no functionality change in this commit.
Updates tailscale/corp#14772
Signed-off-by: Rhea Ghosh <rhea@tailscale.com>
Co-authored-by: Joseph Tsai <joetsai@tailscale.com>
Adds `getTailscaleBrowserSession` to pull the user's session out of
api requests, and `serveTailscaleAuth` to provide the "/api/auth"
endpoint for browser to request auth status and new sessions.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Advertise it on Android (it looks like it already works once advertised).
And both advertise & likely fix it on iOS. Yet untested.
Updates #9672
Change-Id: If3b7e97f011dea61e7e75aff23dcc178b6cf9123
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This optionally uploads MAC address(es) to control, then adds a
c2n handler so control can ask a node to send a WoL packet.
Updates #306
RELNOTE=now supports waking up peer nodes on your LAN via Wake-on-LAN packets
Change-Id: Ibea1275fcd2048dc61d7059039abfbaf1ad4f465
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The Port.Pid was always more of an implementation detail on some
platforms and isn't necessary on Linux so it was never populated.
(Nothing outside the portlist package ever used it)
But might as well populate it for consistency since we have it in
memory and its absence confused people.
Updates #cleanup
Change-Id: I869768a75c9fedeff242a5452206e2b2947a17cb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adds browser session cache, to be used to store sessions for the
full management web client.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Partially reverts 1bd3edbb46 (but keeps part of it)
iptables is almost always required but not strictly needed. Even if
you can technically run Tailscale without it (by manually configuring
nftables or userspace mode), we still now mark this as "Depends"
because our previous experiment in
https://github.com/tailscale/tailscale/issues/9236 of making it only
Recommends caused too many problems. Until our nftables table is more
mature, we'd rather err on the side of wasting a little disk by
including iptables for people who might not need it rather than
handle reports of it being missing.
Updates #9236
Change-Id: I86cc8aa3f78dafa0b4b729f55fb82eef6066be1c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Instead of just falling back to making a TCP query to an upstream DNS
server when the UDP query returns a truncated query, also start a TCP
query in parallel with the UDP query after a given race timeout. This
ensures that if the upstream DNS server does not reply over UDP (or if
the response packet is blocked, or there's an error), we can still make
queries if the server replies to TCP queries.
This also adds a new package, util/race, to contain the logic required for
racing two different functions and returning the first non-error answer.
Updates tailscale/corp#14809
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I4311702016c1093b1beaa31b135da1def6d86316
Make the 'tailscale debug component-logs' command print the component names for
which extra logging can be turned on, for easier discoverability of debug
functions.
Updates #cleanup
Co-authored-by: Paul Scott <paul@tailscale.com>
Signed-off-by: Val <valerie@tailscale.com>
Implements the ability for the address-rewriting code to support rewriting IPv6 addresses.
Specifically, UpdateSrcAddr & UpdateDstAddr.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates https://github.com/tailscale/corp/issues/11202
Now that corp is updated, remove the shim code to bridge the rename from
DefaultMTU() to DefaultTUNMTU.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
When sending a CLI ping with a specific size, continue to probe all possible UDP
paths to the peer until we find one with a large enough MTU to accommodate the
ping. Record any peer path MTU information we discover (but don't use it for
anything other than CLI pings).
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Add a field to record the wire MTU of the path to this address to the
addrLatency struct and rename it addrQuality.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Then use it in tailcfg which had it duplicated a couple times.
I think we have it a few other places too.
And use slices.Equal in wgengine/router too. (found while looking for callers)
Updates #cleanup
Change-Id: If5350eee9b3ef071882a3db29a305081e4cd9d23
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We had a misstep with the semantics when applying an optimization that
showed up in the roll into corp. This test ensures that case and related
cases must be retained.
Updates #9410
Updates #9601
Signed-off-by: James Tucker <james@tailscale.com>
We should be able to freely run `./tool/go generate ./...`, but we're
continually dodging this particular generator. Instead of constantly
dodging it, let's just remove it.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
This reverts commit ee90cd02fd.
The outcome is not identical for empty slices. Cloner really needs
tests!
Updates #9601
Signed-off-by: James Tucker <james@tailscale.com>
It's no conspiracy that I love learning about new words.
Updates tailscale/corp#14698
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
go-billy is held back at v5.4.1 in order to avoid a newly introduced
subdependency that is not compatible with plan9.
Updates #8043
Signed-off-by: James Tucker <james@tailscale.com>
Prevent future problems like we earlier with go.mod replace directives
(e.g. removing our certstore replace in 6d6cf88d82 or wireguard-go
in ea5ee6f87c, both of which were reactions to problems caused by
go.mod replace in non-root modules, often because people are using tsnet
as a library from another module)
Updates #cleanup
Change-Id: I766715cfa7ce7021460ba4933bd2fa977c3081d2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add a more generalized package for getting policies.
Updates tailcale/corp#10967
Signed-off-by: Claire Wang <claire@tailscale.com>
Co-authored-by: Adrian Dewhurst <adrian@tailscale.com>
Thanks to @qur and @eric for debugging!
Fixes#6973
Change-Id: Ib2cf8f030cf595cc73dd061c72e78ac19f5fae5d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1.50.0 switched containerboot from using `tailscale up`
to `tailscale login`. A side-effect is that a re-usable
authkey is now re-applied on every boot by `tailscale login`,
where `tailscale up` would ignore an authkey if already
authenticated.
Though this looks like it is changing the default, in reality
it is setting the default to match what 1.48 and all
prior releases actually implemented.
Fixes https://github.com/tailscale/tailscale/issues/9539
Fixes https://github.com/tailscale/corp/issues/14953
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
UI updates staged behind debug mode flags. Initial new views added
in app.tsx, rendered based on the current debug setting.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
So we can experiment with disabling static linking for tests in CI to
make GitHub Actions output less spammy.
Updates tailscale/corp#13113
Signed-off-by: Brad Fitzpatrick <brad@danga.com>
Adds new LoginOnly server option and swaps out API handler depending
on whether running in login mode or full web client mode.
Also includes some minor refactoring to the synology/qnap authorization
logic to allow for easier sharing between serveLoginAPI and serveAPI.
Updates tailscale/corp#14335
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
These were missed when adding NodeCapMap and resulted
in tsnet binaries not being able to turn on funnel.
Fixes#9566
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Control sends ExitNodeDNSResolvers when configured for IsWireGuardOnly
nodes that are to be used as the default resolver with a lower
precedence than split DNS, and a lower precedence than "Override local
DNS", but otherwise before local DNS is used when the exit node is in
use.
Neither of the below changes were problematic, but appeared so alongside
a number of other client and external changes. See tailscale/corp#14809.
Reland ea9dd8fabc.
Reland d52ab181c3.
Updates #9377
Updates tailscale/corp#14809
Signed-off-by: James Tucker <james@tailscale.com>
Appears to be a missing nil handling case. I looked back over other
usage of findRule and the others all have nil guards. findRule returns
nil when no rules are found matching the arguments.
Fixes#9553
Signed-off-by: James Tucker <james@tailscale.com>
Remove the "JSON" ending, we no longer have a non-JSON version,
it was removed in d74c771 when we switched from the legacy web
client to React.
Also combine getNodeData into serveGetNodeData now that serveGetNodeData
is the single caller of getNodeData.
A #cleanup
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Prepare for path MTU discovery by splitting up the concept of
DefaultMTU() into the concepts of the Tailscale TUN MTU, MTUs of
underlying network interfaces, minimum "safe" TUN MTU, user configured
TUN MTU, probed path MTU to a peer, and maximum probed MTU. Add a set
of likely MTUs to probe.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Use buffer pools for UDP packet forwarding to prepare for increasing the
forwarded UDP packet size for peer path MTU discovery.
Updates #311
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Val <valerie@tailscale.com>
Ensure that when there is an event on a Tailscale managed Ingress or Service child resource, the right parent type gets reconciled
Updates tailscale/tailscale#502
Signed-off-by: Irbe Krumina <irbe@tailscale.com>
This PR ensures zombie foregrounds are shutdown if a new
ServeConfig is created that wipes the ongoing foreground ones.
For example, "tailscale serve|funnel reset|off" should close
all open sessions.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
We weren't correctly retrying truncated requests to an upstream DNS
server with TCP. Instead, we'd return a truncated request to the user,
even if the user was querying us over TCP and thus able to handle a
large response.
Also, add an envknob and controlknob to allow users/us to disable this
behaviour if it turns out to be buggy (✨ DNS ✨).
Updates #9264
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ifb04b563839a9614c0ba03e9c564e8924c1a2bfd
For loading testing & profiling the cost of full netmap updates.
Updates #1909
Change-Id: I0afdf5de9967f8d95c7f81d5b531ed1c92c3208f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Prepare for path MTU discovery by splitting up the concept of
DefaultMTU() into the concepts of the Tailscale TUN MTU, MTUs of
underlying network interfaces, minimum "safe" TUN MTU, user configured
TUN MTU, probed path MTU to a peer, and maximum probed MTU. Add a set
of likely MTUs to probe.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Use buffer pools for UDP packet forwarding to prepare for increasing the
forwarded UDP packet size for peer path MTU discovery.
Updates #311
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Val <valerie@tailscale.com>
Update github.com/go-json-experiment/json to the latest version
and fix the build in light of some breaking API changes.
Updates #cleanup
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The test was sending SIGKILL to containerboot, which results in no
signal propagation down to the bash script that is running as a child
process, thus it leaks.
Minor changes to the test daemon script, so that it cleans up the socket
that it creates on exit, and spawns fewer processes.
Fixestailscale/corp#14833
Signed-off-by: James Tucker <james@tailscale.com>
We're going to need to build a DLL containing custom actions for the installer.
This patch adds the foundations of that capability to dist and gocross.
Updates https://github.com/tailscale/corp/issues/13998
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Replace CanPMTUD() with ShouldPMTUD() to check if peer path MTU discovery should
be enabled, in preparation for adding support for enabling/disabling peer MTU
dynamically.
Updated #311
Signed-off-by: Val <valerie@tailscale.com>
Add an enable/disable argument to setDontFragment() in preparation for dynamic
enable/disable of peer path MTU discovery. Add getDontFragment() to get the
status of the don't fragment bit from a socket.
Updates #311
Co-authored-by: James Tucker <james@tailscale.com>
Signed-off-by: Val <valerie@tailscale.com>
Use IPV6_MTU_DISCOVER for setting don't fragment on IPv6 sockets on Linux (was
using IP_MTU_DISCOVER, the IPv4 arg).
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
Make the debugknob variable name for enabling peer path MTU discovery match the
env variable name.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
One Quad9 IPv6 address was incorrect, and an additional group needed
adding. Additionally I checked Cloudflare and included source reference
URLs for both.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
In typical k8s setups, the MTU configured on the eth0 interfaces is typically 1500 which
results in packets being dropped when they make it to proxy pods as the tailscale0 interface
has a 1280 MTU.
As the primary use of this functionality is TCP, add iptables based MSS clamping to allow
connectivity.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This would've prevented #9470.
This used to pass, fails as of 9538e9f970, and passes again
once #9472 is in.
Updates #9470
Change-Id: Iab97666f7a318432fb3b6372a177ab50c55d4697
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
9538e9f970 broke LocalBackend.WhoIs
where you can no longer lookup yourself in WhoIs.
This occurs because the LocalBackend.peers map only contains peers.
If we fail to lookup a peer, double-check whether it is ourself.
Fixes#9470
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
It was tailscale.com/ts-tailnet-target-ip, which was pretty
redundant. Change it to tailscale.com/tailnet-ip.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The initial implementation directly mirrored the behavior of Tailscale
exit nodes, where the WireGuard exit node DNS took precedence over other
configuration.
This adjusted implementation treats the WireGuard DNS
resolvers as a lower precedence default resolver than the tailnet
default resolver, and allows split DNS configuration as well.
This also adds test coverage to the existing DNS selection behavior with
respect to default resolvers and split DNS routes for Tailscale exit
nodes above cap 25. There may be some refinement to do in the logic in
those cases, as split DNS may not be working as we intend, though that
would be a pre-existing and separate issue.
Updates #9377
Signed-off-by: James Tucker <james@tailscale.com>
It might as well have been spewing out gibberish. This adds
a nicer output format for us to be able to read and identify
whats going on.
Sample output
```
natV4Config{nativeAddr: 100.83.114.95, listenAddrs: [10.32.80.33], dstMasqAddrs: [10.32.80.33: 407 peers]}
```
Fixestailscale/corp#14650
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Fixestailscale/corp#14747
Signed-off-by: David Anderson <danderson@tailscale.com>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: David Anderson <danderson@tailscale.com>
This PR plumbs through awareness of an IPv6 SNAT/masquerade address from the wire protocol
through to the low-level (tstun / wgengine). This PR is the first in two PRs for implementing
IPv6 NAT support to/from peers.
A subsequent PR will implement the data-plane changes to implement IPv6 NAT - this is just plumbing.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates ENG-991
This should allow us to gather a bit more information about errors that
we encounter when creating UPnP mappings. Since we don't have a
"LabelMap" construction for clientmetrics, do what sockstats does and
lazily register a new metric when we see a new code.
Updates #9343
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ibb5aadd6138beb58721f98123debcc7273b611ba
Like PeerCapMap, add a field to `tailcfg.Node` which provides
a map of Capability to raw JSON messages which are deferred to be
parsed later by the application code which cares about the specific
capabilities. This effectively allows us to prototype new behavior
without having to commit to a schema in tailcfg, and it also opens up
the possibilities to develop custom behavior in tsnet applications w/o
having to plumb through application specific data in the MapResponse.
Updates #4217
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This adds a new RawMessage type backed by string instead of the
json.RawMessage which is backed by []byte. The byte slice makes
the generated views be a lot more defensive than the need to be
which we can get around by using a string instead.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
And convert all callers over to the methods that check SelfNode.
Now we don't have multiple ways to express things in tests (setting
fields on SelfNode vs NetworkMap, sometimes inconsistently) and don't
have multiple ways to check those two fields (often only checking one
or the other).
Updates #9443
Change-Id: I2d7ba1cf6556142d219fae2be6f484f528756e3c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This PR fixes a bug to make sure that we don't allow two configs
exist with duplicate ports
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
We have some flaky integration tests elsewhere that have no one place
to ask about the state of the world. This makes LocalBackend be that
place (as it's basically there anyway) but doesn't yet add the ForTest
accessor method.
This adds a LocalBackend.peers map[NodeID]NodeView that is
incrementally updated as mutations arrive. And then we start moving
away from using NetMap.Peers at runtime (UpdateStatus no longer uses
it now). And remove another copy of NodeView in the LocalBackend
nodeByAddr map. Change that to point into b.peers instead.
Future changes will then start streaming whole-node-granularity peer
change updates to WatchIPNBus clients, tracking statefully per client
what each has seen. This will get the GUI clients from receiving less
of a JSON storm of updates all the time.
Updates #1909
Change-Id: I14a976ca9f493bdf02ba7e6e05217363dcf422e5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
NetworkMap.Addresses is redundant with the SelfNode.Addresses. This
works towards a TODO to delete NetworkMap.Addresses and replace it
with a method.
This is similar to #9389.
Updates #cleanup
Change-Id: Id000509ca5d16bb636401763d41bdb5f38513ba0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* Remove unnecessary mutexes (there's no concurrency)
* Simplify LocalBackend.UpdateStatus using the StatusBuilder.WantPeers
field that was added in 0f604923d3, removing passing around some
method values into func args. And then merge two methods.
More remains, but this is a start.
Updates #9433
Change-Id: Iaf2d7ec6e4e590799f00bae185465a4fd089b822
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This enables installing default resolvers specified by
tailcfg.Node.ExitNodeDNSResolvers when the exit node is selected.
Updates #9377
Signed-off-by: James Tucker <james@tailscale.com>
Tailscale exit nodes provide DNS service over the peer API, however
IsWireGuardOnly nodes do not have a peer API, and instead need client
DNS parameters passed in their node description.
For Mullvad nodes this will contain the in network 10.64.0.1 address.
Updates #9377
Signed-off-by: James Tucker <james@tailscale.com>
The kube-apiserver proxy in the operator would only run in
auth proxy mode but thats not always desirable. There are
situations where the proxy should just be a transparent
proxy and not inject auth headers, so do that using a new
env var APISERVER_PROXY and deprecate the AUTH_PROXY env.
THe new env var has three options `false`, `true` and `noauth`.
Updates #8317
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The following IPs are not used anymore: 193.19.108.2 and 193.19.108.3.
All of the servers are now named consistently under dns.mullvad.net.
Several new servers were added.
https://mullvad.net/en/help/dns-over-https-and-dns-over-tls/
Updates #5416
Updates #9345
Signed-off-by: James Tucker <james@tailscale.com>
tailcfg.Node zero-value clone equality checks failed when I added a
[]*foo to the structure, as the zero value and it's clone contained a
different slice header.
Updates #9377
Updates #9408
Signed-off-by: James Tucker <james@tailscale.com>
This PR adds validations for the new new funnel/serve
commands under the following rules:
1. There is always a single config for one port (bg or fg).
2. Foreground configs under the same port cannot co-exists (for now).
3. Background configs can change as long as the serve type is the same.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Currently slack messages for errors fail:
https://github.com/tailscale/tailscale/actions/runs/6159104272/job/16713248204
```
Error: Unexpected token
in JSON at position 151
```
This is likely due to the line break in the text. Restructure the
message to use separate title/text and fix the slack webhook body.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This PR uses the etag/if-match pattern to ensure multiple calls
to SetServeConfig are synchronized. It currently errors out and
asks the user to retry but we can add occ retries as a follow up.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
It became required as of 6e967446e4
Updates #8052
Change-Id: I08d100534254865293c1beca5beff8e529e4e9ac
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It has one user (LocalBackend) which can ask magicsock itself.
Updates #cleanup
Change-Id: I8c03cbb1e5ba57b0b442621b5fa467030c14a2e2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
General cleanup and additional test coverage of WIP code.
* use enum for serveType
* combine instances of ServeConfig access within unset
* cleanMountPoint rewritten into cleanURLPath as it only handles URL paths
* refactor and test expandProxyTargetDev
> **Note**
> Behind the `TAILSCALE_USE_WIP_CODE` flag
updates #8489
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
(continuing the mission of removing rando methods from the Engine
interface that we don't need anymore)
Updates #cleanup
Change-Id: Id5190917596bf04d7185c3b331a852724a3f5a16
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We always have one. Stop pretending we might not.
Instead, add one early panic in NewLocalBackend if we actually don't.
Updates #cleanup
Change-Id: Iba4b78ed22cb6248e59c2b01a79355ca7a200ec8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was only used by Android, until
https://github.com/tailscale/tailscale-android/pull/131
which does the call to the netMon directly instead.
Updates #cleanup
Change-Id: Iab8a1d8f1e63250705835c75f40e2cd8c1c4d5b8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
LocalBackend can talk to magicsock on its own to do this without
the "Engine" being involved.
(Continuing a little side quest of cleaning up the Engine
interface...)
Updates #cleanup
Change-Id: I8654acdca2b883b1bd557fdc0cfb90cd3a418a62
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This logs that the gateway/self IP address has changed if one of the new
values differs.
Updates #8992
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I0919424b68ad97fbe1204dd36317ed6f5915411f
I missed this in 343c0f1031 and I guess we don't have integration
tests for wasm. But it compiled! :)
Updates #fixup to a #cleanup
Change-Id: If147b90bab254d144ec851a392e8db10ab97f98e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It had exactly one user: netstack. Just have LocalBackend notify
netstack when here's a new netmap instead, simplifying the bloated
Engine interface that has grown a bunch of non-Engine-y things.
(plenty of rando stuff remains after this, but it's a start)
Updates #cleanup
Change-Id: I45e10ab48119e962fc4967a95167656e35b141d8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds a new integration test with two nodes where the first gets a
incremental MapResponse (with only PeersRemoved set) saying that the
second node disappeared.
This extends the testcontrol package to support sending raw
MapResponses to nodes.
Updates #1909
Change-Id: Iea0c25c19cf0d72b52dba5a46d01b5cc87b9b39d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Currently only the top four most popular changes: endpoints, DERP
home, online, and LastSeen.
Updates #1909
Change-Id: I03152da176b2b95232b56acabfb55dcdfaa16b79
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
DSM6 does not automatically restart packages on install, we have to do
it explicitly.
Also, DSM6 has a filter for publishers in Package Center. Make the error
message more helpful when update fails because of this filter not
allowing our package.
Fixes#9361
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Some routers don't support lease times for UPnP portmapping; let's fall
back to adding a permanent lease in these cases. Additionally, add a
proper end-to-end test case for the UPnP portmapping behaviour.
Updates #9343
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I17dec600b0595a5bfc9b4d530aff6ee3109a8b12
I missed connecting some controlknobs.Knobs pieces in 4e91cf20a8
resulting in that breaking control knobs entirely.
Whoops.
The fix in ipn/ipnlocal (where it makes a new controlclient) but to
atone, I also added integration tests. Those integration tests use
a new "tailscale debug control-knobs" which by itself might be useful
for future debugging.
Updates #9351
Change-Id: Id9c89c8637746d879d5da67b9ac4e0d2367a3f0d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This PR adds optimistic concurrency control in the local client and
api in order to ensure multiple writes of the ServeConfig do not
conflict with each other.
Updates #9273
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
We're trying to start using that monster type less and eventually get
rid of it.
Updates #1909
Change-Id: I8e1e725bce5324fb820a9be6c7952767863e6542
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I guess we missed this one earlier when we unified the various
copies into set.HandleSet.
Updates #cleanup
Change-Id: I7e6de9ce16e8fc4846abf384dfcc8eaec4d99e60
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is both more efficient (because the knobs' bool is only updated
whenever Node is changed, rarely) and also gets us one step closer to
removing a case of storing a netmap.NetworkMap in
magicsock. (eventually we want to phase out much of the use of that
type internally)
Updates #1909
Change-Id: I37e81789f94133175064fdc09984e4f3a431f1a1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously two tsnet nodes in the same process couldn't have disjoint
sets of controlknob settings from control as both would overwrite each
other's global variables.
This plumbs a new controlknobs.Knobs type around everywhere and hangs
the knobs sent by control on that instead.
Updates #9351
Change-Id: I75338646d36813ed971b4ffad6f9a8b41ec91560
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In prep for incremental netmap update plumbing (#1909), make peerMap
also keyed by NodeID, as all the netmap node mutations passed around
later will be keyed by NodeID.
In the process, also:
* add envknob.InDevMode, as a signal that we can panic more aggressively
in unexpected cases.
* pull two moderately large blocks of code in Conn.SetNetworkMap out
into their own methods
* convert a few more sets from maps to set.Set
Updates #1909
Change-Id: I7acdd64452ba58e9d554140ee7a8760f9043f961
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Sometimes `go test` would exit and close its stdout before we started reading
it, and we would return that "file closed" error then forget to os.Exit(1).
Fixed to prefer the go test subprocess error and exit regardless of the type of
error.
Fixes#9334
Signed-off-by: Paul Scott <paul@tailscale.com>
If the user's running "go test" by hand, no need to spam stderr with
the sentinel marker. It already calls t.Logf (which only gets output
on actual failure, or verbose mode) which is enough to tell users it's
known flaky. Stderr OTOH always prints out and is distracting to
manual "go test" users.
Updates #cleanup
Change-Id: Ie5e6881bae291787c30f75924fa132f4a28abbb2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It's been implicitly enabled (based on capver) for years.
Updates #cleanup
Change-Id: I8ff1ab844f9ed75c97e866e778dfc0b56cfa98a2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
All platforms use it at this point, including iOS which was the
original hold out for memory reasons. No more reason to make it
optional.
Updates #9332
Change-Id: I743fbc2f370921a852fbcebf4eb9821e2bdd3086
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This PR ensures calls to the LocalBackend are not happening
multiples times and ensures the set/unset methods are
only manipulating the serve config
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
I didn't clean up the more idiomatic map[T]bool with true values, at
least yet. I just converted the relatively awkward struct{}-valued
maps.
Updates #cleanup
Change-Id: I758abebd2bb1f64bc7a9d0f25c32298f4679c14f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For use in tsweb debug handlers, so that we can easily inspect cache
and limiter state when troubleshooting.
Updates tailscale/corp#3601
Signed-off-by: David Anderson <danderson@tailscale.com>
Cache the last `ClientVersion` value that was received from coordination
server and pass it in the localapi `/status` response.
When running `tailscale status`, print a message if `RunningAsLatest` is
`false`.
Updates #6907
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Log some progress info to make updates more debuggable. Also, track
whether an active update is already started and return an error if
a concurrent update is attempted.
Some planned future PRs:
* add JSON output to `tailscale update`
* use JSON output from `tailscale update` to provide a more detailed
status of in-progress update (stage, download progress, etc)
Updates #6907
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
A #cleanup that moves all frontend asset handling into assets.go
(formerly dev.go), and stores a single assetsHandler field back
to web.Server that manages when to serve the dev vite proxy versus
static files itself.
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Previously, foreground mode only worked in the simple case of `tailscale funnel <port>`.
This PR ensures that whatever you can do in the background can also be
done in the foreground such as setting mount paths or tcp forwarding.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
pre-generics container/list is quite unpleasant to use, and the pointer
manipulation operations for an LRU are simple enough to implement directly
now that we have generic types.
With this change, the LRU uses a ring (aka circularly linked list) rather
than a simple doubly-linked list as its internals, because the ring makes
list manipulation edge cases more regular: the only remaining edge case is
the transition between 0 and 1 elements, rather than also having to deal
specially with manipulating the first and last members of the list.
While the primary purpose was improved readability of the code, as it
turns out removing the indirection through an interface box also speeds
up the LRU:
│ before.txt │ after.txt │
│ sec/op │ sec/op vs base │
LRU-32 67.05n ± 2% 59.73n ± 2% -10.90% (p=0.000 n=20)
│ before.txt │ after.txt │
│ B/op │ B/op vs base │
LRU-32 21.00 ± 0% 10.00 ± 0% -52.38% (p=0.000 n=20)
│ before.txt │ after.txt │
│ allocs/op │ allocs/op vs base │
LRU-32 0.000 ± 0% 0.000 ± 0% ~ (p=1.000 n=20) ¹
Updates #cleanup
Signed-off-by: David Anderson <danderson@tailscale.com>
The benchmark simulates an LRU being queries with uniformly random
inputs, in a set that's too large for the LRU, which should stress
the eviction codepath.
Signed-off-by: David Anderson <danderson@tailscale.com>
> **Note**
> Behind the `TAILSCALE_FUNNEL_DEV` flag
* Expose additional listeners through flags
* Add a --bg flag to run in the background
* --set-path to set a path for a specific target (assumes running in background)
See the parent issue for more context.
Updates #8489
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
This PR adds a new field to the serve config that can be used to identify which serves are in "foreground mode" and then can also be used to ensure they do not get persisted to disk so that if Tailscaled gets ungracefully shutdown, the reloaded ServeConfig will not have those ports opened.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
This PR removes the per request logging to the CLI as the CLI
will not be displaying those logs initially.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
It was only waiting for 0.5s (5ms * 100), but our CI
is too slow so make it wait up to 3s (10ms * 300).
Updates tailscale/corp#14515
Signed-off-by: Maisem Ali <maisem@tailscale.com>
RELNOTE=Adds support for Wikimedia DNS
Updates #9255
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I4213c29e0f91ea5aa0304a5a026c32b6690fead9
PR #9217 attempted to fix the same issue, but suffered from not letting the
user connect to non-oss tailscaled if something was listening on the socket, as
the --socket flag doesn't let you select the mac apps.
Rather than leave the user unable to choose, we keep the mac/socket preference
order the same and check a bit harder whether the macsys version really is
running. Now, we prefer the App Store Tailscale (even if it's Stopped) and you
can use --socket to sswitch. But if you quit the App Store Tailscale, we'll try
the socket without needing the flag.
Fixes#5761
Signed-off-by: Paul Scott <408401+icio@users.noreply.github.com>
Our build system caches files locally and only updates them when something
changes. Since I need to integrate some distsign stuff into the build system
to validate our Windows 7 MSIs, I want to be able to check the cached copy
of a package before downloading a fresh copy from pkgs.
If the signature changes, then obviously the local copy is outdated and we
return an error, at which point we call Download to refresh the package.
Updates https://github.com/tailscale/corp/issues/14334
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
We would only check if the client was paused, but not
if the client was closed. This meant that a call to
Shutdown may block forever/leak goroutines
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This PR adds a new field to the ServeConfig which maps
WatchIPNBus session ids to foreground serve configs.
The PR also adds a DeleteForegroundSession method to ensure the config
gets cleaned up on sessions ending.
Note this field is not currently used but will be in follow up work.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
It would acquire the lock, calculate `nextState`, relase
the lock, then call `enterState` which would acquire the lock
again. There were obvious races there which could lead to
nil panics as seen in a test in a different repo.
```
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x70 pc=0x1050f2c7c]
goroutine 42240 [running]:
tailscale.com/ipn/ipnlocal.(*LocalBackend).enterStateLockedOnEntry(0x14002154e00, 0x6)
tailscale.com/ipn/ipnlocal/local.go:3715 +0x30c
tailscale.com/ipn/ipnlocal.(*LocalBackend).enterState(0x14002154e00?, 0x14002e3a140?)
tailscale.com/ipn/ipnlocal/local.go:3663 +0x8c
tailscale.com/ipn/ipnlocal.(*LocalBackend).stateMachine(0x14001f5e280?)
tailscale.com/ipn/ipnlocal/local.go:3836 +0x2c
tailscale.com/ipn/ipnlocal.(*LocalBackend).setWgengineStatus(0x14002154e00, 0x14002e3a190, {0x0?, 0x0?})
tailscale.com/ipn/ipnlocal/local.go:1193 +0x4d0
tailscale.com/wgengine.(*userspaceEngine).RequestStatus(0x14005d90300)
tailscale.com/wgengine/userspace.go:1051 +0x80
tailscale.com/wgengine.NewUserspaceEngine.func2({0x14002e3a0a0, 0x2, 0x140025cce40?})
tailscale.com/wgengine/userspace.go:318 +0x1a0
tailscale.com/wgengine/magicsock.(*Conn).updateEndpoints(0x14002154700, {0x105c13eaf, 0xf})
tailscale.com/wgengine/magicsock/magicsock.go:531 +0x424
created by tailscale.com/wgengine/magicsock.(*Conn).ReSTUN in goroutine 42077
tailscale.com/wgengine/magicsock/magicsock.go:2142 +0x3a4
```
Updates tailscale/corp#14480
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This PR adds a SessionID field to the ipn.Notify struct so that
ipn buses can identify a session and register deferred clean up
code in the future. The first use case this is for is to be able to
tie foreground serve configs to a specific watch session and ensure
its clean up when a connection is closed.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
We use it a number of places in different repos. Might as well make
one. Another use is coming.
Updates #cleanup
Change-Id: Ib7ce38de0db35af998171edee81ca875102349a4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Our BETA serve help text is long and often hides the actual error
in the user's usage. Instead of printing the full text, prompt
users to use `serve --help` if they want the help info.
Fixes#14274
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
It would just fail the entire pkg, but would not print any
logs. It was already tracking all the logs, so have it emit
them when the pkg fails/times out.
Updates #9231
Signed-off-by: Maisem Ali <maisem@tailscale.com>
If Start was called multiple times concurrently, it would
create a new client and shutdown the previous one. However
there was a race possible between shutting down the old one
and assigning a new one where the concurent goroutine may
have assigned another one already and it would leak.
Updates tailscale/corp#14471
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Replace %w verb with %v verb when logging errors.
Use %w only for wrapping errors with fmt.Errorf()
Fixes: #9213
Signed-off-by: Craig Rodrigues <rodrigc@crodrigues.org>
resetControlClientLocked is called while b.mu was held and
would call cc.Shutdown which would wait for the observer queue
to drain.
However, there may be active callbacks from cc already waiting for
b.mu resulting in a deadlock.
This makes it so that resetControlClientLocked does not call
Shutdown, and instead just returns the value.
It also makes it so that any status received from previous cc
are ignored.
Updates tailscale/corp#12827
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This eventually allows encoding packages that may respect
the proposed encoding.TextAppender interface.
The performance gains from this is between 10-30%.
Updates tailscale/corp#14379
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We already had a path on the web client server struct, but hadn't
plumbed it through to the CLI. Add that now and use it for Synology and
QNAP instead of hard-coding the path. (Adding flag for QNAP is
tailscale/tailscale-qpkg#112) This will allow supporting other
environments (like unraid) without additional changes to the client/web
package.
Also fix a small bug in unraid handling to only include the csrf token
on POST requests.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
The flags are hidden for now. Adding propagation to tailscaled and
persistence only. The prefs field is wrapped in a struct to allow for
future expansion (like update schedule).
Updates #6907
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
I noticed that failed tests were leaving aroudn stray tailscaled processes
on macOS at least.
To repro, add this to tstest/integration:
func TestFailInFewSeconds(t *testing.T) {
t.Parallel()
time.Sleep(3 * time.Second)
os.Exit(1)
t.Fatal("boom")
}
Those three seconds let the other parallel tests (with all their
tailscaled child processes) start up and start running their tests,
but then we violently os.Exit(1) the test driver and all the children
were kept alive (and were spinning away, using all available CPU in
gvisor scheduler code, which is a separate scary issue)
Updates #cleanup
Change-Id: I9c891ed1a1ec639fb2afec2808c04dbb8a460e0e
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
> **Note**
> Behind the `TAILSCALE_USE_WIP_CODE` flag
In preparing for incoming CLI changes, this PR merges the code path for the `serve` and `funnel` subcommands.
See the parent issue for more context.
The following commands will run in foreground mode when using the environment flag.
```
tailscale serve localhost:3000
tailscae funnel localhost:3000
```
Replaces #9134
Updates #8489
Signed-off-by: Tyler Smalley <tyler@tailscale.com>
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Co-authored-by: Marwan Sulaiman <marwan@tailscale.com>
We want the overall state (used only for tests) to be computed from
the individual states of each component, rather than moving the state
around by hand in dozens of places.
In working towards that, we found a lot of things to clean up.
Updates #cleanup
Change-Id: Ieaaae5355dfae789a8ec7a56ce212f1d7e3a92db
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
During Shutdown of an ephemeral node, we called Logout (to best effort
delete the node earlier), which then called back into
resetForProfileChangeLockedOnEntry, which then tried to Start
again. That's all a waste of work during shutdown and complicates
other cleanups coming later.
Updates #cleanup
Change-Id: I0b8648cac492fc70fa97c4ebef919bbe352c5d7b
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Don't just start goroutines and hope for them to be ordered.
Fixes potential regression from earlier 7074a40c0.
Updates #cleanup
Change-Id: I501a6f3e4e8e6306b958bccdc1e47869991c31f7
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was too aggressive before, as it only had the ill-defined "Major"
bool to work with. Now it can check more precisely.
Updates #9040
Change-Id: I20967283b64af6a9cad3f8e90cff406de91653b8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Drops time by several minutes.
Also, on top of that: skip building variant CLIs on the race builder
(29s), and getting qemu (15s).
Updates #9182
Change-Id: I979e02ab8c0daeebf5200459c9e4458a1f62f728
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We already removed the async API, make it more sync and remove
the FinishLogout state too.
This also makes the callback be synchronous again as the previous
attempt was trying to work around the logout callback resulting
in a client shutdown getting blocked forever.
Updates #3833
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We have cases where the SetControlClientStatus would result in
a Shutdown call back into the auto client that would block
forever. The right thing to do here is to fix the LocalBackend
state machine but thats a different dumpster fire that we
are slowly making progress towards.
This makes it so that the SetControlClientStatus happens in a
different goroutine so that calls back into the auto client
do not block.
Also add a few missing mu.Unlocks in LocalBackend.Start.
Updates #9181
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Then use the Locked variants in Shutdown while we already hold the lock.
Updates #cleanup
Change-Id: I367d53e6be6f37f783c8f43fc9c4d498d0adf501
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* don't try to re-Start (and thus create a new client) during Shutdown
* in tests, wait for controlclient to fully shut down when replacing it
* log a bit more
Updates tailscale/corp#14139
Updates tailscale/corp#13175 etc
Updates #9178 and its flakes.
Change-Id: I3ed2440644dc157aa6e616fe36fbd29a6056846c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We have this in another repo and I wanted it here too.
Updates #cleanup
Change-Id: If93dc73f11eaaada5024acf2a885a153b88db5a0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
As a fallback to package managers, allow updating tailscale that was
self-installed in some way. There are some tricky bits around updating
the systemd unit (should we stick to local binary paths or to the ones
in tailscaled.service?), so leaving that out for now.
Updates #6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Don't depend on the server to do it.
Updates #cleanup
Change-Id: I8ff40b02aa877155a71fd4db58cbecb872241ac8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Instead of trying to use the user config dir, and then fail back to the
OS temp dir, just always use the temp dir. Also use a filename that is
less likely to cause collisions.
This addresses an issue on a test synology instance that was
mysteriously failing because there was a file at /tmp/tailscale. We
could still technically run into this issue if a
/tmp/tailscale-web-csrf.key file exists, but that seems far less likely.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
They were entirely redundant and 1:1 with the status field
so this turns them into methods instead.
Updates #cleanup
Updates #1909
Change-Id: I7d939750749edf7dae4c97566bbeb99f2f75adbc
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Instead of confusing users, emit an event that explicitly tells the
user that HTTPS is disabled on the tailnet and that ingress may not
work until they enable it.
Updates #9141
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Port 8080 is routinely used for HTTP services, make it easier to
use --forwards=tcp/8080/... by moving the metrics port out of the
way.
Updates #1748
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
I'm trying to remove some stuff from the netmap update path.
Updates #1909
Change-Id: Iad2c728dda160cd52f33ef9cf0b75b4940e0ce64
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Ensures that Statefulset reconciler config has only one of Cluster target IP or tailnet target IP.
Adds a test case for containerboot egress proxy mode.
Updates tailscale/tailscale#8184
Signed-off-by: irbekrm <irbekrm@gmail.com>
First part of work for the functionality that allows users to create an egress
proxy to access Tailnet services from within Kubernetes cluster workloads.
This PR allows creating an egress proxy that can access Tailscale services over HTTP only.
Updates tailscale/tailscale#8184
Signed-off-by: irbekrm <irbekrm@gmail.com>
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Co-authored-by: Rhea Ghosh <rhea@tailscale.com>
While investigating the fix in 7538f38671,
I was curious why the testwrapper didn't fail. Turns out if the test
times out and there was no explicit failure, the only message we get
is that the overall pkg failed and no failure information about the
individual test. This resulted in a 0 exit code.
This fixes that by failing the explicit case of the pkg failing when
there is nothing to retry for that pkg.
Updates #8493
Signed-off-by: Maisem Ali <maisem@tailscale.com>
On linux users can install Tailscale via package managers or direct
tarball downloads. Detect when Tailscale is not installed via a package
manager so we can pick the correct update mechanism. Leave the tarball
update function unimplemented for now (coming in next PR!).
Updates #6995
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This makes wsconn.Conns somewhat present reasonably when they are
the client of an http.Request, rather than just put a placeholder
in that field.
Updates tailscale/corp#13777
Signed-off-by: David Anderson <danderson@tailscale.com>
Ensures that we're sending back the csrf token for all requests
made back to unraid clients.
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Adds proxy to the localapi from /api/local/ web client endpoint.
The localapi proxy is restricted to an allowlist of those actually
used by the web client frontend.
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
We would call Update on the secret, but that was racey and would occasionaly
fail. Instead use patch whenever we can.
Fixes errors like
```
boot: 2023/08/29 01:03:53 failed to set serve config: sending serve config: updating config: writing ServeConfig to StateStore: Operation cannot be fulfilled on secrets "ts-webdav-kfrzv-0": the object has been modified; please apply your changes to the latest version and try again
{"level":"error","ts":"2023-08-29T01:03:48Z","msg":"Reconciler error","controller":"ingress","controllerGroup":"networking.k8s.io","controllerKind":"Ingress","Ingress":{"name":"webdav","namespace":"default"},"namespace":"default","name":"webdav","reconcileID":"96f5cfed-7782-4834-9b75-b0950fd563ed","error":"failed to provision: failed to create or get API key secret: Operation cannot be fulfilled on secrets \"ts-webdav-kfrzv-0\": the object has been modified; please apply your changes to the latest version and try again","stacktrace":"sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\tsigs.k8s.io/controller-runtime@v0.15.0/pkg/internal/controller/controller.go:324\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem\n\tsigs.k8s.io/controller-runtime@v0.15.0/pkg/internal/controller/controller.go:265\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2\n\tsigs.k8s.io/controller-runtime@v0.15.0/pkg/internal/controller/controller.go:226"}
```
Updates #502
Updates #7895
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This removes a lot of API from net/interfaces (including all the
filter types, EqualFiltered, active Tailscale interface func, etc) and
moves the "major" change detection to net/netmon which knows more
about the world and the previous/new states.
Updates #9040
Change-Id: I7fe66a23039c6347ae5458745b709e7ebdcce245
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
De-pointer a *time.Time type, move it after the mutex which guard is,
rename two test-only methods with our conventional "ForTest" suffix.
Updates #cleanup
Change-Id: I4f4d1acd9c2de33d9c3cb6465d7349ed051aa9f9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Named result meant error paths assigned that variable to nil.
But a goroutine was concurrently using that variable.
Don't use a named result for that first parameter. Then then return
paths don't overwrite it.
Fixes#9129
Change-Id: Ie57f99d40ca8110085097780686d9bd620aaf160
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For now the method has only one interface (the same as the func it's
replacing) but it will grow, eventually with the goal to remove the
controlclient.Status type for most purposes.
Updates #1909
Change-Id: I715c8bf95e3f5943055a94e76af98d988558a2f2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I didn't see the race builder fail on CI earlier in 590c693b9.
This fixes the test.
Updates #greenci
Change-Id: I9f271bfadfc29b010226b55bf6647f35f03730b1
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Printing out JSON representation things in log output is pretty common.
Updates #cleanup
Change-Id: Ife2d2e321a18e6e1185efa8b699a23061ac5e5a4
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So even if the server doesn't support sending patches (neither the
Tailscale control server nor Headscale yet do), this makes the client
convert a changed node to its diff so the diffs can be processed
individually in a follow-up change.
This lets us make progress on #1909 without adding a dependency on
finishing the server-side part, and also means other control servers
will get the same upcoming optimizations.
And add some clientmetrics while here.
Updates #1909
Change-Id: I9533bcb8bba5227e17389f0b10dff71f33ee54ec
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Top-level Version in pkgs response is not always in sync with SPK
versions, especially on unstable track. It's very confusing when the
confirmation prompt asks you "update to 1.49.x?" and you end up updating
to 1.49.y.
Instead, grab the SPK-specific version field.
Updates #cleanup.
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Reimplement `downloadURLToFile` using `distsign.Download` and move all
of the progress reporting logic over there.
Updates #6995
Updates #755
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This was added in 3451b89e5f, but
resulted in the v6 Tailscale address being added to status when
when the forwarding only happened on the v4 address.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The new ingress reconcile raises events on failure, but I forgot to
add the updated permission.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This makes it more maintainable for other code to statically depend
on the exact value of this string. It also makes it easier to
identify what code might depend on this string by looking up
references to this constant.
Updates tailscale/corp#13777
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This uses the new react-based web client for all builds, not just with
the --dev flag.
If the web client assets have not been built, the client will serve a
message that Tailscale was built without the web client, and link to
build instructions. Because we will include the web client in all of our
builds, this should only be seen by developers or users building from
source. (And eventually this will be replaced by attempting to download
needed assets as runtime.)
We do now checkin the build/index.html file, which serves the error
message when assets are unavailable. This will also eventually be used
to trigger in CI when new assets should be built and uploaded to a
well-known location.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
Helper command to verify package signatures, mainly for debugging.
Also fix a copy-paste mistake in error message in distsign.
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This option allows logging the raw HTTP requests and responses that the
portmapper Client makes when using UPnP. This can be extremely helpful
when debugging strange UPnP issues with users' devices, and might allow
us to avoid having to instruct users to perform a packet capture.
Updates #8992
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I2c3cf6930b09717028deaff31738484cc9b008e4
The previous change just switched the Go version used in the dev
environment (for use with e.g. direnv), not the version used for
the distribution build. Oops.
Updates #cleanup
Signed-off-by: David Anderson <danderson@tailscale.com>
On k8s the serve-config secret mount is symlinked so checking against
the Name makes us miss the events.
Updates #7895
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We pass the file as an io.Reader to http.Post under the hood as request
body. Post, helpfully, detects that the body is an io.Closer and closes
it. So when we try to explicitly close it again, we get "file already
closed" error.
The Close there is not load-bearing, we have a defer for it anyway.
Remove the explicit close and error check.
Updates #cleanup
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Also uses `http.HandlerFunc` to pass the handler into `csrfProtect`
so we can get rid of the extraneous `api` struct.
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Fly apps all set X-Forwarded-For, which breaks debug access even
with a preshared key otherwise.
Updates tailscale/corp#3601
Signed-off-by: David Anderson <danderson@tailscale.com>
It's very common for OOM crashes on Windows to be caused by lack of page
file space (the NT kernel does not overcommit). Since Windows automatically
manages page file space by default, unless the machine is out of disk space,
this is typically caused by manual page file configurations that are too
small.
This patch obtains the current page file size, the amount of free page file
space, and also determines whether the page file is automatically or manually
managed.
Fixes#9090
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Previously, the operator would only monitor Services and create
a Tailscale StatefulSet which acted as a L3 proxy which proxied
traffic inbound to the Tailscale IP onto the services ClusterIP.
This extends that functionality to also monitor Ingress resources
where the `ingressClassName=tailscale` and similarly creates a
Tailscale StatefulSet, acting as a L7 proxy instead.
Users can override the desired hostname by setting:
```
- tls
hosts:
- "foo"
```
Hostnames specified under `rules` are ignored as we only create a single
host. This is emitted as an event for users to see.
Fixes#7895
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This watches the provided path for a JSON encoded ipn.ServeConfig.
Everytime the file changes, or the nodes FQDN changes it reapplies
the ServeConfig.
At boot time, it nils out any previous ServeConfig just like tsnet does.
As the ServeConfig requires pre-existing knowledge of the nodes FQDN to do
SNI matching, it introduces a special `${TS_CERT_DOMAIN}` value in the JSON
file which is replaced with the known CertDomain before it is applied.
Updates #502
Updates #7895
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Previously users would have to unexpose/expose the service in order to
change Hostname/TargetIP. This now applies those changes by causing a
StatefulSet rollout now that a61a9ab087 is in.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
1. Add TCP port forwarding.
For example: ./sniproxy -forwards=tcp/22/github.com
will forward SSH to github.
% ssh -i ~/.ssh/id_ecdsa.pem -T git@github.com
Hi GitHubUser! You've successfully authenticated, but GitHub does not
provide shell access.
% ssh -i ~/.ssh/id_ecdsa.pem -T git@100.65.x.y
Hi GitHubUser! You've successfully authenticated, but GitHub does not
provide shell access.
2. Additionally export clientmetrics as prometheus metrics for local
scraping over the tailnet: http://sniproxy-hostname:8080/debug/varz
Updates https://github.com/tailscale/tailscale/issues/1748
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
I'm not saying it works, but it compiles.
Updates #5794
Change-Id: I2f3c99732e67fe57a05edb25b758d083417f083e
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adding a root key that signs the current signing key on
pkgs.tailscale.com. This key is here purely for development and should
be replaced before 1.50 release.
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Adds a cached self node to the web client Server struct, which will
be used from the web client api to verify that request came from the
node's own machine (i.e. came from the web client frontend). We'll
be using when we switch the web client api over to acting as a proxy
to the localapi, to protect against DNS rebinding attacks.
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Add `dist.Signer` hook which can arbitrarily sign linux/synology
artifacts. Plumb it through in `cmd/dist` and remove existing tarball
signing key. Distsign signing will happen on a remote machine, not using
a local key.
Updates #755
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Synology and QNAP both run the web client as a CGI script. The old web
client didn't care too much about requests paths, since there was only a
single GET and POST handler. The new client serves assets on different
paths, so now we need to care.
First, enforce that the CGI script is always accessed from its full
path, including a trailing slash (e.g. /cgi-bin/tailscale/index.cgi/).
Then, strip that prefix off before passing the request along to the main
serve handler. This allows for properly serving both static files and
the API handler in a CGI environment. Also add a CGIPath option to allow
other CGI environments to specify a custom path.
Finally, update vite and one "api/data" call to no longer assume that we
are always serving at the root path of "/".
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
Add separate server methods for synology and qnap, and enforce
authentication and authorization checks before calling into the actual
serving handlers. This allows us to remove all of the auth logic from
those handlers, since all requests will already be authenticated by that
point.
Also simplify the Synology token redirect handler by using fetch.
Remove the SynologyUser from nodeData, since it was never used in the
frontend anyway.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
This commit doesn't change any of the logic, but just organizes the code
a little to prepare for future changes.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
Previously we would not reapply changes to TS_HOSTNAME etc when
then the container restarted and TS_AUTH_ONCE was enabled.
This splits those into two steps login and set, allowing us to
only rerun the set step on restarts.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Now we have all the commands to generate the key hierarchy and verify
that signing keys were signed correctly:
```
$ ./tool/go run ./cmd/dist gen-key --priv-path root-priv.pem --pub-path root-pub.pem --root
wrote private key to root-priv.pem
wrote public key to root-pub.pem
$ ./tool/go run ./cmd/dist gen-key --priv-path signing-priv.pem --pub-path signing-pub.pem --signing
wrote private key to signing-priv.pem
wrote public key to signing-pub.pem
$ ./tool/go run ./cmd/dist sign-key --root-priv-path root-priv.pem --sign-pub-path signing-pub.pem
wrote signature to signature.bin
$ ./tool/go run ./cmd/dist verify-key-signature --root-pub-path root-pub.pem --sign-pub-path signing-pub.pem --sig-path signature.bin
signature ok
```
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
The Windows Security Center is a component that manages the registration of
security products on a Windows system. Only products that have obtained a
special cert from Microsoft may register themselves using the WSC API.
Practically speaking, most vendors do in fact sign up for the program as it
enhances their legitimacy.
From our perspective, this is useful because it gives us a high-signal
source of information to query for the security products installed on the
system. I've tied this query into the osdiag package and is run during
bugreports.
It uses COM bindings that were automatically generated by my prototype
metadata processor, however that program still has a few bugs, so I had
to make a few manual tweaks. I dropped those binding into an internal
package because (for the moment, at least) they are effectively
purpose-built for the osdiag use case.
We also update the wingoes dependency to pick up BSTR.
Fixes#10646
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Refresh node data when user switches to the web client browser tab.
This helps clean up the auth flow where they're sent to another tab
to authenticate then return to the original tab, where the data
should be refreshed to pick up the login updates.
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Indicate to the web client when it is running in CGI mode, and if it is
then cache the csrf key between requests.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
This adds a workflow_dispatch input to the update-flakehub workflow that
allows the user to specify an existing tag to publish to FlakeHub. This
is useful for publishing a version of a package that has already been
tagged in the repository.
Updates #9008
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
Can write "wasm" instead of js || wasi1p, since there's only two:
$ go tool dist list | grep wasm
js/wasm
wasip1/wasm
Plus, if GOOS=wasip2 is added later, we're already set.
Updates #5794
Change-Id: Ifcfb187c3775c17c9141bc721512dc4577ac4434
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Some OS-specific funcs were defined in init. Another used build tags
and required all other OSes to stub it out. Another one could just be in
the portable file.
Simplify it a bit, removing a file and some stubs in the process.
Updates #5794
Change-Id: I51df8772cc60a9335ac4c1dc0ab59b8a0d236961
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We have a fancy package for doing TLS cert validation even if the machine
doesn't have TLS certs (for LetsEncrypt only) but the CLI's netcheck command
wasn't using it.
Also, update the tlsdial's outdated package docs while here.
Updates #cleanup
Change-Id: I74b3cb645d07af4d8ae230fb39a60c809ec129ad
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This simplifies some netmon code in prep for other changes.
It breaks up Monitor.debounce into a helper method so locking is
easier to read and things unindent, and then it simplifies the polling
netmon implementation to remove the redundant stuff that the caller
(the Monitor.debounce loop) was already basically doing.
Updates #9040
Change-Id: Idcfb45201d00ae64017042a7bdee6ef86ad37a9f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Under normal circumstances, you would typically want to keep the default
behavior of requiring secure cookies. In the case of the Tailscale web
client, we are regularly serving on localhost (where secure cookies
don't really matter), and/or we are behind a reverse proxy running on a
network appliance like a NAS or Home Assistant. In those cases, those
devices are regularly accessed over local IP addresses without https
configured, so would not work with secure cookies.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
To make key management less error-prone, use different PEM block types
for root and signing keys. As a result, separate out most of the Go code
between root/signing keys too.
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This PR removes calls to ioutil library and replaces them
with their new locations in the io and os packages.
Fixes#9034
Updates #5210
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Open control server auth URLs in new browser tabs on web clients
so users don't loose original client URL when redirected for login.
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Actually fixed in 77ff705545 but that was cherry-picked to a branch
and we don't bump capver in branches.
This tells the control plane that UPnP should be re-enabled going
forward.
Updates #8992
Change-Id: I5c4743eb52fdee94175668c368c0f712536dc26b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Upcoming work on incremental netmap change handling will require some
replumbing of which subsystems get notified about what. Done naively,
it could break "tailscale status --json" visibility later. To make sure
I understood the flow of all the updates I was rereading the status code
and realized parts of ipnstate.Status were being populated by the wrong
subsystems.
The engine (wireguard) and magicsock (data plane, NAT traveral) should
only populate the stuff that they uniquely know. The WireGuard bits
were fine but magicsock was populating stuff stuff that LocalBackend
could've better handled, so move it there.
Updates #1909
Change-Id: I6d1b95d19a2d1b70fbb3c875fac8ea1e169e8cb0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I forgot to move the defer out of the func, so the tsnet.Server
immediately closed after starting.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This ensures that `go mod vendor` includes these files, which are needed
for client builds run in corp.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
It was jumbled doing a lot of things, this breaks it up into
the svc reconciliation and the tailscale sts reconciliation.
Prep for future commit.
Updates #502
Signed-off-by: Maisem Ali <maisem@tailscale.com>
I thought this had something to do with Synology or QNAP support, since
they both have specific authentication logic. But it turns out this was
part of the original web client added in #1621, and then refactored as
part of #2093. But with how we handle logging in now, it's never
called.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
Add a new subcommand to generate a Ed25519 key pair for release signing.
The same command can be used to generate both root and signing keys.
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
If we don't have the ICMP hint available, such as on Android, we can use
the signal of rx traffic to bias toward a particular endpoint.
We don't want to stick to a particular endpoint for a very long time
without any signals, so the sticky time is reduced to 1 second, which is
large enough to avoid excessive packet reordering in the common case,
but should be small enough that either rx provides a strong signal, or
we rotate in a user-interactive schedule to another endpoint, improving
the feel of failover to other endpoints.
Updates #8999
Co-authored-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Signed-off-by: James Tucker <james@tailscale.com>
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
There are cases where we do not detect the non-viability of a route, but
we will instead observe a failure to send. In a Disco path this would
normally be handled as a side effect of Disco, which is not available to
non-Disco WireGuard nodes. In both cases, recognizing the failure as
such will result in faster convergence.
Updates #8999
Signed-off-by: James Tucker <james@tailscale.com>
LastFullPing is now used for disco or wireguard only endpoints. This
change updates the comment to make that clear.
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
In order for the installer to restart the GUI correctly post-upgrade, we
need the GUI to be able to register its restart preferences.
This PR adds API support for doing so. I'm adding it to OSS so that it
is available should we need to do any such registrations on OSS binaries
in the future.
Updates https://github.com/tailscale/corp/issues/13998
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
There are latency values stored in bestAddr and endpointState that are
no longer applicable after a connectivity change and should be cleared
out, following the documented behavior of the function.
Updates #8999
Signed-off-by: James Tucker <james@tailscale.com>
This library is intended for use during release to sign packages which
are then served from pkgs.tailscale.com.
The library is also then used by clients downloading packages for
`tailscale update` where OS package managers / app stores aren't used.
Updates https://github.com/tailscale/tailscale/issues/8760
Updates https://github.com/tailscale/tailscale/issues/6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Theory is that our long lived http2 connection to control would
get tainted by _something_ (unclear what) and would get closed.
This picks up the fix for golang/go#60818.
Updates tailscale/corp#5761
Signed-off-by: Maisem Ali <maisem@tailscale.com>
src/**/* was only grabbing files in subdirectories, but not in the src
directory itself.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
This PR addresses a number of the follow ups from PR #8491 that were written
after getting merged.
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
instead of embedding each file individually, embed them all into a
single embed filesystem. This is basically a noop for the current
frontend, but sets things up a little cleaner for the new frontend.
Also added an embed.FS for the source files needed to build the new
frontend. These files are not actually embedded into the binary (since
it is a blank identifier), but causes `go mod vendor` to copy them into
the vendor directory.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
This builds the assets for the new web client as part of our release
process. The path to the web client source is specified by the
-web-client-root flag. This allows corp builds to first vendor the
tailscale.com module, and then build the web client assets in the vendor
directory.
The default value for the -web-client-root flag is empty, so no assets
are built by default.
This is an update of the previously reverted 0fb95ec
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
It was in SelfNode.Hostinfo anyway. The redundant copy was just
costing us an allocation per netmap (a Hostinfo.Clone).
Updates #1909
Change-Id: Ifac568aa5f8054d9419828489442a0f4559bc099
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This workflow will publish a flake to flakehub when a tag is pushed to
the repository. It will only publish tags that match the pattern
`v*.*.*`.
Fixes#9008
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
Adds ability to start Funnel in the foreground and stream incoming
connections. When foreground process is stopped, Funnel is turned
back off for the port.
Exampe usage:
```
TAILSCALE_FUNNEL_V2=on tailscale funnel 8080
```
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
This caused breakages on the build server:
synology/dsm7/x86_64: chdir /home/ubuntu/builds/2023-08-21T21-47-38Z-unstable-main-tagged-devices/0/client/web: no such file or directory
synology/dsm7/i686: chdir /home/ubuntu/builds/2023-08-21T21-47-38Z-unstable-main-tagged-devices/0/client/web: no such file or directory
synology/dsm7/armv8: chdir /home/ubuntu/builds/2023-08-21T21-47-38Z-unstable-main-tagged-devices/0/client/web: no such file or directory
...
Reverting while I investigate.
This reverts commit 0fb95ec07d.
Signed-off-by: Will Norris <will@tailscale.com>
This builds the assets for the new web client as part of our release
process. These assets will soon be embedded into the cmd/tailscale
binary, but are not actually done so yet.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
Adds csrf protection and hooks up an initial POST request from
the React web client.
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Port 0 is interpreted, per the spec (but inconsistently among router
software) as requesting to map every single available port on the UPnP
gateway to the internal IP address. We'd previously avoided picking
ports below 1024 for one of the two UPnP methods (in #7457), and this
change moves that logic so that we avoid it in all cases.
Updates #8992
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I20d652c0cd47a24aef27f75c81f78ae53cc3c71e
Now mapSession has a bunch more fields and methods, rather than being
just one massive func with a ton of local variables.
So far there are no major new optimizations, though. It should behave
the same as before.
This has been done with an eye towards testability (so tests can set
all the callback funcs as needed, or not, without a huge Direct client
or long-running HTTP requests), but this change doesn't add new tests
yet. That will follow in the changes which flesh out the NetmapUpdater
interface.
Updates #1909
Change-Id: Iad4e7442d5bbbe2614bd4b1dc4b02e27504898df
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And flesh it out and use idiomatic doc style ("whether" for bools)
and end in a period while there anyway.
Updates #cleanup
Change-Id: Ieb82f13969656e2340c3510e7b102dc8e6932611
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
When running in our github CI environment, curl sometimes hangs while closing
the download from the nodejs.org server and fails with INTERNAL_ERROR. This is
likely caused by CI running behind some kind of load balancer or proxy that
handles HTTP/2 incorrectly in some minor way, so force curl to use HTTP 1.1.
Updates #8988
Signed-off-by: Val <valerie@tailscale.com>
When sending a ping from the CLI, only accept a pong that is in reply
to the specific CLI ping we sent.
Updates #311
Signed-off-by: Val <valerie@tailscale.com>
And optimize the Persist setting a bit, allocating later and only mutating
fields when there's been a Node change.
Updates #1909
Change-Id: Iaddfd9e88ef76e1d18e8d0a41926eb44d0955312
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In b987b2ab18 (2021-01-12) when we introduced sharing we mapped
the sharer to the userid at a low layer, mostly to fix the display of
"tailscale status" and the client UIs, but also some tests.
The commit earlier today, 7dec09d169, removed the 2.5yo option
to let clients disable that automatic mapping, as clearly we were never
getting around to it.
This plumbs the Sharer UserID all the way to ipnstatus so the CLI
itself can choose to print out the Sharer's identity over the node's
original owner.
Then we stop mangling Node.User and let clients decide how they want
to render things.
To ease the migration for the Windows GUI (which currently operates on
tailcfg.Node via the NetMap from WatchIPNBus, instead of PeerStatus),
a new method Node.SharerOrUser is added to do the mapping of
Sharer-else-User.
Updates #1909
Updates tailscale/corp#1183
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It had a custom Clone func with a TODO to replace with cloner, resolve
that todo. Had to pull out the embedded Auth struct into a named struct.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
I screwed this up in 58a4fd43d as I expected. I even looked out for
cases like this (because this always happens) and I still missed
it. Vet doesn't flag these because they're not the standard printf
funcs it knows about. TODO: make our vet recognize all our
"logger.Logf" types.
Updates #8948
Change-Id: Iae267d5f81da49d0876b91c0e6dc451bf7dcd721
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I'd added a test case of deephash against a tailcfg.Node to make sure
it worked at all more than anything. We don't care what the exact
bytes are in this test, just that it doesn't fail. So adjust for that.
Then when we make changes to tailcfg.Node and types under it, we don't
need to keep adjusting this test.
Updates #cleanup
Change-Id: Ibf4fa42820aeab8f5292fe65f9f92ffdb0b4407b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It was added 2.5 years ago in c1dabd9436 but was never used.
Clearly that migration didn't matter.
We can attempt this again later if/when this matters.
Meanwhile this simplifies the code and thus makes working on other
current efforts in these parts of the code easier.
Updates #1909
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit tries to mimic the way iptables-nft work with the filewall rules. We
follow the convention of using tables like filter, nat and the conventional
chains, to make our nftables implementation work with ufw.
Updates: #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
Serving the web client on the tailscale interface, while useful for
remote management, is also inherently risky if ACLs are not configured
appropriately. Switch the example to listen only on localhost, which is
a much safer default. This is still a valuable example, since it still
demonstrates how to have a web client connected to a tsnet instance.
Updates #13775
Signed-off-by: Will Norris <will@tailscale.com>
Due to the conflict between our nftables implementation and ufw, which is a common utility used
on linux. We now want to take a step back to prevent regression. This will give us more chance to
let users to test our nftables support and heuristic.
Updates: #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
Make it just a views.Slice[netip.Prefix] instead of its own named type.
Having the special case led to circular dependencies in another WIP PR
of mine.
Updates #8948
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is basically https://github.com/bradfitz/iter which was
a joke but now that Go's adding range over int soonish, might
as well. It simplies our code elsewher that uses slice views.
Updates #8948
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The hardware version in `/proc/sys/kernel/syno_hw_version` does not map
exactly to versions in
https://github.com/SynoCommunity/spksrc/wiki/Synology-and-SynoCommunity-Package-Architectures.
It contains some slightly different version formats.
Instead, `/etc/synoinfo.conf` exists and contains a `unique` line with
the CPU architecture encoded. Parse that out and filter through the list
of architectures that we have SPKs for.
Tested on DS218 and DS413j.
Updates #8927
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
The tailscale serve|funnel commands frequently call the LocalBackend's Status
but they never need the peers to be included. This PR changes the call to be
StatusWithoutPeers which should gain a noticeable speed improvement
Updates #8489
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Now a nodeAttr: ForceBackgroundSTUN, DERPRoute, TrimWGConfig,
DisableSubnetsIfPAC, DisableUPnP.
Kept support for, but also now a NodeAttr: RandomizeClientPort.
Removed: SetForceBackgroundSTUN, SetRandomizeClientPort (both never
used, sadly... never got around to them. But nodeAttrs are better
anyway), EnableSilentDisco (will be a nodeAttr later when that effort
resumes).
Updates #8923
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Values are still turned into pointers internally to maintain the
invariants of strideTable, but from the user's perspective it's
now possible to tbl.Insert(pfx, true) rather than
tbl.Insert(pfx, ptr.To(true)).
Updates #7781
Signed-off-by: David Anderson <danderson@tailscale.com>
Previously we would use the Impersonate-Group header to pass through
tags to the k8s api server. However, we would do nothing for non-tagged
nodes. Now that we have a way to specify these via peerCaps respect those
and send down groups for non-tagged nodes as well.
For tagged nodes, it defaults to sending down the tags as groups to retain
legacy behavior if there are no caps set. Otherwise, the tags are omitted.
Updates #5055
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This PR adds DNSFilterURL to the DNSConfig type to be used by
control changes to add DNS filtering logic
Fixes #cleanup
Signed-off-by: Richard Castro <richard@tailscale.com>
* clientupdate: return NOTREACHED for macsys
The work is done in Swift; this is now a documentation placeholder.
Updates #6995
Signed-off-by: Chris Palmer <cpalmer@tailscale.com>
In preparation for a different refactor, but incidentally also saves
10-25% memory on overall table size in benchmarks.
Updates #7781
Signed-off-by: David Anderson <danderson@tailscale.com>
If an optional request ID generating func is supplied to StdHandler,
then requests that return an error will be logged with a request ID that
is also shown as part of the response.
Updates tailscale/corp#2549
Change-Id: Ic7499706df42f95b6878d44d4aab253e2fc6a69b
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
To record wether user is using iptables or nftables after we add support to nftables on linux, we
are adding a field FirewallMode to NetInfo in HostInfo to reflect what firewall mode the host is
running, and form metrics. The information is gained from a global constant in hostinfo.go. We
set it when selection heuristic made the decision, and magicsock reports this to control.
Updates: tailscale/corp#13943
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
If a node is flapping or otherwise generating lots of STUN endpoints, we
can end up caching a ton of useless values and sending them to peers.
Instead, let's apply a fixed per-Addr limit of endpoints that we cache,
so that we're only sending peers up to the N most recent.
Updates tailscale/corp#13890
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8079a05b44220c46da55016c0e5fc96dd2135ef8
This copies the existing go template frontend into very crude react
components that will be driven by a simple JSON api for fetching and
updating data. For now, this returns a static set of test data.
This just implements the simple existing UI, so I've put these all in a
"legacy" component, with the expectation that we will rebuild this with
more properly defined components, some pulled from corp.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
When trying to use serve with https, send users through https cert
provisioning enablement before editing the ServeConfig.
Updates tailscale/corp#10577
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
1. Add metrics to funnel flow.
2. Stop blocking users from turning off funnels when no longer in
their node capabilities.
3. Rename LocalClient.IncrementMetric to IncrementCounter to better
callout its usage is only for counter clientmetrics.
Updates tailscale/corp#10577
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
A #cleanup to add a func to utilize the already-present
"/localapi/v0/upload-client-metrics" localapi endpoint.
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
The Layered Service Provider (LSP) is a deprecated (but still supported)
mechanism for inserting user-mode DLLs into a filter chain between the
Winsock API surface (ie, ws2_32.dll) and the internal user-mode interface
to the networking stack.
While their use is becoming more rare due to the aforementioned deprecation,
it is still possible for third-party software to install their DLLs into
this filter chain and interfere with Winsock API calls. Knowing whether
this is happening is useful for troubleshooting.
Fixes https://github.com/tailscale/tailscale/issues/8142
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
The current router errors out when neither iptables nor nftables support is present. We
should fall back to the previous behaviour which we creates a dummy iptablesRunner.
Fixes: #8878
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
No need to have it on Auto or be behind a mutex; it's only read/written
from a single goroutine. Move it there.
Updates tailscale/corp#5761
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
See issue. This is a baby step towards passing through deltas
end-to-end from node to control back to node and down to the various
engine subsystems, not computing diffs from two full netmaps at
various levels. This will then let us support larger netmaps without
burning CPU.
But this change itself changes no behavior. It just changes a func
type to an interface with one method. That paves the way for future
changes to then add new NetmapUpdater methods that do more
fine-grained work than updating the whole world.
Updates #1909
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The read of the synced field for logging takes place outside the lock, and
races with other (locked) writes of this field, including for example the one
at current line 556 in mapRoutine.
Updates tailscale/corp#13856
Change-Id: I056b36d7a93025aafdf73528dd7645f10b791af6
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
Implement naive update for Synology packages, using latest versions from
pkgs.tailscale.com. This is naive because we completely trust
pkgs.tailscale.com to give us a safe package. We should switch this to
some better signing mechanism later.
I've only tested this on one DS218 box, so all the CPU architecture
munging is purely based on docs.
Updates #6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This removes the unsafe/linkname and only uses the standard library.
It's a bit slower, for now, but https://go.dev/cl/518336 should get us
back.
On darwin/arm64, without https://go.dev/cl/518336
pkg: tailscale.com/tstime/mono
│ before │ after │
│ sec/op │ sec/op vs base │
MonoNow-8 16.20n ± 0% 19.75n ± 0% +21.92% (p=0.000 n=10)
TimeNow-8 39.46n ± 0% 39.40n ± 0% -0.16% (p=0.002 n=10)
geomean 25.28n 27.89n +10.33%
And with it,
MonoNow-8 16.34n ± 1% 16.93n ± 0% +3.67% (p=0.001 n=10)
TimeNow-8 39.55n ± 15% 38.46n ± 1% -2.76% (p=0.000 n=10)
geomean 25.42n 25.52n +0.41%
Updates #8839
Updates tailscale/go#70
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Netcheck no longer performs I/O itself, instead it makes requests via
SendPacket and expects users to route reply traffic to
ReceiveSTUNPacket.
Netcheck gains a Standalone function that stands up sockets and
goroutines to implement I/O when used in a standalone fashion.
Magicsock now unconditionally routes STUN traffic to the netcheck.Client
that it hosts, and plumbs the send packet sink.
The CLI is updated to make use of the Standalone mode.
Fixes#8723
Signed-off-by: James Tucker <james@tailscale.com>
Also allows us to use absolute import paths (see change in index.tsx).
Updates tailscale/corp#13775
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
This sets the Don't Fragment flag, for now behind the
TS_DEBUG_ENABLE_PMTUD envknob.
Updates #311.
Signed-off-by: Val <valerie@tailscale.com>
Signed-off-by: salman <salman@tailscale.com>
Currently just serving a "Hello world" page when running the web
cli in --dev mode.
Updates tailscale/corp#13775
Co-authored-by: Will Norris <will@tailscale.com>
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Extract the self-update logic from cmd/tailscale/cli into a standalone
package that could be used from tailscaled later.
Updates #6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Instead of having updates replace the map polls, create
a third goroutine which is solely responsible for making
sure that control is aware of the latest client state.
This also makes it so that the streaming map polls are only
broken when there are auth changes, or the client is paused.
Updates tailscale/corp#5761
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Go style is for error variables to start with "err" (or "Err")
and for error types to end in "Error".
Updates #cleanup
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
These specific tests rely on some timers in the controlhttp code.
Without time moving forward and timers triggering, the tests fail.
Updates #8587
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
move the tailscale web client out of the cmd/tailscale/cli package, into
a new client/web package. The remaining cli/web.go file is still
responsible for parsing CLI flags and such, and then calls into
client/web. This will allow the web client to be hooked into from other
contexts (for example, from a tsnet server), and provide a dedicated
space to add more functionality to this client.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
Refactor two shared functions used by the tailscale cli,
calcAdvertiseRoutes and licensesURL. These are used by the web client as
well as other tailscale subcommands. The web client is being moved out
of the cli package, so move these two functions to new locations.
Updates tailscale/corp#13775
Signed-off-by: Will Norris <will@tailscale.com>
We would only look for duplicate profiles when a new login
occurred but when using `--force-reauth` we could switch
users which would end up with duplicate profiles.
Updates #7726
Signed-off-by: Maisem Ali <maisem@tailscale.com>
There are a few situations where we end up with duplicate profiles.
Add tests to identify those situations, fix in followup.
Updates #7726
Signed-off-by: Maisem Ali <maisem@tailscale.com>
It was being modified in two places in Direct for the auth routine
and then in LocalBackend when a new NetMap was received. This was
confusing, so make Direct also own changes to Persist when a new
NetMap is received.
Updates #7726
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit replaces the TS_DEBUG_USE_NETLINK_NFTABLES envknob with
a TS_DEBUG_FIREWALL_MODE that should be set to either 'iptables' or
'nftables' to select firewall mode manually, other wise tailscaled
will automatically choose between iptables and nftables depending on
environment and system availability.
updates: #319
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
This adds the capability to pad disco ping message payloads to reach a
specified size. It also plumbs it through to the tailscale ping -size
flag.
Disco pings used for actual endpoint discovery do not use this yet.
Updates #311.
Signed-off-by: salman <salman@tailscale.com>
Co-authored-by: Val <valerie@tailscale.com>
Rather than make each ipn.StateStore implementation guard against
useless writes (a write of the same value that's already in the
store), do writes via a new wrapper that has a fast path for the
unchanged case.
This then fixes profileManager's flood of useless writes to AWS SSM,
etc.
Updates #8785
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Plumb a signing callback function to `unixpkgs.rpmTarget` to allow
signing RPMs. This callback is optional and RPMs will build unsigned if
not set, just as before.
Updates https://github.com/tailscale/tailscale/issues/1882
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Upgrade the nfpm package to the latest version to pick up
24a43c5ad7.
The upgrade is from v0 to v2, so there was some breakage to fix.
Generated packages should have the same contents as before.
Updates https://github.com/tailscale/tailscale/issues/1882
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
* We update wingoes to pick up new version information functionality
(See pe/version.go in the https://github.com/dblohm7/wingoes repo);
* We move the existing LogSupportInfo code (including necessary syscall
stubs) out of util/winutil into a new package, util/osdiag, and implement
the public LogSupportInfo function may be implemented for other platforms
as needed;
* We add a new reason argument to LogSupportInfo and wire that into
localapi's bugreport implementation;
* We add module information to the Windows implementation of LogSupportInfo
when reason indicates a bugreport. We enumerate all loaded modules in our
process, and for each one we gather debug, authenticode signature, and
version information.
Fixes#7802
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Add optional `--upstream` flag to `tailscale version` to fetch the
latest upstream release version from `pkgs.tailscale.com`. This is
useful to diagnose `tailscale update` behavior or write other tooling.
Example output:
$ tailscale version --upstream --json
{
"majorMinorPatch": "1.47.35",
"short": "1.47.35",
"long": "1.47.35-t6afffece8",
"unstableBranch": true,
"gitCommit": "6afffece8a32509aa7a4dc2972415ec58d8316de",
"cap": 66,
"upstream": "1.45.61"
}
Fixes#8669
RELNOTE=adds "tailscale version --upstream"
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
The revoke-keys command allows nodes with tailnet lock keys
to collaborate to erase the use of a compromised key, and remove trust
in it.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates ENG-1848
Previously, tailscale upgrade was doing the bare minimum for checking
authenticode signatures via `WinVerifyTrustEx`. This is fine, but we can do
better:
* WinVerifyTrustEx verifies that the binary's signature is valid, but it doesn't
determine *whose* signature is valid; tailscale upgrade should also ensure that
the binary is actually signed *by us*.
* I added the ability to check the signatures of MSI files.
* In future PRs I will be adding diagnostic logging that lists details about
every module (ie, DLL) loaded into our process. As part of that metadata, I
want to be able to extract information about who signed the binaries.
This code is modelled on some C++ I wrote for Firefox back in the day. See
https://searchfox.org/mozilla-central/rev/27e4816536c891d85d63695025f2549fd7976392/toolkit/xre/dllservices/mozglue/Authenticode.cpp
for reference.
Fixes#8284
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Count number of sessions, number of DNS queries answered
successfully and in error, and number of http->https redirects.
Updates #1748
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
Pass an optional PEM-encoded ECDSA key to `cmd/dist` to sign all built
tarballs. The signature is stored next to the tarball with a `.sig`
extension.
Tested this with an `openssl`-generated key pair and verified the
resulting signature.
Updates #8760
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Every time I use WhoIsResponse I end up writing mildly irritating nil-checking
for both Node and UserProfile, but it turns out our code guarantees that both
are non-nil in successful whois responses.
Updates #cleanup
Signed-off-by: David Anderson <danderson@tailscale.com>
Like net/http.Server.BaseContext, this lets callers specify a base
context for dials.
Updates tailscale/corp#12702
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The nonce value is not read by anything, and di.sharedKey.Seal()
a few lines below generates its own. #cleanup
Signed-off-by: salman <salman@tailscale.com>
While our `shouldStartDomainRenewal` check is correct, `getCertPEM`
would always bail if the existing cert is not expired. Add the same
`shouldStartDomainRenewal` check to `getCertPEM` to make it proceed with
renewal when existing certs are still valid but should be renewed.
The extra check is expensive (ARI request towards LetsEncrypt), so cache
the last check result for 1hr to not degrade `tailscale serve`
performance.
Also, asynchronous renewal is great for `tailscale serve` but confusing
for `tailscale cert`. Add an explicit flag to `GetCertPEM` to force a
synchronous renewal for `tailscale cert`.
Fixes#8725
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This change introduces a new subcommand, `exit-node`, along with a
subsubcommand of `list` and a `--filter` flag.
Exit nodes without location data will continue to be displayed when
`status` is used. Exit nodes with location data will only be displayed
behind `exit-node list`, and in status if they are the active exit node.
The `filter` flag can be used to filter exit nodes with location data by
country.
Exit nodes with Location.Priority data will have only the highest
priority option for each country and city listed. For countries with
multiple cities, a <Country> <Any> option will be displayed, indicating
the highest priority node within that country.
Updates tailscale/corp#13025
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Implement `tailscale update` on FreeBSD. This is much simpler than other
platforms because `pkg rquery` lets us get the version in their repos
without any extra parsing.
Updates #6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
Define PeerCapabilty and PeerCapMap as the new way of sending down
inter-peer capability information.
Previously, this was unstructured and you could only send down strings
which got too limiting for certain usecases. Instead add the ability
to send down raw JSON messages that are opaque to Tailscale but provide
the applications to define them however they wish.
Also update accessors to use the new values.
Updates #4217
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Similar to Arch support, use the latest version info from the official
`apk` repo and don't offer explicit track or version switching.
Add detection for Alpine Linux in version/distro along the way.
Updates #6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
One is a straight "I forgot how to Go" bug, the others are semantic
mismatches with the main implementation around masking the prefixes
passed to insert/delete.
Updates #7781
Signed-off-by: David Anderson <danderson@tailscale.com>
This is a prerequisite for path compression, so that insert/delete
can determine when compression occurred.
Updates #7781
Signed-off-by: David Anderson <danderson@tailscale.com>
This is the Fedora family of distros, including CentOS, RHEL and others.
Tested in `fedora:latest` and `centos:7` containers.
Updates #6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
If the connection provided to sftp.NewServer is closed,
Serve returns the io.EOF error verbatim from io.Reader.Read.
This is an odd error since this is an expected situation,
so we manually ignore io.EOF.
This is somewhat buggy since the sftp package itself
incorrectly reports io.EOF in cases where it should actually
be reporting io.ErrUnexpectedEOF.
See https://github.com/pkg/sftp/pull/554 which patches Serve to
return nil on clean closes and fixes buggy uses of io.ReadFull.
Fixes#8592
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The util/linuxfw/iptables.go had a bunch of code that wasn't yet used
(in prep for future work) but because of its imports, ended up
initializing code deep within gvisor that panicked on init on arm64
systems not using 4KB pages.
This deletes the unused code to delete the imports and remove the
panic. We can then cherry-pick this back to the branch and restore it
later in a different way.
A new test makes sure we don't regress in the future by depending on
the panicking package in question.
Fixes#8658
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Having `127.0.0.53` is not the only way to use `systemd-resolved`. An
alternative way is to enable `libnss_resolve` module, which seems to now
be used by default on Debian 12 bookworm.
Fixes#8549
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Arch version of tailscale is not maintained by us, but is generally
up-to-date with our releases. Therefore "tailscale update" is just a
thin wrapper around "pacman -Sy tailscale" with different flags.
Updates #6995
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
* cmd/tailscale/cli: make `tailscale update` query `softwareupdate`
Even on macOS when Tailscale was installed via the App Store, we can check for
and even install new versions if people ask explicitly. Also, warn if App Store
AutoUpdate is not turned on.
Updates #6995
In late 2022 a subtle but crucial part of documentation was added to ed25519.Verify: It
will panic if len(publicKey) is not [PublicKeySize].
02ed0e5e67
This change catches that error so it won't lead to a panic.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Updates https://github.com/tailscale/corp/issues/8568
Allow inline CSS for debug handlers to make prototyping easier. These
are generally not accessible to the public and the small risk of CSS
injection via user content seems acceptable.
Also allow form submissions on the same domain, instead of banning all
forms. An example of such form is
http://webhooks.corp.ts.net:6359/debug/private-nodes/
Updates #3576
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
This changes the ACLTestError type to reuse the existing/identical
types from the ACL implementation, to avoid issues in the future if
the two types fall out of sync.
Updates #8645
Signed-off-by: Jenny Zhang <jz@tailscale.com>
This commit adds nftable rule injection for tailscaled. If tailscaled is
started with envknob TS_DEBUG_USE_NETLINK_NFTABLES = true, the router
will use nftables to manage firewall rules.
Updates: #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
The MacOS client can't set the MTU when creating the tun due to lack
of permissions, so add it to the router config and have MacOS set it
in the callback using a method that it does have permissions for.
Updates #8219
Signed-off-by: Val <valerie@tailscale.com>
If the absolute value of the difference between the current
PreferredDERP's latency and the best latency is <= 10ms, don't change
it and instead prefer the previous value.
This is in addition to the existing hysteresis that tries to remain
on the previous DERP region if the relative improvement is small, but
handles nodes that have low latency to >1 DERP region better.
Updates #8603
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I1e34c94178f8c9a68a69921c5bc0227337514c70
When using a custom http port like 8080, this was resulting in a
constructed hostname of `host.tailnet.ts.net:8080.tailnet.ts.net` when
looking up the serve handler. Instead, strip off the port before adding
the MagicDNS suffix.
Also use the actual hostname in `serve status` rather than the literal
string "host".
Fixes#8635
Signed-off-by: Will Norris <will@tailscale.com>
We were never resetting the backoff in streaming mapResponses.
The call to `PollNetMap` always returns with an error. Changing that contract
is harder, so manually reset backoff when a netmap is received.
Updates tailscale/corp#12894
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This allows providing additional information to the client about how to
select a home DERP region, such as preferring a given DERP region over
all others.
Updates #8603
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I7c4a270f31d8585112fab5408799ffba5b75266f
Add a few helper functions in tsweb to add common security headers to handlers. Use those functions for all non-tailscaled-facing endpoints in derper.
Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
`go test -json` outputs invalid JSON when a build fails.
Handle that case by reseting the json.Decode and continuing to read.
Updates #8493
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This allows sending logs from the "logpolicy" package (and associated
callees) to something other than the log package. The behaviour for
tailscaled remains the same, passing in log.Printf
Updates #8249
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie1d43b75fa7281933d9225bffd388462c08a5f31
This pulls in IP checksum optimization on amd64, see
tailscale/wireguard-go@bb2c8f2.
Updates tailscale/corp#9755
Change-Id: I60e932fc4031703b56eb86a676465c5d02d99236
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
When performing a fallback DNS query, run the recursive resolver in a
separate goroutine and compare the results returned by the recursive
resolver with the results we get from "regular" bootstrap DNS. This will
allow us to gather data about whether the recursive DNS resolver works
better, worse, or about the same as "regular" bootstrap DNS.
Updates #5853
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ifa0b0cc9eeb0dccd6f7a3d91675fe44b3b34bd48
We were storing a lot of "ExitNodeFilteredSet":null in the database.
Updates tailscale/corp#1818 (found in the process)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The server hasn't sent it in ages.
Updates #cleanup
Change-Id: I9695ab0f074ec6fb006e11faf3cdfc5ca049fbf8
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change removes the noV4/noV6 check from addrForSendWireGuardLocked.
On Android, the client panics when reaching `rand.Intn()`, likely due to
the candidates list being containing no candidates. The suspicion is
that the `noV4` and the `noV6` are both being triggered causing the
loop to continue.
Updates tailscale/corp#12938
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Without this, the client would just get stuck dialing even if the
context was canceled.
Updates tailscale/corp#12590
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This change introduces tstime.Clock which is the start of a mockable
interface for use with testing other upcoming code changes.
Fixes#8463
Change-Id: I59eabc797828809194575736615535d918242ec4
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
This change introduces tstime.NewClock and tstime.ClockOpts as a new way
to construct tstime.Clock. This is a subset of #8464 as a stepping stone
so that we can update our internal code to use the new API before making
the second round of changes.
Updates #8463
Change-Id: Ib26edb60e5355802aeca83ed60e4fdf806c90e27
Signed-off-by: Adrian Dewhurst <adrian@tailscale.com>
From Go commit 0a48e5cbfabd679e, then with some generics sprinkled
about.
Updates tailscale/corp#7354
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Instead of calling kubectl directly in k8s Makefile, write the yaml to
stdout so it can be reviewed/edited/etc before manually applying with
kubectl.
Fixes: #8511
Signed-off-by: David Wolever <david@wolever.net>
Exclide GOARCHs including: mips, mips64, mips64le, mipsle, riscv64.
These archs are not supported by gvisor.dev/gvisor/pkg/hostarch.
Fixes: #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
Previously it would wait for all tests to run before printing anything,
instead stream the results over a channel so that they can be emitted
immediately.
Updates #8493
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Previously it would only print the failures without providing
more information on which package the failures from.
This commit makes it so that it prints out the package information
as well as the attempt numbers.
```
➜ tailscale.com git:(main) ✗ go run ./cmd/testwrapper ./cmd/...
ok tailscale.com/cmd/derper
ok tailscale.com/cmd/k8s-operator
ok tailscale.com/cmd/tailscale/cli
ok tailscale.com/cmd/tailscaled
=== RUN TestFlakeRun
flakytest.go:38: flakytest: issue tracking this flaky test: https://github.com/tailscale/tailscale/issues/0
flakytest_test.go:41: First run in testwrapper, failing so that test is retried. This is expected.
--- FAIL: TestFlakeRun (0.00s)
FAIL tailscale.com/cmd/testwrapper/flakytest
Attempt #2: Retrying flaky tests:
ok tailscale.com/cmd/testwrapper/flakytest
```
Updates #8493
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Calling both mono.Now() and time.Now() is slow and
leads to unnecessary precision errors.
Instead, directly compute mono.Time relative to baseMono and baseWall.
This is the opposite calculation as mono.Time.WallTime.
Updates tailscale/corp#8427
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The panicLogWriter is too strict, and any panics that occur
get wrapped up in quotes. This makes it so that it will allow
panics to continue writing to Stderr without going through
logger.Logf.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This package contains platform-independent abstractions for fetching
information about an open TCP connection.
Updates #8413
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I236657b1060d7e6a45efc7a2f6aacf474547a2fe
This change is introducing new netfilterRunner interface and moving iptables manipulation to a lower leveled iptables runner.
For #391
Signed-off-by: KevinLiang10 <kevinliang@tailscale.com>
This change updates the documentation for the fields on the location
struct.
Updates tailscale/corp#12146
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This commit updates our IP forwarding parsing logic to allow the less
common but still valid value of `2` to be parsed as `true`, which fixes
an error some users encountered.
Fixes#8375
Signed-off-by: Ross Zurowski <ross@rosszurowski.com>
Correct a minor cut-n-paste error that resulted in an invalid or
missing ping type being accepted as a disco ping.
Fixes#8457
Signed-off-by: Val <valerie@tailscale.com>
Redo the testwrapper to track and only retry flaky tests instead
of retrying the entire pkg. It also fails early if a non-flaky test fails.
This also makes it so that the go test caches are used.
Fixes#7975
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Instead of treating any lxcfs mount as an indicator that we're running
in a container, check for one of the mounts actually used by LXC
containers.
For reference, here's a list of mounts I am seeing in an LXC container:
```
$ grep lxcfs /proc/mounts
lxcfs /proc/cpuinfo fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
lxcfs /proc/diskstats fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
lxcfs /proc/loadavg fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
lxcfs /proc/meminfo fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
lxcfs /proc/stat fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
lxcfs /proc/swaps fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
lxcfs /proc/uptime fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
lxcfs /sys/devices/system/cpu/online fuse.lxcfs rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other 0 0
```
Fixes#8444
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This change adds Location field to HostInfo.
Location contains the option for a Country, CountryCode, City, CityCode
and a Priority. Neither of these fields are populated by default.
The Priority field is used to determine the priority an exit
node should be given for use, if the field is set. The higher the value
set, the higher priority the node should be given for use.
Updates tailscale/corp#12146
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Also switch the wrapper script to use bash not posix shell. We now
depend on bash elsewhere for saner behavior in esoteric areas, so
might as well use it everywhere for consistency.
Fixes#8425
Signed-off-by: David Anderson <danderson@tailscale.com>
As far as I can tell from the DSM documentation and known undocumented
fields, there is no 'version' field in this config file that DSM cares
about.
Updates #8232
Signed-off-by: David Anderson <danderson@tailscale.com>
ScrubbedGoroutineDump previously only returned the stacks of all
goroutines. I also want to be able to use this for only the current
goroutine's stack. Add a bool param to support both ways.
Updates tailscale/corp#5149
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There are two race conditions in output handling.
The first race condition is due to a misuse of exec.Cmd.StdoutPipe.
The documentation explicitly forbids concurrent use of StdoutPipe
with exec.Cmd.Wait (see golang/go#60908) because Wait will
close both sides of the pipe once the process ends without
any guarantees that all data has been read from the pipe.
To fix this, we allocate the os.Pipes ourselves and
manage cleanup ourselves when the process has ended.
The second race condition is because sshSession.run waits
upon exec.Cmd to finish and then immediately proceeds to call ss.Exit,
which will close all output streams going to the SSH client.
This may interrupt any asynchronous io.Copy still copying data.
To fix this, we close the write-side of the os.Pipes after
the process has finished (and before calling ss.Exit) and
synchronously wait for the io.Copy routines to finish.
Fixes#7601
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Co-authored-by: Maisem Ali <maisem@tailscale.com>
On redhat 9 and similarly locked down systems, root user does not have
access to a users directory. This fix does not set a directory for the
incubator process and instead sets the directory when the actual process
requested by remote user is executed.
Fixes#8118
Signed-off-by: Derek Burdick <derek-burdick@users.noreply.github.com>
Adds a `Tailscale-Headers-Info` header whenever the `Tailscale-User-`
headers are filled from the HTTP proxy handler.
Planning on hooking this shorturl up to KB docs about the header
values (i.e. what's a login name vs. display name) and security
considerations to keep in mind while using these headers - notibly
that they can also be filled from external requests that do not hit
tailscaled.
Updates https://github.com/tailscale/tailscale/issues/6954
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
prober uses NewRegionClient() to connect to a derper using a faked up
single-node region, but NewRegionClient() fails to connect if there is
no non-STUN only client in the region. Set the STUN only flag to false
before we call NewRegionClient() so we can monitor nodes marked as
STUN only in the default derpmap.
Updates #11492
Signed-off-by: Val <valerie@tailscale.com>
Trying to SSH when SELinux is enforced results in errors like:
```
➜ ~ ssh ec2-user@<ip>
Last login: Thu Jun 1 22:51:44 from <ip2>
ec2-user: no shell: Permission denied
Connection to <ip> closed.
```
while the `/var/log/audit/audit.log` has
```
type=AVC msg=audit(1685661291.067:465): avc: denied { transition } for pid=5296 comm="login" path="/usr/bin/bash" dev="nvme0n1p1" ino=2564 scontext=system_u:system_r:unconfined_service_t:s0 tcontext=unconfined_u:unconfined_r:unconfined_t:s0 tclass=process permissive=0
```
The right fix here would be to somehow install the appropriate context when
tailscale is installed on host, but until we figure out a way to do that
stop using the `login` cmd in these situations.
Updates #4908
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit continues the work from #8303, providing a method for a
tka.Authority to generate valid deeplinks for signing devices. We'll
use this to provide the necessary deeplinks for users to sign from
their mobile devices.
Updates #8302
Signed-off-by: Ross Zurowski <ross@rosszurowski.com>
Adds two new headers to HTTP serve proxy:
- `Tailscale-User-Login`: Filled with requester's login name.
- `Tailscale-User-Name`: Filled with requester's display name.
These headers only get filled when the SrcAddr is associated with
a non-tagged (i.e. user-owned) node within the client's Tailnet.
The headers are passed through empty when the request originated
from another tailnet, or the public internet (via funnel).
Updates https://github.com/tailscale/tailscale/issues/6954
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
* tka: provide verify-deeplink local API endpoint
Fixes https://github.com/tailscale/tailscale/issues/8302
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
Address code review comments
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
Address code review comments by Ross
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
* Improve error encoding, fix logic error
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
---------
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
The netstack code had a bunch of logic to figure out if the LocalBackend should handle an
incoming connection and then would call the function directly on LocalBackend. Move that
logic to LocalBackend and refactor the methods to return conn handlers.
Updates #cleanup
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Also fix a js/wasm issue with tsnet in the process. (same issue as WASI)
Updates #8320Fixes#8315
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If you start hearing everything in auto-tune for the rest of the day,
I take no responsibility for it.
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
We've talked in the past about reworking how bootstrap DNS works to
instead do recursive DNS resolution from the root; this would better
support on-prem customers and Headscale users where the DERP servers
don't currently resolve their DNS server. This package is an initial
implementation of recursive resolution for A and AAAA records.
Updates #5853
Change-Id: Ibe974d78709b4b03674b47c4ef61f9a00addf8b4
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
This basically allows running services on the SSH client and reaching
them from the SSH server during the session.
Updates #6575
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Switch our best address selection to use a scoring-based approach, where
we boost each address based on whether it's a private IP or IPv6.
For users in cloud environments, this biases endpoint selection towards
using an endpoint that is less likely to cost the user money, and should
be less surprising to users.
This also involves updating the tests to not use private IPv4 addresses;
other than that change, the behaviour should be identical for existing
endpoints.
Updates #8097
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I069e3b399daea28be66b81f7e44fc27b2943d8af
This PR removes all async functionality from the portlist package
which may be a breaking change for non-tailscale importers. The only
importer within this codebase (LocalBackend) is already using the synchronous
API so no further action needed.
Fixes#8171
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
This is needed in order to build our network extension on tvOS. First step for #8282
Signed-off-by: Andrea Gottardo <andrea@tailscale.com>
Co-authored-by: Andrea Gottardo <andrea@tailscale.com>
This is a follow up on PR #8172 that adds a synchronous Poll method
which allows for the Poller to be used as a zero value without needing
the constructor. The local backend is also changed to use the new API.
A follow up PR will remove the async functionality from the portlist package.
Updates #8171
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Max username length is increased to 256 on linux to match /usr/include/bits/local_lim.h
Fixes#8277
Signed-off-by: Derek Burdick <derek-burdick@users.noreply.github.com>
The invocation at the end unconditionally used
./tool/go, but the structuring on lines 14-17
sets up to use a different toolchain if the
platform requires it.
Fixes https://github.com/tailscale/tailscale/issues/8156
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
Allow calls to `WatchIPNBus` to be permformed by clients with
Readonly permissions. This brings it in line with the permissions
required for `Status`, which also exposes the similar information.
This allows clients to get realtime updates about the tailnet
in their own applications, without needing to actively poll the
`Status` endpoint.
Fixes https://github.com/tailscale/tailscale/issues/7797
Signed-off-by: Dominic Black <dom@encore.dev>
Instead of renewing certificates based on whether or not they're expired
at a fixed 14-day period in the future, renew based on whether or not
we're more than 2/3 of the way through the certificate's lifetime. This
properly handles shorter-lived certificates without issue.
Updates #8204
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I5e82a9cadc427c010d04ce58c7f932e80dd571ea
In order to improve our ability to understand the state of policies and
registry settings when troubleshooting, we enumerate all values in all subkeys.
x/sys/windows does not already offer this, so we need to call RegEnumValue
directly.
For now we're just logging this during startup, however in a future PR I plan to
also trigger this code during a bugreport. I also want to log more than just
registry.
Fixes#8141
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This adds a new `SetAuthorized` method that allows setting device
authorization to true or false. I chose the method name to be consistent
with SetTags.
Updates https://github.com/tailscale/corp/issues/10160
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This platform is technically an armv7, but has no hardware floating
point unit. armv5 is the only target Go understands to lack floating
point, so use that.
Updates #6860
Signed-off-by: David Anderson <danderson@tailscale.com>
Various BSD-derived operating systems including macOS and FreeBSD
require that ping6 be used for IPv6 destinations. The "ping" command
does not understand an IPv6 destination.
FreeBSD 13.x and later do handle IPv6 in the regular ping command,
but also retain a ping6 command. We use ping6 on all versions of
FreeBSD.
Fixes https://github.com/tailscale/tailscale/issues/8225
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
Some builders return absolute paths to build products already. When that
happens, the manifest writing logic shouldn't tack on another absolute
prefix.
Signed-off-by: David Anderson <danderson@tailscale.com>
go vet complains when we copy a lock value. Create clone function that
copies everything but the lock value.
Fixes#8207
Signed-off-by: Val <valerie@tailscale.com>
This PR parameterizes receiving loopback updates from the portlist package.
Callers can now include services bound to localhost if they want.
Note that this option is off by default still.
Fixes#8171
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
This change introduces a SSHSessionRecordingFailed event type
that is used when a session recording fails to start or fails during a
session, and the on failure indicates that it should fail open.
Updates tailscale/corp#9967
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
The authorize device API (/api/v2/device/{deviceID}/authorized)
will soon allow device deauthorisation.
Fixes corp#10160.
Signed-off-by: salman <salman@tailscale.com>
58ab66ec51 added LDAP support
for #4945 by shelling out to getdent.
It was supposed to fall back to the old method when getdent wasn't
found, but some variable name confusion (uid vs username) meant the
old path wasn't calling the right lookup function (user.LookupId
instead of user.Lookup).
Which meant that changed probably also broke FreeBSD and macOS SSH
support in addition to the reported OpenWRT regression.
The gokrazy support didn't look right either.
Fixes#8180
Change-Id: I273bbe96fe98b2517fbf0335fd476b483c051554
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Hey team! I've been diving deep into the code ocean for the past few
hours, tackling those sneaky race conditions that were threatening our
database. It was quite the crabby situation, but fear not! It's friday
and I've emerged and I'm ready to shell-ebrate with some punny word
additions. 🎉
This commit introduces a shell-shocking array of crustaceans to our word
list. From the lively lobsters to the clever prawns.
Signed-off-by: James Tucker <james@tailscale.com>
~97% of the log messages derper outputs are related to the normal
non-error state of a client disconnecting in some manner. Add a
verbose logging feature that only logs these messages when enabled.
Fixes#8024
Signed-off-by: Val <valerie@tailscale.com>
We were only closing on side of the pty/tty pair.
Close the other side too.
Thanks to @fritterhoff for reporting and debugging the issue!
Fixes#8119
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The client/tailscale is a stable-ish API we try not to break. Revert
the Client.CreateKey method as it was and add a new
CreateKeyWithExpiry method to do the new thing. And document the
expiry field and enforce that the time.Duration can't be between in
range greater than 0 and less than a second.
Updates #7143
Updates #8124 (reverts it, effectively)
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Adds a parameter for create key that allows a number of seconds
(less than 90) to be specified for new keys.
Fixes https://github.com/tailscale/tailscale/issues/7965
Signed-off-by: Matthew Brown <matthew@bargrove.com>
getSingleObject can return `nil, nil`, getDeviceInfo was not handling
that case which resulted in panics.
Fixes#7303
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We have two other types of Sets here. Add the basic obvious one too.
Needed for a change elsewhere.
Updates #cleanup
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The retry logic was pathological in the following ways:
* If we restarted the logging service, any pending uploads
would be placed in a retry-loop where it depended on backoff.Backoff,
which was too aggresive. It would retry failures within milliseconds,
taking at least 10 retries to hit a delay of 1 second.
* In the event where a logstream was rate limited,
the aggressive retry logic would severely exacerbate the problem
since each retry would also log an error message.
It is by chance that the rate of log error spam
does not happen to exceed the rate limit itself.
We modify the retry logic in the following ways:
* We now respect the "Retry-After" header sent by the logging service.
* Lacking a "Retry-After" header, we retry after a hard-coded period of
30 to 60 seconds. This avoids the thundering-herd effect when all nodes
try reconnecting to the logging service at the same time after a restart.
* We do not treat a status 400 as having been uploaded.
This is simply not the behavior of the logging service.
Updates #tailscale/corp#11213
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This test was either fixed by intermediate changes or was mis-flagged as
failing during #7876 triage.
Updates #7876
Signed-off-by: James Tucker <jftucker@gmail.com>
This test was either fixed in the intermediate time or mis-flagged
during the #7876 triage, but is now passing.
Updates #7876
Signed-off-by: James Tucker <jftucker@gmail.com>
The subshell in which gocross gets built cd's to the corp checkout dir
near the top, so all future references to corp repository files should
be simple relative paths, and not reference $repo_root. When $repo_root
is an absolute path, it doesn't matter and everything works out, but on
some OSes and shells and invocations, $repo_root is a completely relative
path that is invalidated by the "cd".
Fixestailscale/corp#11183
Signed-off-by: David Anderson <danderson@tailscale.com>
I noticed cmd/{cloner,viewer} didn't support structs with embedded
fields while working on a change in another repo. This adds support.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Wait 2 minutes before we start reporting battery usage. There is always
radio activity on initial startup, which gets reported as 100% high
power usage. Let that settle before we report usage data.
Updates tailscale/corp#9230
Signed-off-by: Will Norris <will@tailscale.com>
The previous commit 58ab66e added ssh/tailssh/user.go as part of
working on #4945. So move some more user-related code over to it.
Updates #cleanup
Change-Id: I24de66df25ffb8f867e1a0a540d410f9ef16d7b0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Current code will set the "dirty" field of VersionInfo always "true"
if vcs.modified flag is there. No matter whether the flag is "true" or
"false". It will make sense to set this field due to vcs.modified
value, not only the existence of the key.
Signed-off-by: Chenyang Gao <gps949@outlook.com>
Signed-off-by: Chenyang Gao <gps949@outlook.com>
in commit 6e96744, the tsd system type has been added.
Which will cause the daemon will crash on some OSs (Windows, darwin and so on).
The root cause is that on those OSs, handleSubnetsInNetstack() will return true and set the conf.Router with a wrapper.
Later in NewUserspaceEngine() it will do subsystem set and found that early set router mismatch to current value, then panic.
expvar can only be defined once, so running tests with a repeat counter
will fail if the variables are defined inside of the test function.
Observed failure:
```
--- FAIL: TestHandler (0.00s)
panic: Reuse of exported var name: gauge_promvarz_test_expvar
[recovered]
panic: Reuse of exported var name: gauge_promvarz_test_expvar
goroutine 9 [running]:
testing.tRunner.func1.2({0x100f267e0, 0x1400026e770})
/usr/local/go/src/testing/testing.go:1526 +0x1c8
testing.tRunner.func1()
/usr/local/go/src/testing/testing.go:1529 +0x364
panic({0x100f267e0, 0x1400026e770})
/usr/local/go/src/runtime/panic.go:884 +0x1f4
log.Panicln({0x140000b8e20?, 0x1a?, 0x1400026e750?})
/usr/local/go/src/log/log.go:398 +0x60
expvar.Publish({0x100e2b21d, 0x1a}, {0x100fd7a08?, 0x140000232c0})
/usr/local/go/src/expvar/expvar.go:284 +0xc0
expvar.NewInt(...)
/usr/local/go/src/expvar/expvar.go:304
tailscale.com/tsweb/promvarz.TestHandler(0x14000082b60)
/Users/charlotte/ts-src/tailscale/tsweb/promvarz/promvarz_test.go:18 +0x5c
testing.tRunner(0x14000082b60, 0x100fd5858)
/usr/local/go/src/testing/testing.go:1576 +0x104
created by testing.(*T).Run
/usr/local/go/src/testing/testing.go:1629 +0x370
FAIL tailscale.com/tsweb/promvarz 0.149s
```
Fixes#8065
Signed-off-by: James Tucker <james@tailscale.com>
This change bumps the capability version to 62, after support for
sending SSHEventNotificationRequests to control via noise for failure
events was introduced.
Updates tailscale/corp#9967
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This change adds a ConnectionID field to both SSHEventNotifyRequest and
CastHeader that identifies the ID of a connection to the SSH server.
Updates tailscale/corp#9967
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This change sends an SSHEventNotificationRequest over noise when a
SSH session is set to fail closed and the session is unable to start
because a recorder is not available or a session is terminated because
connection to the recorder is ended. Each of these scenarios have their
own event type.
Updates tailscale/corp#9967
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This change renames SSHFailureNotifyRequest to SSHEventNotifyRequest
to better reflect the additional events we could add in the future.
This change also adds an EventType used to catagories the events.
Updates tailscale/corp#9967
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
This change introduces a NodeKey func on localbackend that returns the
public node key.
Updates tailscale/corp#9967
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
It was supposed to be best effort but in some cases (macsys at least,
per @marwan-at-work) it hangs and exhausts the whole context.Context
deadline so we fail to make the SetDNS call to the server.
Updates #8067
Updates #3273 etc
Change-Id: Ie1f04abe9689951484748aecdeae312afbafdb0f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
`interfaces.Tailscale()` returns all zero values when it finds no
Tailscale interface and encounters no errors. The netns package was
treating no error as a signal that it would receive a non-zero pointer
value leading to nil pointer dereference.
Observed in:
```
--- FAIL: TestGetInterfaceIndex (0.00s)
--- FAIL: TestGetInterfaceIndex/IP_and_port (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x1029eb7d8]
goroutine 7 [running]:
testing.tRunner.func1.2({0x102a691e0, 0x102bc05c0})
/Users/raggi/.cache/tailscale-go/src/testing/testing.go:1526 +0x1c8
testing.tRunner.func1()
/Users/raggi/.cache/tailscale-go/src/testing/testing.go:1529 +0x384
panic({0x102a691e0, 0x102bc05c0})
/Users/raggi/.cache/tailscale-go/src/runtime/panic.go:884 +0x204
tailscale.com/net/netns.getInterfaceIndex(0x14000073f28, 0x1028d0284?, {0x1029ef3b7, 0xa})
/Users/raggi/src/github.com/tailscale/tailscale/net/netns/netns_darwin.go:114 +0x228
tailscale.com/net/netns.TestGetInterfaceIndex.func2(0x14000138000)
/Users/raggi/src/github.com/tailscale/tailscale/net/netns/netns_darwin_test.go:37 +0x54
testing.tRunner(0x14000138000, 0x140000551b0)
/Users/raggi/.cache/tailscale-go/src/testing/testing.go:1576 +0x10c
created by testing.(*T).Run
/Users/raggi/.cache/tailscale-go/src/testing/testing.go:1629 +0x368
FAIL tailscale.com/net/netns 0.824s
```
Fixes#8064
Signed-off-by: James Tucker <jftucker@gmail.com>
This is part of an effort to clean up tailscaled initialization between
tailscaled, tailscaled Windows service, tsnet, and the mac GUI.
Updates #8036
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Periodic update for start of cycle. goreleaser is not updated to v2 yet,
but indirects updated.
Updates #8043
Signed-off-by: James Tucker <james@tailscale.com>
Installer script relies on pkgs.tailscale.com being reachable, both for
checking what Linux distros are supported, but also for actually
downloading repo configuration files, gpg keys and packages themselves.
This change adds a simple reachability check which will print an error
message when pkgs.tailscale.com is not reachable.
Fixes https://github.com/tailscale/corp/issues/8952
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This holds back gvisor, kubernetes, goreleaser, and esbuild, which all
had breaking API changes.
Updates #8043
Updates #7381
Updates #8042 (updates u-root which adds deps)
Change-Id: I889759bea057cd3963037d41f608c99eb7466a5b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We removed it earlier in 916aa782af, but we still want to support it for some time longer.
Updates tailscale/corp#9967
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This change introduces address selection for wireguard only endpoints.
If a endpoint has not been used before, an address is randomly selected
to be used based on information we know about, such as if they are able
to use IPv4 or IPv6. When an address is initially selected, we also
initiate a new ICMP ping to the endpoints addresses to determine which
endpoint offers the best latency. This information is then used to
update which endpoint we should be using based on the best possible
route. If the latency is the same for a IPv4 and an IPv6 address, IPv6
will be used.
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
In the case where the exit node requires SNAT, we would SNAT all traffic not just the
traffic meant to go through the exit node. This was a result of the default route being
added to the routing table which would match basically everything.
In this case, we need to account for all peers in the routing table not just the ones
that require NAT.
Fix and add a test.
Updates tailscale/corp#8020
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Avoid selecting an endpoint as "better" than the current endpoint if the
total latency improvement is less than 1%. This adds some hysteresis to
avoid flapping between endpoints for a minimal improvement in latency.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If8312e1768ea65c4b4d4e13d8de284b3825d7a73
This passes the *dnscache.Resolver down from the Direct client into the
Noise client and from there into the controlhttp client. This retains
the Resolver so that it can share state across calls instead of creating
a new resolver.
Updates #4845
Updates #6110
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ia5d6af1870f3b5b5d7dd5685d775dcf300aec7af
Every time we change `installer.sh`, run it in a few docker
containers based on different Linux distros, just as a simple test.
Also includes a few changes to the installer script itself to make
installation work in docker:
- install dnf config-manager command before running it
- run zypper in non-interactive mode
- update pacman indexes before installing packages
Updates https://github.com/tailscale/corp/issues/8952
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
I need this for a corp change where I have a set as a queue, and make a
different decisison if the set is empty.
Updates tailscale/corp#10344
Signed-off-by: James Tucker <james@tailscale.com>
Can't have a dupe when the dupe is wrong. Clearly we need to up
our spell checking game. Did anyone say AI?
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
The action cache restore process either matches the restore key pattern
exactly, or uses a matching prefix with the most recent date.
If the restore key is an exact match, then no updates are uploaded, but
if we've just computed tests executions for more recent code then we
will likely want to use those results in future runs.
Appending run_id to the cache key will give us an always new key, and
then we will be restore a recently uploaded cache that is more likely
has a higher overlap with the code being tested.
Updates #7975
Signed-off-by: James Tucker <james@tailscale.com>
DERP doesn't support HTTP/2. If an HTTP/2 proxy was placed in front of
a DERP server requests would fail because the connection would
be initialized with HTTP/2, which the DERP client doesn't support.
Signed-off-by: Kyle Carberry <kyle@carberry.com>
This change adds a v6conn to the pinger to enable sending pings to v6
addrs.
Updates #7826
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
We need to always specify tags when creating an AuthKey from an OAuth key.
Check for that, and reuse the `--advertise-tags` param.
Updates #7982
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This fix does not seem ideal, but the test infrastructure using a local
goos doesn't seem to avoid all of the associated challenges, but is
somewhat deeply tied to the setup.
The core issue this addresses for now is that when run on Windows there
can be no code paths that attempt to use an invalid UID string, which on
Windows is described in [1].
For the goos="linux" tests, we now explicitly skip the affected
migration code if runtime.GOOS=="windows", and for the Windows test we
explicitly use the running users uid, rather than just the string
"user1". We also now make the case where a profile exists and has
already been migrated a non-error condition toward the outer API.
Updates #7876
[1] https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers
Signed-off-by: James Tucker <jftucker@gmail.com>
Benchmark flags prevent test caching, so benchmarks are now executed
independently of tests.
Fixes#7975
Signed-off-by: James Tucker <james@tailscale.com>
Previously we would error out when the recording server disappeared after the in memory
buffer filled up for the io.Copy. This makes it so that we handle failing open correctly
in that path.
Updates tailscale/corp#9967
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Fixes#6784
This PR makes it so that we can persist the tailscaled state with
intelligent tiering which increases the capacity from 4kb to 8kb
Signed-off-by: Marwan Sulaiman <marwan@tailscale.com>
Looks like on some systems there's an IPv6 address, but then opening
a IPv6 UDP socket fails later. Probably some firewall. Tolerate it
better and don't crash.
To repro: check the "udp6" to something like "udp7" (something that'll
fail) and run "go run ./cmd/tailscale netcheck" on a machine with
active IPv6. It used to crash and now it doesn't.
Fixes#7949
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This adds support to try dialing out to multiple recorders each
with a 5s timeout and an overall 30s timeout. It also starts respecting
the actions `OnRecordingFailure` field if set, if it is not set
it fails open.
Updates tailscale/corp#9967
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This allows control to specify how to handle situations where the recorder
isn't available.
Updates tailscale/corp#9967
Signed-off-by: Maisem Ali <maisem@tailscale.com>
A follow-up PR will start using this field after we set it in our
production DERPMap.
Updates #7925
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Idb41b79e6055dddb8944f79d91ad4a186ace98c7
On some platforms (notably macOS and iOS) we look up the default
interface to bind outgoing connections to. This is both duplicated
work and results in logspam when the default interface is not available
(i.e. when a phone has no connectivity, we log an error and thus cause
more things that we will try to upload and fail).
Fixed by passing around a netmon.Monitor to more places, so that we can
use its cached interface state.
Fixes#7850
Updates #7621
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
We are seeing indications that some devices are still getting into an
upload loop. Bump logInterval in case these devices are on slow
connections that are taking more than 3 seconds to uploads sockstats.
Updates #7719
Signed-off-by: Will Norris <will@tailscale.com>
We're using it in more and more places, and it's not really specific to
our use of Wireguard (and does more just link/interface monitoring).
Also removes the separate interface we had for it in sockstats -- it's
a small enough package (we already pull in all of its dependencies
via other paths) that it's not worth the extra complexity.
Updates #7621
Updates #7850
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
I manually tested that the code path that relaxes pipe permissions is
not executed when run with elevated priviliges, and the test also passes
in that case.
Updates #7876
Signed-off-by: James Tucker <jftucker@gmail.com>
The test is re-enabled for Windows with a relaxed time assertion.
On Windows the runtime poller currently does not have sufficient
resolution to meet the normal requirements for this test.
See https://github.com/golang/go/issues/44343 for background.
Updates #7876
Signed-off-by: James Tucker <jftucker@gmail.com>
This is a follow-up to #7905 that adds two more linters and fixes the corresponding findings. As per the previous PR, this only flags things that are "obviously" wrong, and fixes the issues found.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8739bdb7bc4f75666a7385a7a26d56ec13741b7c
Without this, the peer fails to do anything over the PeerAPI if it
has a masquerade address.
```
Apr 19 13:58:15 hydrogen tailscaled[6696]: peerapi: invalid request from <ip>:58334: 100.64.0.1/32 not found in self addresses
```
Updates #8020
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Found this when adding a test that does a ping over PeerAPI.
Our integration tests set up a trafficTrap to ensure that tailscaled
does not call out to the internet, and it does so via a HTTP_PROXY.
When adding a test for pings over PeerAPI, it triggered the trap and investigation
lead to the realization that we were not removing the Proxy when trying to
dial out to the PeerAPI.
Updates tailscale/corp#8020
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Exposes some internal state of the sockstats package via the C2N and
PeerAPI endpoints, so that it can be used for debugging. For now this
includes the estimated radio on percentage and a second-by-second view
of the times the radio was active.
Also fixes another off-by-one error in the radio on percentage that
was leading to >100% values (if n seconds have passed since we started
to monitor, there may be n + 1 possible seconds where the radio could
have been on).
Updates tailscale/corp#9230
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
When splitting the radio monitor usage array, we were splitting at now %
3600 to get values into chronological order. This caused the value for
the final second to be included at the beginning of the ordered slice
rather than the end. If there was activity during that final second, an
extra five seconds of high power usage would get recorded in some cases.
This could result in a final calculation of greater than 100% usage.
This corrects that by splitting values at (now+1 % 3600).
This also simplifies the percentage calculation by always rounding
values down, which is sufficient for our usage.
Signed-off-by: Will Norris <will@tailscale.com>
It's somewhat common (e.g. when a phone has no reception), and leads to
lots of logspam.
Updates #7850
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This adds an initial and intentionally minimal configuration for
golang-ci, fixes the issues reported, and adds a GitHub Action to check
new pull requests against this linter configuration.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8f38fbc315836a19a094d0d3e986758b9313f163
Exclude traffic with 100.100.100.100 (for IPv4) and
with fd7a:115c:a1e0::53 (for IPv6) since this traffic with the
Tailscale service running locally on the node.
This traffic never left the node.
It also happens to be a high volume amount of traffic since
DNS requests occur over UDP with each request coming from a
unique port, thus resulting in many discrete traffic flows.
Fixestailscale/corp#10554
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Redoes the approach from #5550 and #7539 to explicitly pass in the logf
function, instead of having global state that can be overridden.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
TestMonitorMode skips by default, without the --monitor flag, and then
it previously ran forever. This adds an option --monitor-duration flag
that defaults to zero (run forever) but if non-zero bounds how long
the tests runs. This means you can then also use e.g. `go test
--cpuprofile` and capture a CPU/mem profile for a minute or two.
Updates #7621
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is a continuation of the earlier 2a67beaacf but more aggressive;
this now remembers that we failed to find the "home" router IP so we
don't try again later on the next call.
Updates #7621
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Previously, when updating endpoints we would immediately stop
advertising any endpoint that wasn't discovered during
determineEndpoints. This could result in, for example, a case where we
performed an incremental netcheck, didn't get any of our three STUN
packets back, and then dropped our STUN endpoint from the set of
advertised endpoints... which would result in clients falling back to a
DERP connection until the next call to determineEndpoints.
Instead, let's cache endpoints that we've discovered and continue
reporting them to clients until a timeout expires. In the above case
where we temporarily don't have a discovered STUN endpoint, we would
continue reporting the old value, then re-discover the STUN endpoint
again and continue reporting it as normal, so clients never see a
withdrawal.
Updates tailscale/coral#108
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I42de72e7418ab328a6c732bdefc74549708cf8b9
The comment still said *magicsock.Conn implemented wireguard-go conn.Bind.
That wasn't accurate anymore.
A doc #cleanup.
Change-Id: I7fd003b939497889cc81147bfb937b93e4f6865c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
So we're staying within the netip.Addr/AddrPort consistently and
avoiding allocs/conversions to the legacy net addr types.
Updates #5162
Change-Id: I59feba60d3de39f773e68292d759766bac98c917
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
These tests are passing locally and on CI. They had failed earlier in
the day when first fixing up CI, and it is not immediately clear why. I
have cycled IPv6 support locally, but this should not have a substantial
effect.
Updates #7876
Signed-off-by: James Tucker <jftucker@gmail.com>
This test is not regularly passing on CI, but seems to pass reliably
locally. Needs deeper debugging.
Updates #7876
Signed-off-by: James Tucker <jftucker@gmail.com>
Go artifact caching will help provided that the cache remains small
enough - we can reuse the strategy from the Windows build where we only
cache and pull the zips, but let go(1) do the many-file unpacking as it
does so faster.
The race matrix was building once without race, then running all the
tests with race, so change the matrix to incldue a `buildflags`
parameter and use that both in the build and test steps.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
This is an exact copy of the files misc/set/set{,_test}.go from
tailscale/corp@a5415daa9c, plus the
license headers.
For use in #7877
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I712d09c6d1a180c6633abe3acf8feb59b27e2866
We accidentally switched to ./tool/go in
4022796484 which resulted in no longer
running Windows builds, as this is attempting to run a bash script.
I was unable to quickly fix the various tests that have regressed, so
instead I've added skips referencing #7876, which we need to back and
fix.
Updates #7262
Updates #7876
Signed-off-by: James Tucker <james@tailscale.com>
example was missing the "-auth" type in the key prefix, which all new
keys now contain. Also update key ID to match the full key, and fix
indenting of closing braces.
Signed-off-by: Will Norris <will@tailscale.com>
To get the tree green again for other people.
Updates #7866
Change-Id: Ibdad2e1408e5f0c97e49a148bfd77aad17c2c5e5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This also adds a bunch of tests for this function to ensure that we're
returning the proper IP(s) in all cases.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I0d9d57170dbab5f2bf07abdf78ecd17e0e635399
This makes `omitempty` actually work, and saves bytes in each map response.
Updates tailscale/corp#8020
Signed-off-by: Maisem Ali <maisem@tailscale.com>
At the current unoptimized memory utilization of the various data structures,
100k IPv6 routes consumes in the ballpark of 3-4GiB, which risks OOMing our
386 test machine.
Until we have the optimizations to (drastically) reduce that consumption,
skip the test that bloats too much for 32-bit machines.
Signed-off-by: David Anderson <danderson@tailscale.com>
Using log.Printf may end up being printed out to the console, which
is not desirable. I noticed this when I was investigating some client
logs with `sockstats: trace "NetcheckClient" was overwritten by another`.
That turns to be harmless/expected (the netcheck client will fall back
to the DERP client in some cases, which does its own sockstats trace).
However, the log output could be visible to users if running the
`tailscale netcheck` CLI command, which would be needlessly confusing.
Updates tailscale/corp#9230
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
We use it to gate code that depends on custom Go toolchain, but it's
currently only passed in the corp runners. Add a set on OSS so that we
can catch regressions earlier.
To specifically test sockstats this required adding a build tag to
explicitly enable them -- they're normally on for iOS, macOS and Android
only, and we don't run tests on those platforms normally.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
It's used to control various opt-in functionality for the macOS and iOS
apps, and was lost in the migration to gocross.
Updates tailscale/tailscale#7769
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
This splits Prometheus metric handlers exposed by tsweb into two
modules:
- `varz.Handler` exposes Prometheus metrics generated by our expvar
converter;
- `promvarz.Handler` combines our expvar-converted metrics and native
Prometheus metrics.
By default, tsweb will use the promvarz handler, however users can keep
using only the expvar converter. Specifically, `tailscaled` now uses
`varz.Handler` explicitly, which avoids a dependency on the
(heavyweight) Prometheus client.
Updates https://github.com/tailscale/corp/issues/10205
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This provides an example of using native Prometheus metrics with tsweb.
Prober library seems to be the only user of PrometheusVar, so I am
removing support for it in tsweb.
Updates https://github.com/tailscale/corp/issues/10205
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
The handler will expose built-in process and Go metrics by default,
which currently duplicate some of the expvar-proxied metrics
(`goroutines` vs `go_goroutines`, `memstats` vs `go_memstats`), but as
long as their names are different, Prometheus server will just scrape
both.
This will change /debug/varz behaviour for most tsweb binaries, but
notably not for control, which configures a `tsweb.VarzHandler`
[explicitly](a5b5d5167f/cmd/tailcontrol/tailcontrol.go (L779))
Updates https://github.com/tailscale/corp/issues/10205
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Otherwise there may be a panic if it's nil (and the control side of
the c2n call will just time out).
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Makes it more apparent in the PeerAPI endpoint that the client was
not built with the appropriate toolchain or build tags.
Updates tailscale/corp#9230
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
The lazy initialization of the disco key is not necessary, and
contributes to unnecessary locking and state checking.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
Running tailscaled with the race detector enabled immediately fires on
this field, as it is updated after first read.
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
A peer can have IsWireGuardOnly, which means it will not support DERP or
Disco, and it must have Endpoints filled in order to be usable.
In the present implementation only the first Endpoint will be used as
the bestAddr.
Updates tailscale/corp#10351
Co-authored-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Co-authored-by: James Tucker <james@tailscale.com>
Signed-off-by: James Tucker <james@tailscale.com>
Identified in review in #7821 endpoint.discoKey and endpoint.discoShort
are often accessed without first taking endpoint.mu. The arrangement
with endpoint.mu is inconvenient for a good number of those call-sites,
so it is instead replaced with an atomic pointer to carry both pieces of
disco info. This will also help with #7821 that wants to add explicit
checks/guards to disable disco behaviors when disco keys are missing
which is necessarily implicitly mostly covered by this change.
Updates #7821
Signed-off-by: James Tucker <james@tailscale.com>
power state is very roughly approximated based on observed network
activity and AT&T's state transition timings for a typical 3G radio.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Will Norris <will@tailscale.com>
Adds NewGaugeFunc and NewCounterFunc (inspired by expvar.Func) which
change the current value to be reported by a function. This allows
some client metric values to be computed on-demand during uploading (at
most every 15 seconds), instead of being continuously updated.
clientmetric uploading had a bunch of micro-optimizations for memory
access (#3331) which are not possible with this approach. However, any
performance hit from function-based metrics is contained to those metrics
only, and we expect to have very few.
Also adds a DisableDeltas() option for client metrics, so that absolute
values are always reported. This makes server-side processing of some
metrics easier to reason about.
Updates tailscale/corp#9230
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Make developing derp easier by:
1. Creating an envknob telling clients to use HTTP to connect to derp
servers, so devs don't have to acquire a valid TLS cert.
2. Creating an envknob telling clients which derp server to connect
to, so devs don't have to edit the ACLs in the admin console to add a
custom DERP map.
3. Explaining how the -dev and -a command lines args to derper
interact.
To use this:
1. Run derper with -dev.
2. Run tailscaled with TS_DEBUG_USE_DERP_HTTP=1 and
TS_DEBUG_USE_DERP_ADDR=localhost
This will result in the client connecting to derp via HTTP on port
3340.
Fixes#7700
Signed-off-by: Val <valerie@tailscale.com>
This commit implements UDP offloading for Linux. GSO size is passed to
and from the kernel via socket control messages. Support is probed at
runtime.
UDP GSO is dependent on checksum offload support on the egress netdev.
UDP GSO will be disabled in the event sendmmsg() returns EIO, which is
a strong signal that the egress netdev does not support checksum
offload.
Updates tailscale/corp#8734
Signed-off-by: Jordan Whited <jordan@tailscale.com>
macOS does not allow unix socket creation in private temp directories,
but global /tmp is ok, so swap out for global temp for now.
Updates #7658
Updates #7785
Signed-off-by: James Tucker <jftucker@gmail.com>
This makes the sockstat logger available on all builds, but only enables
it by default for unstable. For stable builds, the logger must be
explicitly enabled via C2N component logger.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Will Norris <will@tailscale.com>
I realized that a lot of the problems that we're seeing around migration and
LocalBackend state can be avoided if we drive Windows pref migration entirely
from within tailscaled. By doing it this way, tailscaled can automatically
perform the migration as soon as the connection with the client frontend is
established.
Since tailscaled is already running as LocalSystem, it already has access to
the user's local AppData directory. The profile manager already knows which
user is connected, so we simply need to resolve the user's prefs file and read
it from there.
Of course, to properly migrate this information we need to also check system
policies. I moved a bunch of policy resolution code out of the GUI and into
a new package in util/winutil/policy.
Updates #7626
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This adds the util/sysresources package, which currently only contains a
function to return the total memory size of the current system.
Then, we modify magicsock to scale the number of buffered DERP messages
based on the system's available memory, ensuring that we never use a
value lower than the previous constant of 32.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ib763c877de4d0d4ee88869078e7d512f6a3a148d
The intent of atomicfile is to overwrite regular files. Most use cases
that would overwrite irregular files, unix sockets, named pipes,
devices, and so on are more than likely misuse, so disallow them.
Fixes#7658
Signed-off-by: James Tucker <james@tailscale.com>
#7339 changed the root directory logic to find the ancestor of the cwd
with a go.mod file. This works when running the the binary from this
repo directly, but breaks when we're a dependency in another repo.
Allow the directory to be passed in via a -rootdir flag (the repo that
depends on it can then use `go list -m -f '{{.Dir}}' tailscale.com`
or similar to pass in the value).
Updates tailscale/corp#10165
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Noted on #5915 TS_DEBUG_MTU was not used consistently everywhere.
Extract the default into a function that can apply this centrally and
use it everywhere.
Added envknob.Lookup{Int,Uint}Sized to make it easier to keep CodeQL
happy when using converted values.
Updates #5915
Signed-off-by: James Tucker <james@tailscale.com>
A LogKnob allows enabling logs with an envknob, netmap capability, and
manually, and calling a logging function when logs are enabled.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Id66c608d4e488bfd4eaa5e867a8d9289686748be
For stores like k8s secrets we need to dial out to the k8s API as though Tailscale
wasn't running. The issue currently only manifests when you try to use an exit node
while running inside a k8s cluster and are trying to use Kubernetes secrets as the
backing store.
This doesn't address cmd/containerboot, which I'll do in a follow up.
Updates #7695
Signed-off-by: Maisem Ali <maisem@tailscale.com>
When running a SOCKS or HTTP proxy, configure the tshttpproxy package to
drop those addresses from any HTTP_PROXY or HTTPS_PROXY environment
variables.
Fixes#7407
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I6cd7cad7a609c639780484bad521c7514841764b
Split apart polling of sockstats and logging them to disk. Add a 3
second delay before writing logs to disk to prevent an infinite upload
loop when uploading stats to logcatcher.
Fixes#7719
Signed-off-by: Will Norris <will@tailscale.com>
This adds support to make exit nodes and subnet routers work
when in scenarios where NAT is required.
It also updates the NATConfig to be generated from a `wgcfg.Config` as
that handles merging prefs with the netmap, so it has the required information
about whether an exit node is already configured and whether routes are accepted.
Updates tailscale/corp#8020
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Since users can run tailscaled in a variety of ways (root, non-root,
non-root with process capabilities on Linux), this check will print the
current process permissions to the log to aid in debugging.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ida93a206123f98271a0c664775d0baba98b330c7
Recent egrep builds produce a warning:
```
egrep: warning: egrep is obsolescent; using grep -E
```
Updates #cleanup
Signed-off-by: James Tucker <james@tailscale.com>
Use the local context on Impl to check for shut down state in order to
drop rather than inject packets after close has begun.
Netstack sets endpoint.dispatcher to nil during shutdown. After the
recent adjustment in 920ec69241 we now
wait for netstack to fully shutdown before we release tests. This means
that we may continue to accept packets and attempt to inject them, which
we must prevent in order to avoid nil pointer panic.
References google/gvisor#8765Fixes#7715
Signed-off-by: James Tucker <james@tailscale.com>
There were two code paths that could fail depending on how fast
the recorder responses. This fixes that by returning the correct
error from both paths.
Fixes#7707
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit updates the wireguard-go dependency to pull in fixes for
the tun package, specifically 052af4a and aad7fca.
Signed-off-by: Jordan Whited <jordan@tailscale.com>
In addition to checking the total hostname length, validate characters used in each DNS label and label length.
Updates https://github.com/tailscale/corp/issues/10012
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
The reverse proxy was sending the ingressd IPv6 down as the
X-Forwarded-For. This update uses the actual remote addr.
Updates tailscale/corp#9914
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
This change trims the mountPoint from the request URL path before
sending the request to the reverse proxy.
Today if you mount a proxy at `/foo` and request to
`/foo/bar/baz`, we leak the `mountPoint` `/foo` as part of the request
URL's path.
This fix makes removed the `mountPoint` prefix from the path so
proxied services receive requests as if they were running at the root
(`/`) path.
This could be an issue if the app generates URLs (in HTML or otherwise)
and assumes `/path`. In this case, those URLs will 404.
With that, I still think we should trim by default and not leak the
`mountPoint` (specific to Tailscale) into whatever app is hosted.
If it causes an issue with URL generation, I'd suggest looking at configuring
an app-specific path prefix or running Caddy as a more advanced
solution.
Fixes: #6571
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
* wgengine/magicsock: add envknob to send CallMeMaybe to non-existent peer
For testing older client version responses to the PeerGone packet format change.
Updates #4326
Signed-off-by: Val <valerie@tailscale.com>
* derp: remove dead sclient struct member replaceLimiter
Leftover from an previous solution to the duplicate client problem.
Updates #2751
Signed-off-by: Val <valerie@tailscale.com>
* derp, derp/derphttp, wgengine/magicsock: add new PeerGone message type Not Here
Extend the PeerGone message type by adding a reason byte. Send a
PeerGone "Not Here" message when an endpoint sends a disco message to
a peer that this server has no record of.
Fixes#4326
Signed-off-by: Val <valerie@tailscale.com>
---------
Signed-off-by: Val <valerie@tailscale.com>
If multiple Go channels have a value (or are closed), receiving from
them all in a select will nondeterministically return one of the two
arms. In this case, it's possible that the hairpin check timer will have
expired between when we start checking and before we check at all, but
the hairpin packet has already been received. In such cases, we'd
nondeterministically set report.HairPinning.
Instead, check if we have a value in our results channel first, then
select on the value and timeout channel after. Also, add a test that
catches this particular failure.
Fixes#1795
Change-Id: I842ab0bd38d66fabc6cabf2c2c1bb9bd32febf35
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
We were checking against the wrong directory, instead if we
have a custom store configured just use that.
Fixes#7588Fixes#7665
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We were not storing the ACME keys in the state store, they would always
be stored on disk.
Updates #7588
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This adds support in tstun to utitilize the SelfNodeV4MasqAddrForThisPeer and
perform the necessary modifications to the packet as it passes through tstun.
Currently this only handles ICMP, UDP and TCP traffic.
Subnet routers and Exit Nodes are also unsupported.
Updates tailscale/corp#8020
Co-authored-by: Melanie Warrick <warrick@tailscale.com>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This only adds the field, to be used in a future commit.
Updates tailscale/corp#8020
Co-authored-by: Melanie Warrick <warrick@tailscale.com>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Previously it would dial out using the http.DefaultClient, however that doesn't work
when tailscaled is running in userspace mode (e.g. when testing).
Updates tailscale/corp#9967
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Kubernetes uses SPDY/3.1 which is incompatible with HTTP/2, disable it
in the transport and server.
Fixes#7645Fixes#7646
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Kubernetes doesn't allow slashes as keys in secrets, replace them with "__".
This shows up in the kubernetes-operator now that tsnet sets resets the ServeConfig
at startup.
Fixes#7662
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This change focuses on the backend log ID, which is the mostly commonly
used in the client. Tests which don't seem to make use of the log ID
just use the zero value.
Signed-off-by: Will Norris <will@tailscale.com>
Move the assertions about our post-privilege-drop UID/GID out of the
conditional if statement and always run them; I haven't been able to
find a case where this would fail. Defensively add an envknob to disable
this feature, however, which we can remove after the 1.40 release.
Updates #7616
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Iaec3dba9248131920204bd6c6d34bbc57a148185
This makes it less likely that we trip over bugs like golang/go#1435.
Updates #7616
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ic28c03c3ad8ed5274a795c766b767fa876029f0e
Otherwise we see errors like
```
ssh-session(sess-20230322T005655-5562985593): recording: error sending recording to <addr>:80: Post "http://<addr>:80/record": context canceled
```
The ss.ctx is closed when the session closes, but we don't want to break the upload at that time. Instead we want to wait for the session to
close the writer when it finishes, which it is already doing.
Updates tailscale/corp#9967
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Switch to using logtail for logging sockstat logs. Always log locally
(on supported platforms), but disable automatic uploading. Change
existing c2n sockstats request to trigger upload to log server and
return log ID.
Signed-off-by: Will Norris <will@tailscale.com>
Allows the iOS and macOS apps to include their frontend logs when
generating bug reports (tailscale/corp#9982).
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Currently we only send down recorders in first action, allow the final action
to replace them but not to drop them.
Updates tailscale/corp#9967
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This change introduces the Recorders field to the SSHRule struct. The
field is used to store and define addresses where the ssh recorder is
located.
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Previously, the build ended up embedding an empty string, which made
the shell wrapper rebuild gocross on every invocation. This is still
reasonably fast, but fixing the bypass shaves 80% off gocross's overhead
when no rebuild is needed.
Signed-off-by: David Anderson <danderson@tailscale.com>
Followup to #7518 to also export client metrics when the active interface
is cellular.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
A bunch of us invoke tool/go from outside the repo that hosts gocross,
as a way of accessing our version-controlled toolchain. This removes
assumptions from gocross that it's being invoked within the repository
that contains its source code and toolchain configuration.
Fixestailscale/corp#9627
Signed-off-by: David Anderson <danderson@tailscale.com>
This used to make sense, but after a refactor somewhere along the line
this results in trying to download from a malformed URL and generally
confusing failures.
Signed-off-by: David Anderson <danderson@tailscale.com>
In May 2021, Azure App Services used 172.16.x.x addresses:
```
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 02:42:ac:10:01:03 brd ff:ff:ff:ff:ff:ff
inet 172.16.1.3/24 brd 172.16.1.255 scope global eth0
valid_lft forever preferred_lft forever
```
Now it uses link-local:
```
2: eth0@if6: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
link/ether 8a:30:1f:50:1d:23 brd ff:ff:ff:ff:ff:ff
inet 169.254.129.3/24 brd 169.254.129.255 scope global eth0
valid_lft forever preferred_lft forever
```
This is reasonable for them to choose to do, it just broke the handling in net/interfaces.
This PR proposes to:
1. Always allow link-local in LocalAddresses() if we have no better
address available.
2. Continue to make isUsableV4() conditional on an environment we know
requires it.
I don't love the idea of having to discover these environments one by
one, but I don't understand the consequences of making isUsableV4()
return true unconditionally. It makes isUsableV4() essentially always
return true and perform no function.
Fixes https://github.com/tailscale/tailscale/issues/7603
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
On FreeBSD and Darwin, changing a process's supplementary groups with
setgroups(2) will also change the egid of the process, setting it to the
first entry in the provided list. This is distinct from the behaviour on
other platforms (and possibly a violation of the POSIX standard).
Because of this, on FreeBSD with no TTY, our incubator code would
previously not change the process's gid, because it would read the
newly-changed egid, compare it against the expected egid, and since they
matched, not change the gid. Because we didn't use the 'login' program
on FreeBSD without a TTY, this would propagate to a child process.
This could be observed by running "id -p" in two contexts. The expected
output, and the output returned when running from a SSH shell, is:
andrew@freebsd:~ $ id -p
uid andrew
groups andrew
However, when run via "ssh andrew@freebsd id -p", the output would be:
$ ssh andrew@freebsd id -p
login root
uid andrew
rgid wheel
groups andrew
(this could also be observed via "id -g -r" to print just the gid)
We fix this by pulling the details of privilege dropping out into their
own function and prepending the expected gid to the start of the list on
Darwin and FreeBSD.
Finally, we add some tests that run a child process, drop privileges,
and assert that the final UID/GID/additional groups are what we expect.
More information can be found in the following article:
https://www.usenix.org/system/files/login/articles/325-tsafrir.pdf
Updates #7616
Alternative to #7609
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I0e6513c31b121108b50fe561c89e5816d84a45b9
This allows tracking packet flow via logs for prober clients. Note that
the new sclient.debug() function is called on every received packet, but
will do nothing for most clients.
I have adjusted sclient logging to print public keys in short format
rather than full. This takes effect even for existing non-debug logging
(mostly client disconnect messages).
Example logs for a packet being sent from client [SbsJn] (connected to
derper [dM2E3]) to client [10WOo] (connected to derper [AVxvv]):
```
derper [dM2E3]:
derp client 10.0.0.1:35470[SbsJn]: register single client mesh("10.0.1.1"): 4 peers
derp client 10.0.0.1:35470[SbsJn]: read frame type 4 len 40 err <nil>
derp client 10.0.0.1:35470[SbsJn]: SendPacket for [10WOo], forwarding via <derphttp_client.Client [AVxvv] url=https://10.0.1.1/derp>: <nil>
derp client 10.0.0.1:35470[SbsJn]: read frame type 0 len 0 err EOF
derp client 10.0.0.1:35470[SbsJn]: read EOF
derp client 10.0.0.1:35470[SbsJn]: sender failed: context canceled
derp client 10.0.0.1:35470[SbsJn]: removing connection
derper [AVxvv]:
derp client 10.0.1.1:50650[10WOo]: register single client
derp client 10.0.1.1:50650[10WOo]: received forwarded packet from [SbsJn] via [dM2E3]
derp client 10.0.1.1:50650[10WOo]: sendPkt attempt 0 enqueued
derp client 10.0.1.1:50650[10WOo]: sendPacket from [SbsJn]: <nil>
derp client 10.0.1.1:50650[10WOo]: read frame type 0 len 0 err EOF
derp client 10.0.1.1:50650[10WOo]: read EOF
derp client 10.0.1.1:50650[10WOo]: sender failed: context canceled
derp client 10.0.1.1:50650[10WOo]: removing connection
```
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
This allows disabling spread mode, which is helpful if you are manually
running derpprobe in `--once` mode against a small number of DERP
machines.
Updates https://github.com/tailscale/corp/issues/9916
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
Xcode changed how/what data it exports to build steps at some point
recently, so our old way of figuring out the minimum support version
for clang stopped working.
Updates tailscale/corp#4095
Signed-off-by: David Anderson <danderson@tailscale.com>
Sometimes, our cached toolchain ends up being an older version of
Go, older than our go.mod allows. In that scenario, gocross-wrapper.sh
would find a usable toolchain, but then fail to compile gocross.
This change makes the wrapper script check that the cached toolchain's
minor version is good enough to build tailscale.com, and re-bootstraps
in shell if not.
Signed-off-by: David Anderson <danderson@tailscale.com>
They're not needed for the sockstats logger, and they're somewhat
expensive to return (since they involve the creation of a map per
label). We now have a separate GetInterfaces() method that returns
them instead (which we can still use in the PeerAPI debug endpoint).
If changing sockstatlog to sample at 10,000 Hz (instead of the default
of 10Hz), the CPU usage would go up to 59% on a iPhone XS. Removing the
per-interface stats drops it to 20% (a no-op implementation of Get that
returns a fixed value is 16%).
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
I thought our versioning scheme would make go.mod include a commit hash
even on stable builds. I was wrong. Fortunately, the rest of this code
wants anything that 'git rev-parse' understands (to convert it into a full
git hash), and tags qualify.
Signed-off-by: David Anderson <danderson@tailscale.com>
tsnet.Server.Close was calling listener.Close with the server mutex
held, but the listener close method tries to grab that mutex, resulting
in a deadlock.
Co-authored-by: David Crawshaw <crawshaw@tailscale.com>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We were not handling tags at all, pass them through as Impersonate-Group headers.
And use the FQDN for tagged nodes as Impersonate-User.
Updates #5055
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We persist the ServeConfig, even for tsnet apps. It's quite possible for
the ServeConfig to be out of step with the code. Example: If you run
`ListenFunnel` then later turn it off, the ServeConfig will still show
it enabled, the admin console will show it enabled, but the packet
handler will reject the packets.
Workaround by clearing the ServeConfig in `tsnet.Up`
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
This lets a tsnet binary share a server out over Tailscale Funnel.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
Followup to #7499 to make validation a separate function (
GetWithValidation vs. Get). This way callers that don't need it don't
pay the cost of a syscall per active TCP socket.
Also clears the conn on close, so that we don't double-count the stats.
Also more consistently uses Go doc comments for the exported API of the
sockstats package.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Though not fine-grained enough to be useful for detailed analysis, we
might as well export that we gather as client metrics too, since we have
an upload/analysis pipeline for them.
clientmetric.Metric.Add is an atomic add, so it's pretty cheap to also
do per-packet.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Previously the part that handled Funnel connections was not
aware of any listeners that tsnet.Servers might have had open
so it would check against the ServeConfig and fail.
Adding a ServeConfig for a TCP proxy was also not suitable in this
scenario as that would mean creating two different listeners and have
one forward to the other, which really meant that you could not have
funnel and tailnet-only listeners on the same port.
This also introduces the ipn.FunnelConn as a way for users to identify
whether the call is coming over funnel or not. Currently it only holds
the underlying conn and the target as presented in the "Tailscale-Ingress-Target"
header.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The addition of WaitGroup.Go in the standard library has been
repeatedly proposed and rejected.
See golang/go#18022, golang/go#23538, and golang/go#39863
In summary, the argument for WaitGroup.Go is that it avoids bugs like:
go func() {
wg.Add(1)
defer wg.Done()
...
}()
where the increment happens after execution (not before)
and also (to a lesser degree) because:
wg.Go(func() {
...
})
is shorter and more readble.
The argument against WaitGroup.Go is that the provided function
takes no arguments and so inputs and outputs must closed over
by the provided function. The most common race bug for goroutines
is that the caller forgot to capture the loop iteration variable,
so this pattern may make it easier to be accidentally racy.
However, that is changing with golang/go#57969.
In my experience the probability of race bugs due to the former
still outwighs the latter, but I have no concrete evidence to prove it.
The existence of errgroup.Group.Go and frequent utility of the method
at least proves that this is a workable pattern and
the possibility of accidental races do not appear to
manifest as frequently as feared.
A reason *not* to use errgroup.Group everywhere is that there are many
situations where it doesn't make sense for the goroutine to return an error
since the error is handled in a different mechanism
(e.g., logged and ignored, formatted and printed to the frontend, etc.).
While you can use errgroup.Group by always returning nil,
the fact that you *can* return nil makes it easy to accidentally return
an error when nothing is checking the return of group.Wait.
This is not a hypothetical problem, but something that has bitten us
in usages that was only using errgroup.Group without intending to use
the error reporting part of it.
Thus, add a (yet another) variant of WaitGroup here that
is identical to sync.WaitGroup, but with an extra method.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
This reverts commit 6eca47b16c and fixes forward.
Previously the first ever streaming MapRequest that a client sent would also
set ReadOnly to true as it didn't have any endpoints and expected/relied on the
map poll to restart as soon as it got endpoints. However with 48f6c1eba4,
we would no longer restart MapRequests as frequently as we used to, so control
would only ever get the first streaming MapRequest which had ReadOnly=true.
Control would treat this as an uninteresting request and would not send it
any further netmaps, while the client would happily stay in the map poll forever
while litemap updates happened in parallel.
This makes it so that we never set `ReadOnly=true` when we are doing a streaming
MapRequest. This is no longer necessary either as most endpoint discovery happens
over disco anyway.
Co-authored-by: Andrew Dunham <andrew@du.nham.ca>
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Add Value, which measures the rate at which an event occurs,
exponentially weighted towards recent activity.
It is guaranteed to occupy O(1) memory, operate in O(1) runtime,
and is safe for concurrent use.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
withSockStats may be called before setLinkMonitor, in which case we
don't have a populated knownInterfaces map. Since we pre-populate the
per-interface counters at creation time, we would end up with an
empty map. To mitigate this, we do an on-demand request for the list of
interfaces.
This would most often happen with the logtail instrumentation, since we
initialize it very early on.
Updates tailscale/corp#9230
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Effectively reverts #249, since the server side was fixed (with #251?)
to send a 200 OK/content-length 0 response.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
We can use the TCP_CONNECTION_INFO getsockopt() on Darwin to get
OS-collected tx/rx bytes for TCP sockets. Since this API is not available
for UDP sockets (or on Linux/Android), we can't rely on it for actual
stats gathering.
However, we can use it to validate the stats that we collect ourselves
using read/write hooks, so that we can be more confident in them. We
do need additional hooks from the Go standard library (added in
tailscale/go#59) to be able to collect them.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Prior to this change, if we were in the middle of a lite map update we'd
tear down the entire map session and restart it. With this change, we'll
cancel an in-flight lite map request up to 10 times and restart before
we tear down the streaming map request. We tear down everything after 10
retries to ensure that a steady stream of calls to sendNewMapRequest
doesn't fail to make progress by repeatedly canceling and restarting.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Change-Id: I9392bf8cf674e7a58ccd1e476039300a359ef3b1
Previously, it would accept all TCP connections and then close the ones
it did not care about. Make it only ever accept the connections that it
cares about.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The main motivation for this change is to stop using the deprecated
set-output function which triggers deprecation warnings in the action.
Change-Id: I80496c44ea1166b9c40d5cd9e450129778ad4aaf
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This package handles cases where we need to truncate human-readable text to fit
a length constraint without leaving "ragged" multi-byte rune fragments at the
end of the truncated value.
Change-Id: Id972135d1880485f41b1fedfb65c2b8cc012d416
Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This change adds a ringbuffer to each magicsock endpoint that keeps a
fixed set of "changes"–debug information about what updates have been
made to that endpoint.
Additionally, this adds a LocalAPI endpoint and associated
"debug peer-status" CLI subcommand to fetch the set of changes for a given
IP or hostname.
Updates tailscale/corp#9364
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I34f726a71bddd0dfa36ec05ebafffb24f6e0516a
I explained this tails/scales list to my 5yo and he looked at me like
it was the most obvious idea ever. Of course we'd make such lists at
work! What else do grown-ups do all day? And then he wouldn't stop
talking about coelacanths and I had no clue what he was saying or how
to spell it until I asked my phone and the phone apparently understood
me and I realized it was a fish and he was helping me? I think?
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add a DNS server which always responds as its own IP addresses.
Additionally add a tsnet TailscaleIPs() function to return the
IP addresses, both IPv4 and IPv6.
Updates https://github.com/tailscale/tailscale/issues/1748
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
The time.Parse function has been optimized to the point
where it is faster than our custom implementation.
See upstream changes in:
* https://go.dev/cl/429862
* https://go.dev/cl/425197
* https://go.dev/cl/425116
Performance:
BenchmarkGoParse3339/Z 38.75 ns/op 0 B/op 0 allocs/op
BenchmarkGoParse3339/TZ 54.02 ns/op 0 B/op 0 allocs/op
BenchmarkParse3339/Z 40.17 ns/op 0 B/op 0 allocs/op
BenchmarkParse3339/TZ 87.06 ns/op 0 B/op 0 allocs/op
We can see that the stdlib implementation is now faster.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Makes it cheaper/simpler to persist values, and encourages reuse of
labels as opposed to generating an arbitrary number.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Despite the fact that WSL configuration is still disabled by default, we
continue to log the machine's list of WSL distros as a diagnostic measure.
Unfortunately I have seen the "wsl.exe -l" command hang indefinitely. This patch
adds a (more than reasonable) 10s timeout to ensure that tailscaled does not get
stuck while executing this operation.
I also modified the Windows implementation of NewOSConfigurator to do the
logging asynchronously, since that information is not required in order to
continue starting up.
Fixes#7476
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Some languages do not give you any useful access to the sockets
underlying their networking packages. E.g. java.net.http.HttpClient
provides no official access to its dialing logic.
...but everyone supports proxies. So add a SOCKS5 proxy on the listener
we are already running.
(The function being revamped is very new,
I only added it in the last week and it wasn't part of any release,
so I believe it is fine to redo its function signature.)
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This prevents a panic where we synthesize a new netmap in
setClientStatus after we've shut down and nil'd out the controlclient,
since that function expects to be called while connected to control.
Fixes#7392
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ib631eb90f34f6afa008d69bbb386f70da145e102
Conforms to RFC 1929.
To support Java HTTP clients via libtailscale, who offer no other
reliable hooks into their sockets.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
No ListenPacket support yet, but Listen with a udp network type fit
easier into netstack's model to start.
Then added an example of using it to cmd/sniproxy with a little udp
:53 handler.
No tests in tsnet yet because we don't have support for dialing over
UDP in tsnet yet. When that's done, a new test can test both sides.
Updates #5871
Updates #1748
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This ensures that any mappings that are created are correctly cleaned
up, instead of waiting for them to expire in the router.
Updates #7377
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I436248ee7740eded6d8adae5df525e785a8f7ccb
Per a packet capture provided, some gateways will reply to a UPnP
discovery packet with a UDP packet with a source port that does not come
from the UPnP port. Accept these packets with a log message.
Updates #7377
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I5d4d5b2a0275009ed60f15c20b484fe2025d094b
We were previously sending a lower-case "udp" protocol, whereas other
implementations like miniupnp send an upper-case "UDP" protocol. For
compatibility, use an upper-case protocol instead.
Updates #7377
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I4aed204f94e4d51b7a256d29917af1536cb1b70f
Some devices don't let you UPnP portmap a port below 1024, so let's just
avoid that range of ports entirely.
Updates #7377
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ib7603b1c9a019162cdc4fa21744a2cae48bb1d86
Return a mock set of interfaces and a mock gateway during this test and
verify that LikelyHomeRouterIP returns the outcome we expect. Also
verify that we return an error if there are no IPv4 addresses available.
Follow-up to #7447
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I8f06989e7f1f0bebd108861cbff17b820ed2e6e4
We have many function pointers that we replace for the duration of test and
restore it on test completion, add method to do that.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We weren't filtering out IPv6 addresses from this function, so we could
be returning an IPv4 gateway IP and an IPv6 self IP. Per the function
comments, only return IPv4 addresses for the self IP.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If19a4aadc343fbd4383fc5290befa0eff006799e
Now that we're using rand.Shuffle in a few locations, create a generic
shuffle function and use it instead. While we're at it, move the
interleaveSlices function to the same package for use.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I0b00920e5b3eea846b6cedc30bd34d978a049fd3
The debug flag on tailscaled isn't available in the macOS App Store
build, since we don't have a tailscaled binary; move it to the
'tailscale debug' CLI that is available on all platforms instead,
accessed over LocalAPI.
Updates #7377
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I47bffe4461e036fab577c2e51e173f4003592ff7
Followup to #7177 to avoid adding extra dependencies to the CLI. We
instead declare an interface for the link monitor.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
WSL has started to set the eth0 default route interface default to 1280
MTU, which is too low to carry 1280 byte packets from tailscale0 once
wrapped in WireGuard. The change down to 1280 is very likely smaller
than necessary for almost all users. We can not easily determine the
ideal MTU, but if all the preconditions match, we raise the MTU to 1360,
which is just enough for Tailscale traffic to work.
Updates #4833
Updates #7346
Signed-off-by: James Tucker <james@tailscale.com>
This is to address a possible DNS failure on startup. Before this
change IPv6 addresses would be listed first, and the client dialer would
fail for hosts without IPv6 connectivity.
This ensures that we're trying multiple returned IPs, since the DERP
servers return the same response to all queries. This should increase
the chances that we eventually reach a working IP.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ie8d4fb93df96da910fae49ae71bf3e402b9fdecc
Update API documentation to include explanation of resources, a cleaner and more consistent structure, updated terminology, and fixes to a few errors and omissions.
Signed-off-by: Julia Stein <julia@tailscale.com>
Signed-off-by: Will Norris <will@tailscale.com>
Co-authored-by: Will Norris <will@tailscale.com>
Share the same underlying implementation for both PrivateID and PublicID.
For the shared methods, declare them in the same order.
Only keep documentation on methods without obvious meaning.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
We had two implemenetations of the kube client, merge them.
containerboot was also using a raw http.Transport, this also has
the side effect of making it use a http.Client
Signed-off-by: Maisem Ali <maisem@tailscale.com>
By default, cmd/dist only prints the output of failed commands.
With this, you can turn all the noisy output back on.
Updates tailscale/corp#9045
Signed-off-by: David Anderson <danderson@tailscale.com>
The helper suppresses output if the command runs successfully. If the
command fails, it dumps the buffered output to stdout before returning
the error. This means the happy path isn't swamped by debug noise or
xcode being intensely verbose about what kind of day it's having,
but you still get debug output when something goes wrong.
Updates tailscale/corp#9045
Signed-off-by: David Anderson <danderson@tailscale.com>
Given recent changes in corp, I originally thought we could remove all of the
syso files, but then I realized that we still need them so that binaries built
purely from OSS (without going through corp) will still receive a manifest.
We can remove the arm32 one though, since we don't support 32-bit ARM on Windows.
Updates https://github.com/tailscale/corp/issues/9576
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
"Device Authorization" was recently renamed to "Device Approval"
on the control side. This change updates the k8s operator to match.
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
"Device Authorization" was recently renamed to "Device Approval"
on the control side. This change updates tsconnect to match.
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Uses the hooks added by tailscale/go#45 to instrument the reads and
writes on the major code paths that do network I/O in the client. The
convention is to use "<package>.<type>:<label>" as the annotation for
the responsible code path.
Enabled on iOS, macOS and Android only, since mobile platforms are the
ones we're most interested in, and we are less sensitive to any
throughput degradation due to the per-I/O callback overhead (macOS is
also enabled for ease of testing during development).
For now just exposed as counters on a /v0/sockstats PeerAPI endpoint.
We also keep track of the current interface so that we can break out
the stats by interface.
Updates tailscale/corp#9230
Updates #3363
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
"Device Authorization" was recently renamed to "Device Approval"
on the control side. This change updates the linux cli to match.
Signed-off-by: Sonia Appasamy <sonia@tailscale.com>
Ever since the introduction of the "must" package,
most MustXXX functions are no longer necessary.
Remove this as it is no longer depended upon
from within this repository and by the internal private repository.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
The log ID types were moved to a separate package so that
code that only depend on log ID types do not need to link
in the logic for the logtail client itself.
Not all code need the logtail client.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
It turns out even with an AuthKey that pre-approves devices on a tailnet
with machine auth turned on, we still temporarily see the
NeedsMachineAuth state. So remove that error (for now).
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This is for use by LocalAPI clients written in other languages that
don't appear to be able to talk HTTP over a socket (e.g.
java.net.http.HttpClient).
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This allows us to differentiate between the various tsnet apps that
we have like `golinks` and `k8s-operator`.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Exposes the delegated interface data added by #7248 in the debug
endpoint. I would have found it useful when working on that PR, and
it may be handy in the future as well.
Also makes the interfaces table slightly easier to parse by adding
borders to it. To make then nicer-looking, the CSP was relaxed to allow
inline styles.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
One might argue they have two, but until that hypothesis can be proven
these tails and scales will have to do!
Signed-off-by: Charlotte Brandhorst-Satzkorn <charlotte@tailscale.com>
Github requires explicitly listing every single job within a workflow
that is required for status checks, instead of letting you list entire
workflows. This is ludicrous, and apparently this nonsense is the
workaround.
Signed-off-by: David Anderson <danderson@tailscale.com>
This makes gocross and its bootstrap script understand an absolute
path in go.toolchain.rev to mean "use the given toolchain directly".
Signed-off-by: David Anderson <danderson@tailscale.com>
We need to build gocross from multiple repos, but Go's innate
git hash embedding only works when you build gocross from this repo,
not when you build it from elsewhere via 'go build
tailscale.com/tool/gocross'. Instead, explicitly embed the version
found with 'git rev-parse HEAD', which will work from any git repo.
Signed-off-by: David Anderson <danderson@tailscale.com>
This avoids accidentally overwriting variables from the input
environment, which might non-deterministically change the behavior
of gocross.
Signed-off-by: David Anderson <danderson@tailscale.com>
Turns out directing the printed script into the bootstrap location leads
to irritating "text file busy" problems and then having to muck about with
tempfiles and chmod and all that. Instead, have gocross write everything
with the right values.
Signed-off-by: David Anderson <danderson@tailscale.com>
So that when importing and using gocross from other repos, there's
an easy way to get at the right wrapper script that's in sync with
the gocross binary.
Signed-off-by: David Anderson <danderson@tailscale.com>
trimmed builds don't have absolute path information in executable
metadata, which leads the runtime.Caller approach failing
mysteriously in yarn with complaints about relative package paths.
So, instead of using embedded package metadata to find paths,
expect that we're being invoked within the tailscale repo, and
locate the tsconnect directory that way.
Signed-off-by: David Anderson <danderson@tailscale.com>
These RPCs will be used to power the future 'tailscale lock remove' default behavior
of resigning signatures for which trust is about to be removed.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Also add some basic tests for this implementation.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I307ebb6db91d0c172657befb276b38ccb638f828
armv5 because that's what we ship to most downstreams right now,
armv7 becuase that's what we want to ship more of.
Fixes https://github.com/tailscale/tailscale/issues/7269
Signed-off-by: David Anderson <danderson@tailscale.com>
CI status doesn't collapse into "everything OK" if a job gets
skipped. Instead, always run the job, but skip its only step in PRs.
Signed-off-by: David Anderson <danderson@tailscale.com>
Replaces the former shell goop, which was a shell reimplementation
of a subset of version/mkversion.
Signed-off-by: David Anderson <danderson@tailscale.com>
With this change, you can collect version info from either a git
checkout of the tailscale.com Go module (this repo), or a git
checkout of a repo that imports the tailscale.com Go module.
Signed-off-by: David Anderson <danderson@tailscale.com>
No particular reason. Just good point of our release cycle for some #cleanup.
It also makes dependabot happy about something we're not using?
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This ensures that we put the kubeconfig in the correct directory from within the macOS Sandbox when
paired with tailscale/corp@3035ef7
Updates #7220
Signed-off-by: Maisem Ali <maisem@tailscale.com>
This isn't currently supported due to missing support in upstream
dependencies, and also we don't use this package anywhere right now.
Just conditionally skip this for now.
Fixes#7268
Change-Id: Ie7389c2c0816b39b410c02a7276051a4c18b6450
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
So that I just get a quick PR to approve and merge instead of
periodically discovering that the SRI hash has bitrotted.
Signed-off-by: David Anderson <danderson@tailscale.com>
OSS-Fuzz doesn't update their version of Go as quickly as we do, so
we sometimes end up with OSS-Fuzz being unable to build our code for
a few weeks. We don't want CI to be red for that entire time, but
we also don't want to forget to reenable fuzzing when OSS-Fuzz does
start working again.
This change makes two configurations worthy of a CI pass:
- Fuzzing works, and we expected it to work. This is a normal
happy state.
- Fuzzing didn't compile, and we expected it to not compile. This
is the "OSS-Fuzz temporarily broken" state.
If fuzzing is unexpectedly broken, or unexpectedly not broken, that's
a CI failure because we need to either address a fuzz finding, or
update TS_FUZZ_CURRENTLY_BROKEN to reflect the state of OSS-Fuzz.
Signed-off-by: David Anderson <danderson@tailscale.com>
Github's matrix runner formats the race variant as '(amd64, true)' if we
use race=true. So, change the way the variable is defined so that it says
'(amd64, race)' even if that makes the if statements a bit more complex.
Signed-off-by: David Anderson <danderson@tailscale.com>
Instead of having a dozen files that contribute CI steps with
inconsistent configs, this one file lists out everything that,
for us, constitutes "a CI run". It also enables the slack
notification webhook to notify us exactly once on a mass breakage,
rather than once for every sub-job that fails.
Signed-off-by: David Anderson <danderson@tailscale.com>
The use of GOOS to mean "the compiler's host architecture" ends up
overriding whatever GOOS the user passed in, resulting in befuddling
errors like "unsupported GOOS/GOARCH pair linux/wasm" when the caller
requests js/wasm.
Signed-off-by: David Anderson <danderson@tailscale.com>
We've never used the "[ci skip]" magic commit header in our history,
across all our repos. This seems to be boilerplate we imported years
ago and have since been copying around our CI configs.
Signed-off-by: David Anderson <danderson@tailscale.com>
In the switch to static toolchains, we removed a legacy oddity from the
toolchain URL structure, but forgot to update printdep.
Signed-off-by: David Anderson <danderson@tailscale.com>
Before (note attempted use of absent date and commit hash):
"short": "1.37.0-dev",
"long": "1.37.0-dev-t",
After:
"short": "1.37.0-ERR-BuildInfo",
"long": "1.37.0-ERR-BuildInfo",
Signed-off-by: David Anderson <danderson@tailscale.com>
Co-authored-by: Maisem Ali <maisem@tailscale.com>
Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: David Anderson <danderson@tailscale.com>
With #6566 we added an external mechanism for getting the default
interface, and used it on macOS and iOS (see tailscale/corp#8201).
The goal was to be able to get the default physical interface even when
using an exit node (in which case the routing table would say that the
Tailscale utun* interface is the default).
However, the external mechanism turns out to be unreliable in some
cases, e.g. when multiple cellular interfaces are present/toggled (I
have occasionally gotten my phone into a state where it reports the pdp_ip1
interface as the default, even though it can't actually route traffic).
It was observed that `ifconfig -v` on macOS reports an "effective interface"
for the Tailscale utn* interface, which seems promising. By examining
the ifconfig source code, it turns out that this is done via a
SIOCGIFDELEGATE ioctl syscall. Though this is a private API, it appears
to have been around for a long time (e.g. it's in the 10.13 xnu release
at https://opensource.apple.com/source/xnu/xnu-4570.41.2/bsd/net/if_types.h.auto.html)
and thus is unlikely to go away.
We can thus use this ioctl if the routing table says that a utun*
interface is the default, and go back to the simpler mechanism that
we had before #6566.
Updates #7184
Updates #7188
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
As part of the work on #7248 I wanted to know all of the flags on the
RouteMessage struct that we get back from macOS. Though it doesn't turn
out to be useful (when using an exit node/Tailscale is the default route,
the flags for the physical interface routes are the same), it still seems
useful from a debugging/comprehensiveness perspective.
Adds additional Darwin flags that were output once I enabled this mode.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Followup to #7235, we were not treating the formatting arguments as
variadic. This worked OK for single values, but stopped working when
we started passing multiple values (noticed while trying out #7244).
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Commit 59c254579e moved a lot of work
from functions that could be eliminated at compile time (because
tests against runtime.GOOS are compile-time constant), into code
that must always run before main().
So, revert that, and instead optimize the package only by moving the
remaining string processing code behind sync.Onces.
Signed-off-by: David Anderson <danderson@tailscale.com>
Useful when debugging issues (e.g. to see the full routing table), and
easier to refer to the output via a browser than trying to read it from
the logs generated by `bugreport --diagnose`.
Behind a canDebug() check, similar to the /magicsock and /interfaces
endpoints.
Updates #7184
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
For tailscale/go#55 experimentation in another repo primarily,
but this is our source of truth, so we bump here.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We no longer carry an SRI hash for the toolchain, so flake
updating is no longer needed for toolchain changes.
Signed-off-by: David Anderson <danderson@tailscale.com>
This package is an initial implementation of something that can read
netfilter and iptables rules from the Linux kernel without needing to
shell out to an external utility; it speaks directly to the kernel using
syscalls and parses the data returned.
Currently this is read-only since it only knows how to parse a subset of
the available data.
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
Change-Id: Iccadf5dcc081b73268d8ccf8884c24eb6a6f1ff5
Tailnet-owned auth keys (which all OAuth-created keys are) must include tags, since there is no user to own the registered devices.
Signed-off-by: Will Norris <will@tailscale.com>
Having an empty `on` spec results in the job still running, but it
immediately fails with a "No jobs were run" message.
Go back to the original `on: [pull_request]` spec, and disable the
workflow in the GitHub UI instead.
This reverts commit f7b3156f16.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
With #6566 we started to more aggressively bind to the default interface
on Darwin. We are seeing some reports of the wrong cellular interface
being chosen on iOS. To help with the investigation, this adds to knobs
to control the behavior changes:
- CapabilityDebugDisableAlternateDefaultRouteInterface disables the
alternate function that we use to get the default interface on macOS
and iOS (implemented in tailscale/corp#8201). We still log what it
would have returned so we can see if it gets things wrong.
- CapabilityDebugDisableBindConnToInterface is a bigger hammer that
disables binding of connections to the default interface altogether.
Updates #7184
Updates #7188
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
We don't require any cert at all for Noise-over-plaintext-port-80-HTTP,
so why require a valid cert chain for Noise-over-HTTPS? The reason we use
HTTPS at all is to get through firewalls that allow tcp/443 but not tcp/80,
not because we need the security properties of TLS.
Updates #3198
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We stopped writing network lock keys as separate items with #6315,
the constant is no longer used.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
The 255 byte limit was chosen more than 3 years ago (tailscale/corp@929635c9d9),
when iOS was operating under much more significant memory constraints.
With iOS 15 the network extension has an increased limit, so increasing
it to 4K should be fine.
The motivating factor was that the network interfaces being logged
by linkChange in wgengine/userspace.go were getting truncated, and it
would be useful to know why in some cases we're choosing the pdp_ip1
cell interface instead of the pdp_ip0 one.
Updates #7184
Updates #7188
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Previously, we only printed these at startup; print those when the user
generates a bugreport as we so we don't have to go spelunking through
the logs.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If5b0970f09fcb4cf8839958af5d37f84e0ba6ed2
The profileManager was using the LoginName as a proxy to figure out if the profile
had logged in, however the LoginName is not present if the node was created with an
Auth Key that does not have an associated user.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
We now handle the case where the NetworkMap.SelfNode has already expired
and do not return an expiry time in the past (which causes an ~infinite
loop of timers to fire).
Additionally, we now add an explicit check to ensure that the next
expiry time is never before the current local-to-the-system time, to
ensure that we don't end up in a similar situation due to clock skew.
Finally, we add more tests for this logic to ensure that we don't
regress on these edge cases.
Fixes#7193
Change-Id: Iaf8e3d83be1d133a7aab7f8d62939e508cc53f9c
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
It was originally added to control memory use on iOS (#2490), but then
was relaxed conditionally when running on iOS 15 (#3098). Now that we
require iOS 15, there's no need for the limit at all, so simplify back
to the original state.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
GetProxyConnectHeader (golang/go#41048) was upstreamed in Go 1.16 and
OnProxyConnectResponse (golang/go#54299) in Go 1.20, thus we no longer
need to guard their use by the tailscale_go build tag.
Updates #7123
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Add the envknob TS_DEBUG_EXIT_NODE_DNS_NET_PKG, which enables more
verbose debug logging when calling the handleExitNodeDNSQueryWithNetPkg
function. This function is currently only called on Windows and Android.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ieb3ca7b98837d7dc69cd9ca47609c1c52e3afd7b
Having this information near the "user bugreport" line makes it easier
to identify the node and expiry without spelunking through the rest of
the logs.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I1597c783efc06574fa4c8f211e68d835f20b6ccb
Also removes the toolchain builds from flake.nix. For now the flake
build uses upstream Go 1.20, a followup change will switch it back to
our custom toolchain.
Updates tailscale/corp#9005
Signed-off-by: David Anderson <danderson@tailscale.com>
Now that Go 1.20 is released, multierr.Error can implement
Unwrap() []error
Updates #7123
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ic28c2579de6799801836c447afbca8cdcba732cf
If the user passes the --diagnose flag, print a warning if any of the
default or fallback DNS resolvers are Tailscale IPs. This can interfere
with the ability to connect to the controlplane, and is typically
something to pay attention to if there's a connectivity issue.
Change-Id: Ib14bf6228c037877fbdcd22b069212b1a4b2c456
Signed-off-by: Andrew Dunham <andrew@tailscale.com>
When we make a connection to a server, we previously would verify with
the system roots, and then fall back to verifying with our baked-in
Let's Encrypt root if the system root cert verification failed.
We now explicitly check for, and log a health error on, self-signed
certificates. Additionally, we now always verify against our baked-in
Let's Encrypt root certificate and log an error if that isn't
successful. We don't consider this a health failure, since if we ever
change our server certificate issuer in the future older non-updated
versions of Tailscale will no longer be healthy despite being able to
connect.
Updates #3198
Change-Id: I00be5ceb8afee544ee795e3c7a2815476abc4abf
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
To aid in debugging where a customer has static port-forwards set up and
there are issues establishing a connection through that port.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ic5558bcdb40c9119b83f79dcacf2233b07777f2a
Updates #7123
Updates #6257 (more to do in other repos)
Change-Id: I073e2a6d81a5d7fbecc29caddb7e057ff65239d0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It doesn't yet support Go 1.20. We can bring it back later.
Updates #7123
Change-Id: I6c4a4090e910d06f34c3f4d612e737989fe85812
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
It's since been rewritten in Swift.
#cleanup
Change-Id: I0860d681e8728697804ce565f63c5613b8b1088c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Bleeding edge Tailscale Nix flake broke after updating to go1.20rc3.
Go 1.20 moved to Go 1.17 as a bootstarp toolchain. Fortunately nixpkgs
nixos-unstable already had a 1.20.nix with bootstrap117.nix.
```
❯ ./result/bin/tailscale version
1.37.0-dev
track: unstable (dev); frequent updates and bugs are likely
go version: go1.20rc3-ts6a17f14c05
```
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
It includes xtermjs/xterm.js#4216, which improves handling of some
escape sequences. Unfortunately it's not enough to fix the issue
with `ponysay`, but it does not hurt to be up to date.
Updates #6090
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
We can log too quickly for logtail to catch up, even when we opt out of
log rate-limiting. When the user passes the --diagnose flag to
bugreport, we use a token bucket to control how many logs per second are
printed and sleep until we're able to write more.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: If27672d66b621b589280bd0fe228de367ffcbd8f
`prober.DERP` was created in #5988 based on derpprobe. Having used it
instead of derpprobe for a few months, I think we have enough confidence
that it works and can now migrate derpprobe to use the prober framework
and get rid of code duplication.
A few notable changes in behaviour:
- results of STUN probes over IPv4 and IPv6 are now reported separately;
- TLS probing now includes OCSP verification;
- probe names in the output have changed;
- ability to send Slack notification from the prober has been removed.
Instead, the prober now exports metrics in Expvar (/debug/vars) and
Prometheus (/debug/varz) formats.
Fixes https://github.com/tailscale/corp/issues/8497
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
There's an error in the `Perform CodeQL Analysis` step saying to upgrade to v2 as v1 was deprecated on 18th January.
Signed-off-by: Nick Kirby <nrkirb@gmail.com>
Makes the Wasm client more similar to the others, and allows the default
profile to be correctly picked up when restarting the client in dev
mode (where we persist the state in sessionStorage).
Also update README to reflect that Go wasm changes can be picked up
with just a reload (as of #5383)
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
There is no stable release yet, and for alpha we want people on the
unstable build while we iterate.
Updates #502
Signed-off-by: David Anderson <danderson@tailscale.com>
The iOS has a command to reset the persisted state of the app, but it
was doing its own direct keychain manipulation. This proved to be
brittle (since we changed how preferences are stored with #6022), so
we instead add a LocalAPI endpoint to do do this, which can be updated
in tandem.
This clears the same state as the iOS implementation (tailscale/corp#3186),
that is the machine key and preferences (which includes the node key).
Notably this does not clear the logtail ID, so that logs from the device
still end up in the same place.
Updates tailscale/corp#8923
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Update all code generation tools, and those that check for license
headers to use the new standard header.
Also update copyright statement in LICENSE file.
Fixes#6865
Signed-off-by: Will Norris <will@tailscale.com>
This updates all source files to use a new standard header for copyright
and license declaration. Notably, copyright no longer includes a date,
and we now use the standard SPDX-License-Identifier header.
This commit was done almost entirely mechanically with perl, and then
some minimal manual fixes.
Updates #6865
Signed-off-by: Will Norris <will@tailscale.com>
Follow-up to #7065 with some comments from Brad's review.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ia1219f4fa25479b2dada38ffe421065b408c5954
The API documentation does claim to output empty strings under certain
conditions, but we're sometimes seeing nil pointers in the wild, not empty
strings.
Fixes https://github.com/tailscale/corp/issues/8878
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
When turned on via environment variable (off by default), this will use
the BSD routing APIs to query what interface index a socket should be
bound to, rather than binding to the default interface in all cases.
Updates #5719
Updates #5940
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ib4c919471f377b7a08cd3413f8e8caacb29fee0b
Running sync-containers in a GitHub workflow will be
simpler if we check github.Keychain, which uses the
GITHUB_TOKEN if present.
Updates https://github.com/tailscale/corp/issues/8461
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
You can now install Tailscale on Windows via [Scoop](https://scoop.sh).
This change adds a check to `packageTypeWindows()`, looking at the exe's path, and
checking if it starts with: `C:\User\<NAME>\scoop\apps\tailscale`. If so, it
returns `"scoop"` as the package type.
Fixes: #6988
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
This allows users to temporarily enable/disable dnscache logging via a
new node capability, to aid in debugging strange connectivity issues.
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I46cf2596a8ae4c1913880a78d0033f8b668edc08
The dependency injection functionality has been deprecated a while back
and it'll be removed in the 0.15 release of Controller Runtime. This
changeset sets the Client after creating the Manager, instead of using
InjectClient.
Signed-off-by: Vince Prignano <vince@prigna.com>
This will ensure that the `tailscale-archive-keyring` Debian package
gets installed by the installer script.
Updates #3151
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
The current node isn't in NetMap.Peers, so without this we would not
have fired this timer on self expiry.
Updates #6932
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Id57f96985397e372f9226802d63b42ff92c95093
For detecting a non-ideal binary running on the current CPU.
And for helping detect the best Synology package to update to.
Updates #6995
Change-Id: I722f806675b60ce95364471b11c388150c0d4aea
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Per recent user confusion on a QNAP issue.
Change-Id: Ibda00013df793fb831f4088b40be8a04dfad17c2
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Add `tailscale version --json` JSON output mode. This will be used
later for a double-opt-in (per node consent like Tailscale SSH +
control config) to let admins do remote upgrades via `tailscale
update` via a c2n call, which would then need to verify the
cmd/tailscale found on disk for running tailscale update corresponds
to the running tailscaled, refusing if anything looks amiss.
Plus JSON output modes are just nice to have, rather than parsing
unstable/fragile/obscure text formats.
Updates #6995
Updates #6907
Change-Id: I7821ab7fbea4612f4b9b7bdc1be1ad1095aca71b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
On macOS (AppStore and macsys), we need to bind to ""/all-interfaces
due to the network sandbox. Ideally we would only bind to the
Tailscale interface, but macOS errors out if we try to
to listen on privileged ports binding only to a specific
interface.
We also implement the lc.Control hook, same as we do for
peerapi. It doesn't solve our problem but it's better that
we do and would likely be required when Apple gets around to
fixing per-interface priviliged port binding.
Fixes: #6364
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
They changed a type in their SDK which meant others using the AWS APIs
in their Go programs (with newer AWS modules in their caller go.mod)
and then depending on Tailscale (for e.g. tsnet) then couldn't compile
ipn/store/awsstore.
Thanks to @thisisaaronland for bringing this up.
Fixes#7019
Change-Id: I8d2919183dabd6045a96120bb52940a9bb27193b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Create an interface and mock implementation of tailscale.LocalClient for
serve command tests.
Updates #6304Closes#6372
Signed-off-by: Shayne Sweeney <shayne@tailscale.com>
The single packet WriteTo() through RebindingUDPConn.WriteBatch() was
not checking for a rebind between loading the PacketConn and writing to
it. Same with ReadFrom()/ReadBatch().
Fixes#6989
Signed-off-by: Jordan Whited <jordan@tailscale.com>
When you hit control-C on a tailscaled (notably in dev mode, but
also on any systemctl stop/restart), there is a flood of messages like:
magicsock: doing cleanup for discovery key d:aa9c92321db0807f
magicsock: doing cleanup for discovery key d:bb0f16aacadbfd46
magicsock: doing cleanup for discovery key d:b5b2d386296536f2
magicsock: doing cleanup for discovery key d:3b640649f6796c91
magicsock: doing cleanup for discovery key d:71d7b1afbcce52cd
magicsock: doing cleanup for discovery key d:315b61d7e0111377
magicsock: doing cleanup for discovery key d:9301f63dce69bf45
magicsock: doing cleanup for discovery key d:376141884d6fe072
....
It can be hundreds or even tens of thousands.
So don't do that. Not a useful log message during shutdown.
Change-Id: I029a8510741023f740877df28adff778246c18e5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
I typoed/brainoed in the earlier 3582628691
Change-Id: Ic198a6f9911f195d9da9fc5259b5784a4b15e5e3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This change delays the first flush in the /watch-ipn-bus/ handler
until after the watcher has been successfully installed on the IPN
bus. It does this by adding a new onWatchAdded callback to
LocalBackend.WatchNotifications().
Without this, the endpoint returns a 200 almost immediatly, and
only then installs a watcher for IPN events. This means there's a
small window where events could be missed by clients after calling
WatchIPNBus().
Fixestailscale/corp#8594.
Signed-off-by: salman <salman@tailscale.com>
In order to be able to synthesize a new NetMap when a node expires, have
LocalBackend start a timer when receiving a new NetMap that fires
slightly after the next node expires. Additionally, move the logic that
updates expired nodes into LocalBackend so it runs on every netmap
(whether received from controlclient or self-triggered).
Updates #6932
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: I833390e16ad188983eac29eb34cc7574f555f2f3
01b90df2fa added SCTP support before
(with explicit parsing for ports) and
69de3bf7bf tried to add support for
arbitrary IP protocols (as long as the ACL permited a port of "*",
since we might not know how to find ports from an arbitrary IP
protocol, if it even has such a concept). But apparently that latter
commit wasn't tested end-to-end enough. It had a lot of tests, but the
tests made assumptions about layering that either weren't true, or
regressed since 1.20. Notably, it didn't remove the (*Filter).pre
bidirectional filter that dropped all "unknown" protocol packets both
leaving and entering, even if there were explicit protocol matches
allowing them in.
Also, don't map all unknown protocols to 0. Keep their IP protocol
number parsed so it's matchable by later layers. Only reject illegal
things.
Fixes#6423
Updates #2162
Updates #2163
Change-Id: I9659b3ece86f4db51d644f9b34df78821758842c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Goal: one way for users to update Tailscale, downgrade, switch tracks,
regardless of platform (Windows, most Linux distros, macOS, Synology).
This is a start.
Updates #755, etc
Change-Id: I23466da1ba41b45f0029ca79a17f5796c2eedd92
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Needed for clients that get information via the /v0/status LocalAPI
endpoint (e.g. to not offer expired exit nodes as options).
Updates tailscale/corp#8702
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
UI works remains, but data is there now.
Updates #4015
Change-Id: Ib91e94718b655ad60a63596e59468f3b3b102306
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The -terminate-tls flag is for the tcp subsubcommand, not the serve
subcommand like the usage example suggests.
Signed-off-by: salman <salman@tailscale.com>
Gateway devices operating as an HA pair w/VRRP or CARP may send UPnP
replies from static addresses rather than the floating gateway address.
This commit relaxes our source address verification such that we parse
responses from non-gateway IPs, and re-point the UPnP root desc
URL to the gateway IP. This ensures we are still interfacing with the
gateway device (assuming L2 security intact), even though we got a
root desc from a non-gateway address.
This relaxed handling is required for ANY port mapping to work on certain
OPNsense/pfsense distributions using CARP at the time of writing, as
miniupnpd may only listen on the static, non-gateway interface address
for PCP and PMP.
Fixes#5502
Signed-off-by: Jordan Whited <jordan@tailscale.com>
This is based on the tagsEqual func from corp/control/control.go, moved
here so that it can be reused in other places.
Signed-off-by: Will Norris <will@tailscale.com>
Nodes that are expired, taking into account the time delta calculated
from MapResponse.ControlTime have the newly-added Expired boolean set.
For additional defense-in-depth, also replicate what control does and
clear the Endpoints and DERP fields, and additionally set the node key
to a bogus value.
Updates #6932
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
Change-Id: Ia2bd6b56064416feee28aef5699ca7090940662a
QNAP's "Force HTTPS" mode redirects even localhost HTTP to
HTTPS, but uses a self-signed certificate which fails
verification. We accommodate this by disabling checking
of the cert.
Fixes https://github.com/tailscale/tailscale/issues/6903
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
Unsigned peers should not be allowed to generate Wake-on-Lan packets,
only access Funnel.
Updates #6934
Updates #7515
Updates #6475
Signed-off-by: James Tucker <james@tailscale.com>
I don't think CVE-2022-41717 necessarily impacts us (maybe as part of
funnel?), but it came up in a recent security scan so worth updating
anyway.
Signed-off-by: Will Norris <will@tailscale.com>
3 years ago
2509 changed files with 398170 additions and 49098 deletions
- name:Verify that static manifests are up to date
run:|
make kube-generate-all
echo
echo
git diff --name-only --exit-code || (echo "Generated files for Tailscale Kubernetes operator are out of date. Please run 'make kube-generate-all' and commit the diff."; exit 1)
We as members, contributors, and leaders pledge to make participation
in our community a harassment-free experience for everyone, regardless
of age, body size, visible or invisible disability, ethnicity, sex
characteristics, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open,
welcoming, diverse, inclusive, and healthy community.
We are committed to creating an open, welcoming, diverse, inclusive, healthy and respectful community.
Unacceptable, harmful and inappropriate behavior will not be tolerated.
## Our Standards
Examples of behavior that contributes to a positive environment for
our community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our
mistakes, and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
Examples of behavior that contributes to a positive environment for our community include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or
political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in
a professional setting
- Demonstrating empathy and kindness toward other people.
- Being respectful of differing opinions, viewpoints, and experiences.
- Giving and gracefully accepting constructive feedback.
- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience.
- Focusing on what is best not just for us as individuals, but for the overall community.
## Enforcement Responsibilities
Examples of unacceptable behavior include without limitation:
Community leaders are responsible for clarifying and enforcing our
standards of acceptable behavior and will take appropriate and fair
corrective action in response to any behavior that they deem
inappropriate, threatening, offensive, or harmful.
- The use of language, imagery or emojis (collectively "content") that is racist, sexist, homophobic, transphobic, or otherwise harassing or discriminatory based on any protected characteristic.
- The use of sexualized content and sexual attention or advances of any kind.
- The use of violent, intimidating or bullying content.
- Trolling, concern trolling, insulting or derogatory comments, and personal or political attacks.
- Public or private harassment.
- Publishing others' personal information, such as a photo, physical address, email address, online profile information, or other personal information, without their explicit permission or with the intent to bully or harass the other person.
- Posting deep fake or other AI generated content about or involving another person without the explicit permission.
- Spamming community channels and members, such as sending repeat messages, low-effort content, or automated messages.
- Phishing or any similar activity.
- Distributing or promoting malware.
- The use of any coded or suggestive content to hide or provoke otherwise unacceptable behavior.
- Other conduct which could reasonably be considered harmful, illegal, or inappropriate in a professional setting.
Community leaders have the right and responsibility to remove, edit,
or reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, and will
communicate reasons for moderation decisions when appropriate.
Please also see the Tailscale Acceptable Use Policy, available at [tailscale.com/tailscale-aup](https://tailscale.com/tailscale-aup).
## Scope
## Reporting Incidents
This Code of Conduct applies within all community spaces, and also
applies when an individual is officially representing the community in
public spaces. Examples of representing our community include using an
official e-mail address, posting via an official social media account,
or acting as an appointed representative at an online or offline
event.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to Tailscale directly via <info@tailscale.com>, or to the community leaders or moderators via DM or similar.
All complaints will be reviewed and investigated promptly and fairly.
We will respect the privacy and safety of the reporter of any issues.
## Enforcement
Please note that this community is not moderated by staff 24/7, and we do not have, and do not undertake, any obligation to prescreen, monitor, edit, or remove any content or data, or to actively seek facts or circumstances indicating illegal activity.
While we strive to keep the community safe and welcoming, moderation may not be immediate at all hours.
If you encounter any issues, report them using the appropriate channels.
Instances of abusive, harassing, or otherwise unacceptable behavior
may be reported to the community leaders responsible for enforcement
at [info@tailscale.com](mailto:info@tailscale.com). All complaints
will be reviewed and investigated promptly and fairly.
## Enforcement Guidelines
All community leaders are obligated to respect the privacy and
security of the reporter of any incident.
Community leaders and moderators are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
## Enforcement Guidelines
Community leaders and moderators have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Community Code of Conduct.
Tailscale retains full discretion to take action (or not) in response to a violation of these guidelines with or without notice or liability to you.
We will interpret our policies and resolve disputes in favor of protecting users, customers, the public, our community and our company, as a whole.
Community leaders will follow these Community Impact Guidelines in
determining the consequences for any action they deem in violation of
this Code of Conduct:
Community leaders will follow these community enforcement guidelines in determining the consequences for any action they deem in violation of this Code of Conduct,
and retain full discretion to apply the enforcement guidelines as necessary depending on the circumstances:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior
deemed unprofessional or unwelcome in the community.
Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders,
providing clarity around the nature of the violation and an
explanation of why the behavior was inappropriate. A public apology
may be requested.
Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate.
A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
Community Impact: A violation through a single incident or series of actions.
**Consequence**: A warning with consequences for continued
behavior. No interaction with the people involved, including
unsolicited interaction with those enforcing the Code of Conduct, for
a specified period of time. This includes avoiding interactions in
community spaces as well as external channels like social
media. Violating these terms may lead to a temporary or permanent ban.
Consequence: A warning with consequences for continued behavior.
No interaction with the people involved, including unsolicited interaction with those enforcing this Community Code of Conduct, for a specified period of time.
This includes avoiding interactions in community spaces as well as external channels like social media.
Violating these terms may lead to a temporary or permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards,
including sustained inappropriate behavior.
Community Impact: A serious violation of community standards, including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or
public communication with the community for a specified period of
time. No public or private interaction with the people involved,
including unsolicited interaction with those enforcing the Code of
Conduct, is allowed during this period. Violating these terms may lead
to a permanent ban.
Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time.
No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of
community standards, including sustained inappropriate behavior,
harassment of an individual, or aggression toward or disparagement of
classes of individuals.
Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction
within the community.
Consequence: A permanent ban from any sort of public interaction within the community.
## Acceptable Use Policy
Violation of this Community Code of Conduct may also violate the Tailscale Acceptable Use Policy, which may result in suspension or termination of your Tailscale account.
For more information, please see the Tailscale Acceptable Use Policy, available at [tailscale.com/tailscale-aup](https://tailscale.com/tailscale-aup).
## Privacy
Please see the Tailscale [Privacy Policy](https://tailscale.com/privacy-policy) for more information about how Tailscale collects, uses, discloses and protects information.
## Attribution
This Code of Conduct is adapted from the [Contributor
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at <https://www.contributor-covenant.org/version/2/0/code_of_conduct.html>.
Community Impact Guidelines were inspired by [Mozilla's code of
assert("a has fewer",routesWithout(prefixes("1.1.1.1/32","1.1.1.2/32"),prefixes("1.1.1.1/32","1.1.1.2/32","1.1.1.3/32","1.1.1.4/32")),[]netip.Prefix{})
assert("a has more",routesWithout(prefixes("1.1.1.1/32","1.1.1.2/32","1.1.1.3/32","1.1.1.4/32"),prefixes("1.1.1.1/32","1.1.1.3/32")),prefixes("1.1.1.2/32","1.1.1.4/32"))
panic("binary built with tailscale_go build tag but failed to read build info or find tailscale.toolchain.rev in build info")
}
want:=strings.TrimSpace(GoToolchainRev)
iftsRev!=want{
ifos.Getenv("TS_PERMIT_TOOLCHAIN_MISMATCH")=="1"{
fmt.Fprintf(os.Stderr,"tailscale.toolchain.rev = %q, want %q; but ignoring due to TS_PERMIT_TOOLCHAIN_MISMATCH=1\n",tsRev,want)
return
}
panic(fmt.Sprintf("binary built with tailscale_go build tag but Go toolchain %q doesn't match github.com/tailscale/tailscale expected value %q; override this failure with TS_PERMIT_TOOLCHAIN_MISMATCH=1",tsRev,want))
// GNOME expands submenus downward in the main menu, rather than flyouts to the side.
// Either as a result of that or another limitation, there seems to be a maximum depth of submenus.
// Mullvad countries that have a city submenu are not being rendered, and so can't be selected.
// Handle this by simply treating all mullvad countries as single-city and select the best peer.
hideMullvadCities=true
case"kde":
// KDE doesn't need a delay, and actually won't render submenus
// if we delay for more than about 400µs.
newMenuDelay=0
default:
// Add a slight delay to ensure the menu is created before adding items.
//
// Systray implementations that use libdbusmenu sometimes process messages out of order,
// resulting in errors such as:
// (waybar:153009): LIBDBUSMENU-GTK-WARNING **: 18:07:11.551: Children but no menu, someone's been naughty with their 'children-display' property: 'submenu'
//
// See also: https://github.com/fyne-io/systray/issues/12
newMenuDelay=10*time.Millisecond
}
}
// onReady is called by the systray package when the menu is ready to be built.