WinTun is installed lazily by tailscaled while it is running as LocalSystem.
Based upon what we're seeing in bug reports and support requests, removing
WinTun as a lesser user may fail under certain Windows versions, even when that
user is an Administrator.
By adding a user-defined command code to tailscaled, we can ask the service to
do the removal on our behalf while it is still running as LocalSystem.
* The uninstall code is basically the same as it is in corp;
* The command code will be sent as a service control request and is protected by
the SERVICE_USER_DEFINED_CONTROL access right, which requires Administrator.
I'll be adding follow-up patches in corp to engage this functionality.
Updates https://github.com/tailscale/tailscale/issues/6433
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
tailscaled on Windows had two entirely separate start-up paths for running
as a service vs in the foreground. It's been causing problems for ages.
This unifies the two paths, making them be the same as the path used
for every other platform.
Also, it uses the new async LocalBackend support in ipnserver.Server
so the Server can start serving HTTP immediately, even if tun takes
awhile to come up.
Updates #6535
Change-Id: Icc8c4f96d4887b54a024d7ac15ad11096b5a58cf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This is step 1 of de-special-casing of Windows and letting the
LocalAPI HTTP server start serving immediately, even while the rest of
the world (notably the Engine and its TUN device) are being created,
which can take a few to dozens of seconds on Windows.
With this change, the ipnserver.New function changes to not take an
Engine and to return immediately, not returning an error, and let its
Run run immediately. If its ServeHTTP is called when it doesn't yet
have a LocalBackend, it returns an error. A TODO in there shows where
a future handler will serve status before an engine is available.
Future changes will:
* delete a bunch of tailscaled_windows.go code and use this new API
* add the ipnserver.Server ServerHTTP handler to await the engine
being available
* use that handler in the Windows GUI client
Updates #6522
Change-Id: Iae94e68c235e850b112a72ea24ad0e0959b568ee
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This patch removes the crappy, half-backed COM initialization used by `go-ole`
and replaces that with the `StartRuntime` function from `wingoes`, a library I
have started which, among other things, initializes COM properly.
In particular, we should always be initializing COM to use the multithreaded
apartment. Every single OS thread in the process becomes implicitly initialized
as part of the MTA, so we do not need to concern ourselves as to whether or not
any particular OS thread has initialized COM. Furthermore, we no longer need to
lock the OS thread when calling methods on COM interfaces.
Single-threaded apartments are designed solely for working with Win32 threads
that have a message pump; any other use of the STA is invalid.
Fixes https://github.com/tailscale/tailscale/issues/3137
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Centralize the fake GOOS stuff, start to use it more. To be used more
in the future.
Change-Id: Iabacfbeaf5fca0b53bf4d5dbcdc0367f05a205f9
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The //go:build syntax was introduced in Go 1.17:
https://go.dev/doc/go1.17#build-lines
gofmt has kept the +build and go:build lines in sync since
then, but enough time has passed. Time to remove them.
Done with:
perl -i -npe 's,^// \+build.*\n,,' $(git grep -l -F '+build')
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This doesn't change any behaviour for now, other than maybe running a
full netcheck more often. The intent is to start gathering data on
captive portals, and additionally, seeing this in the 'tailscale
netcheck' command should provide a bit of additional information to
users.
Updates #1634
Change-Id: I6ba08f9c584dc0200619fa97f9fde1a319f25c76
Signed-off-by: Andrew Dunham <andrew@du.nham.ca>
The io/ioutil package has been deprecated as of Go 1.16 [1]. This commit
replaces the existing io/ioutil functions with their new definitions in
io and os packages.
Reference: https://golang.org/doc/go1.16#ioutil
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
This lets the control plane can make HTTP requests to nodes.
Then we can use this for future things rather than slapping more stuff
into MapResponse, etc.
Change-Id: Ic802078c50d33653ae1f79d1e5257e7ade4408fd
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The hujson package transition to just being a pure AST
parser and formatter for HuJSON and not an unmarshaler.
Thus, parse HuJSON as such, convert it to JSON,
and then use the standard JSON unmarshaler.
Signed-off-by: Joe Tsai <joetsai@digital-static.net>
Once a stop request is received and the service updates its status to `svc.StopPending`,
it should continue running *until the shutdown sequence is complete*, and then
return out of `(*ipnService).Execute`, which automatically sends a `svc.Stopped`
notification to Windows.
To make this happen, I changed the loop so that it runs until `doneCh` is
closed, and then returns. I also removed a spurious `svc.StopPending` notification
that the Windows Service Control Manager might be interpreting as a request for
more time to shut down.
Finally, I added some optional logging that sends a record of service notifications
to the Windows event log, allowing us to more easily correlate with any Service
Control Manager errors that are sent to the same log.
Change-Id: I5b596122e5e89c4c655fe747a612a52cb4e8f1e0
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Remove the weird netstack -> tailssh dependency and instead have tailssh
register itself with ipnlocal when linked.
This makes tailssh.server a singleton, so we can have a global map of
all sessions.
Updates #3802
Change-Id: Iad5caec3a26a33011796878ab66b8e7b49339f29
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates #4377
Very smoky/high-level test to ensure that derphttp internals play well
with an agressive (stare + bump) meddler-in-the-middle proxy.
Signed-off-by: Tom DNetto <tom@tailscale.com>
I would like to do some more customized integration tests in the future,
(specifically, bringing up a mitm proxy and testing tailscaled through that)
so hoping to bring back the nixos wiring to support that.
Signed-off-by: Tom DNetto <tom@tailscale.com>
And add a CapabilityVersion type, primarily for documentation.
This makes MapRequest.Version, RegisterRequest.Version, and
SetDNSRequest.Version all use the same version, which will avoid
confusing in the future if Register or SetDNS ever changed their
semantics on Version change. (Currently they're both always 1)
This will requre a control server change to allow a
SetDNSRequest.Version value other than 1 to be deployed first.
Change-Id: I073042a216e0d745f52ee2dbc45cf336b9f84b7c
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Also move KubeStore and MemStore into their own package.
RELNOTE: tsnet now supports providing a custom ipn.StateStore.
Signed-off-by: Maisem Ali <maisem@tailscale.com>
For ssh and maybe windows service babysitter later.
Updates #3802
Change-Id: I7492b98df98971b3fb72d148ba92c2276cca491f
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Otherwise omitempty doesn't work.
This is wire-compatible with a non-pointer type, so switching
is safe, now and in the future.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
And log it when provided in map responses.
The test uses the date on which I joined Tailscale. :)
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Also fix a somewhat related printing bug in the process where
some paths would print "Success." inconsistently even
when there otherwise was no output (in the EditPrefs path)
Fixes#3830
Updates #3702 (which broke it once while trying to fix it)
Change-Id: Ic51e14526ad75be61ba00084670aa6a98221daa5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
A new package can also later record/report which knobs are checked and
set. It also makes the code cleaner & easier to grep for env knobs.
Change-Id: Id8a123ab7539f1fadbd27e0cbeac79c2e4f09751
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
testNodes have a reference to a testing.TB via their env.
Use it instead of making the caller pass theirs.
We did this in some methods but not others; finish the job.
This simplifies the call sites.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
magicsock was hanging onto its netmap on logout,
which caused tailscale status to display partial
information about a bunch of zombie peers.
After logout, there should be no peers.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
If you're using -verbose-tailscaled, you're doing in-the-weeds debugging,
so you probably want the verbose output.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
The existing code relied on the Go build cache to avoid
needless work when obtaining the tailscale binaries.
For non-obvious reasons, the binaries were getting re-linked
every time, which added 600ms or so on my machine to every test.
Instead, build the binaries exactly once, on demand.
This reduces the time to run 'go test -count=5' from 34s to 10s
on my machine.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
fee2d9fad added support for cmd/tailscale to connect to IPNExtension.
It came in two parts: If no socket was provided, dial IPNExtension first,
and also, if dialing the socket failed, fall back to IPNExtension.
The second half of that support caused the integration tests to fail
when run on a machine that was also running IPNExtension.
The integration tests want to wait until the tailscaled instances
that they spun up are listening. They do that by dialing the new
instance. But when that dial failed, it was falling back to IPNExtension,
so it appeared (incorrectly) that tailscaled was running.
Hilarity predictably ensued.
If a user (or a test) explicitly provides a socket to dial,
it is a reasonable assumption that they have a specific tailscaled
in mind and don't want to fall back to IPNExtension.
It is certainly true of the integration tests.
Instead of adding a bool to Connect, split out the notion of a
connection strategy. For now, the implementation remains the same,
but with the details hidden a bit. Later, we can improve that.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Not done yet, but this move more of the outbound dial special casing
from random packages into tsdial, which aspires to be the one unified
place for all outbound dialing shenanigans.
Then this plumbs it all around, so everybody is ultimately
holding on to the same dialer.
As of this commit, macOS/iOS using an exit node should be able to
reach to the exit node's DoH DNS proxy over peerapi, doing the sockopt
to stay within the Network Extension.
A number of steps remain, including but limited to:
* move a bunch more random dialing stuff
* make netstack-mode tailscaled be able to use exit node's DNS proxy,
teaching tsdial's resolver to use it when an exit node is in use.
Updates #1713
Change-Id: I1e8ee378f125421c2b816f47bc2c6d913ddcd2f5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For now this just deletes the net/socks5/tssocks implementation (and
the DNSMap stuff from wgengine/netstack) and moves it into net/tsdial.
Then initialize a Dialer early in tailscaled, currently only use for the
outbound and SOCKS5 proxies. It will be plumbed more later. Notably, it
needs to get down into the DNS forwarder for exit node DNS forwading
in netstack mode. But it will also absorb all the peerapi setsockopt
and netns Dial and tlsdial complexity too.
Updates #1713
Change-Id: Ibc6d56ae21a22655b2fa1002d8fc3f2b2ae8b6df
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And annotate magicsock as a start.
And add localapi and debug handlers with the Prometheus-format
exporter.
Updates #3307
Change-Id: I47c5d535fe54424741df143d052760387248f8d3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
github.com/go-multierror/multierror served us well.
But we need a few feature from it (implement Is),
and it's not worth maintaining a fork of such a small module.
Instead, I did a clean room implementation inspired by its API.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
For the service, all we need to do is handle the `svc.SessionChange` command.
Upon receipt of a `windows.WTS_SESSION_UNLOCK` event, we fire off a goroutine to flush the DNS cache.
(Windows expects responses to service requests to be quick, so we don't want to do that synchronously.)
This is gated on an integral registry value named `FlushDNSOnSessionUnlock`,
whose value we obtain during service initialization.
(See [this link](https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nc-winsvc-lphandler_function_ex) for information re: handling `SERVICE_CONTROL_SESSIONCHANGE`.)
Fixes#2956
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This adds support for tailscaled to be an HTTP proxy server.
It shares the same backend dialing code as the SOCK5 server, but the
client protocol is HTTP (including CONNECT), rather than SOCKS.
Fixes#2289
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
* Revert "Revert "types/key: add MachinePrivate and MachinePublic.""
This reverts commit 61c3b98a24.
Signed-off-by: David Anderson <danderson@tailscale.com>
* types/key: add ControlPrivate, with custom serialization.
ControlPrivate is just a MachinePrivate that serializes differently
in JSON, to be compatible with how the Tailscale control plane
historically serialized its private key.
Signed-off-by: David Anderson <danderson@tailscale.com>
Plumb throughout the codebase as a replacement for the mixed use of
tailcfg.MachineKey and wgkey.Private/Public.
Signed-off-by: David Anderson <danderson@tailscale.com>
I have seen this once in the VM test (caused by an EOF, I believe on
shutdown) that didn't need to cause the test to fail.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
The tests build fine on other Unix's, they just can't run there.
But there is already a t.Skip by default, so `go test` ends up
working fine elsewhere and checks the code compiles.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This uses a neat little tool to dump the output of DNS queries to
standard out. This is the first end-to-end test of DNS that runs against
actual linux systems. The /etc/resolv.conf test may look superflous,
however this will help for correlating system state if one of the DNS
tests fails.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Fix a few test printing issues when tests fail.
Qemu console output is super useful when something is wrong in the
harness and we cannot even bring up the tests.
Also useful for figuring out where all the time goes in tests.
A little noisy, but not too noisy as long as you're only running one VM
as part of the tests, which is my plan.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
Also remove extra distros for now.
We can bring them back later if useful.
Though our most important distros are these two Ubuntu, debian stable,
and Raspbian (not currently supported).
And before doing more Linux, we should do Windows.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
The VM test has two tailscaled instances running and interleaves the
logs. Without a prefix it is impossible to figure out what is going on.
It might be even better to include the [ABCD] node prefix here as well.
Unfortunately lots of interesting logs happen before tailscaled has a
node key, so it wouldn't be a replacement for a short ID.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
By default httptest listens only on the loopback adapter.
Instead, listen on the IP the user asked for.
The VM test needs this, as it wants to start DERP and STUN
servers on the host that can be reached by guest VMs.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This is useful for manual performance testing
of networks with many nodes.
I imagine it'll grow more knobs over time.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This prevents centos tests from timing out because sshd does reverse dns
lookups on every session being established instead of doing it once on
the acutal ssh connection being established. This is odd. Appending this
to the sshd config and restarting it seems to fix it though.
Signed-off-by: Christine Dodrill <xe@tailscale.com>