This lets us distinguish "no IPv6 because the device's ISP doesn't
offer IPv6" from "IPv6 is unavailable/disabled in the OS".
Signed-off-by: David Anderson <danderson@tailscale.com>
Together with 06aa141632 this minimizes
the number of NEPacketTunnelNetworkSettings updates that we have to do,
and thus avoids Chrome interrupting outstanding requests due to
(perceived) network changes.
Updates #3102
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
And remove the GCP special-casing from ipn/ipnlocal; do it only in the
forwarder for *.internal.
Fixes#4980Fixes#4981
Change-Id: I5c481e96d91f3d51d274a80fbd37c38f16dfa5cb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This does three things:
* If you're on GCP, it adds a *.internal DNS split route to the
metadata server, so we never break GCP DNS names. This lets people
have some Tailscale nodes on GCP and some not (e.g. laptops at home)
without having to add a Tailnet-wide *.internal DNS route.
If you already have such a route, though, it won't overwrite it.
* If the 100.100.100.100 DNS forwarder has nowhere to forward to,
it forwards it to the GCP metadata IP, which forwards to 8.8.8.8.
This means there are never errNoUpstreams ("upstream nameservers not set")
errors on GCP due to e.g. mangled /etc/resolv.conf (GCP default VMs
don't have systemd-resolved, so it's likely a DNS supremacy fight)
* makes the DNS fallback mechanism use the GCP metadata IP as a
fallback before our hosted HTTP-based fallbacks
I created a default GCP VM from their web wizard. It has no
systemd-resolved.
I then made its /etc/resolv.conf be empty and deleted its GCP
hostnames in /etc/hosts.
I then logged in to a tailnet with no global DNS settings.
With this, tailscaled writes /etc/resolv.conf (direct mode, as no
systemd-resolved) and sets it to 100.100.100.100, which then has
regular DNS via the metadata IP and *.internal DNS via the metadata IP
as well. If the tailnet configures explicit DNS servers, those are used
instead, except for *.internal.
This also adds a new util/cloudenv package based on version/distro
where the cloud type is only detected once. We'll likely expand it in
the future for other clouds, doing variants of this change for other
popular cloud environments.
Fixes#4911
RELNOTES=Google Cloud DNS improvements
Change-Id: I19f3c2075983669b2b2c0f29a548da8de373c7cf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
There appear to be devices out there which send only their
first descriptor in response to a discovery packet for
`ssdp:all`, for example the Sagemcom FAST3890V3 only sends
urn:schemas-wifialliance-org:device:WFADevice:1
Send both ssdp:all and a discovery frame for
InternetGatewayDevice specifically.
Updates https://github.com/tailscale/tailscale/issues/3557
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
When there are group policy entries for the NRPT that do not belong to Tailscale,
we recognize that we need to add ourselves to group policy and use that registry
key instead of the local one. We also refresh the group policy settings as
necessary to ensure that our changes take effect immediately.
Fixes https://github.com/tailscale/tailscale/issues/4607
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Start up a backend service, put a SOCKS5 server in front
of it, and verify that we can get data from the backend via
SOCKS5.
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
In the 1.27 unstable releases we set the min-version to iOS15,
which means we have 50 MBytes of RAM in the Network Extension.
https://tailscale.com/blog/go-linker/
Include the UPnP/NAT-PMP/PCP portmapper support now that there
is memory for it.
Fixes https://github.com/tailscale/tailscale/issues/2495
Signed-off-by: Denton Gentry <dgentry@tailscale.com>
We can't do Noise-over-HTTP in Wasm/JS (because we don't have bidirectional
communication), but we should be able to do it over WebSockets. Reuses
derp WebSocket support that allows us to turn a WebSocket connection
into a net.Conn.
Updates #3157
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
Currently we only support "via-<site-id>.<IPv4>", however that does not
work with Google Chrome which parses `http://via-1.10.0.0.1` as a search
string and not as a URL. This commit introduces "<IPv4>.via-<site-id>"
(`http://10.0.0.1.via-1`) which is parsed correctly by Chrome.
Updates #3616
Signed-off-by: Maisem Ali <maisem@tailscale.com>
AFAICT this isn't documented on MSDN, but based on the issue referenced below,
NRPT rules are not working when a rule specifies > 50 domains.
This patch modifies our NRPT rule generator to split the list of domains
into chunks as necessary, and write a separate rule for each chunk.
For compatibility reasons, we continue to use the hard-coded rule ID, but
as additional rules are required, we generate new GUIDs. Those GUIDs are
stored under the Tailscale registry path so that we know which rules are ours.
I made some changes to winutils to add additional helper functions in support
of both the code and its test: I added additional registry accessors, and also
moved some token accessors from paths to util/winutil.
Fixes https://github.com/tailscale/coral/issues/63
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
Fixes https://github.com/tailscale/corp/issues/5198
The upstream forwarder will block indefinitely on `udpconn.ReadFrom` if no
reply is recieved, due to the lack of deadline on the connection object.
There still isn't a deadline on the connection object, but the automatic closing
of the context on deadline expiry will close the connection via `closeOnCtxDone`,
unblocking the read and resulting in a normal teardown.
Signed-off-by: Tom DNetto <tom@tailscale.com>
We were marking them as gauges, but they are only ever incremented,
thus counter is more appropriate.
Signed-off-by: Mihai Parparita <mihai@tailscale.com>
* net/dns, wgengine: implement DNS over TCP
Signed-off-by: Tom DNetto <tom@tailscale.com>
* wgengine/netstack: intercept only relevant port/protocols to quad-100
Signed-off-by: Tom DNetto <tom@tailscale.com>
This were intended to be pushed to #4408, but in my excitement I
forgot to git push :/ better late than never.
Signed-off-by: Tom DNetto <tom@tailscale.com>
This change wires netstack with a hook for traffic coming from the host
into the tun, allowing interception and handling of traffic to quad-100.
With this hook wired, magicDNS queries over UDP are now handled within
netstack. The existing logic in wgengine to handle magicDNS remains for now,
but its hook operates after the netstack hook so the netstack implementation
takes precedence. This is done in case we need to support platforms with
netstack longer than expected.
Signed-off-by: Tom DNetto <tom@tailscale.com>
A subsequent commit implements handling of magicDNS traffic via netstack.
Implementing this requires a hook for traffic originating from the host and
hitting the tun, so we make another hook to support this.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Moves magicDNS-specific handling out of Resolver & into dns.Manager. This
greatly simplifies the Resolver to solely issuing queries and returning
responses, without channels.
Enforcement of max number of in-flight magicDNS queries, assembly of
synthetic UDP datagrams, and integration with wgengine for
recieving/responding to magicDNS traffic is now entirely in Manager.
This path is being kept around, but ultimately aims to be deleted and
replaced with a netstack-based path.
This commit is part of a series to implement magicDNS using netstack.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Well, goimports actually (which adds the normal import grouping order we do)
Change-Id: I0ce1b1c03185f3741aad67c14a7ec91a838de389
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This updates the fix from #4562 to pick the proxy based on the request
scheme.
Updates #4395, #2605, #4562
Signed-off-by: James Tucker <james@tailscale.com>
Currently we try to use `https://` when we see `https_host`, however
that doesn't work and results in errors like `Received error: fetch
control key: Get "https://controlplane.tailscale.com/key?v=32":
proxyconnect tcp: tls: first record does not look like a TLS handshake`
This indiciates that we are trying to do a HTTPS request to a HTTP
server. Googling suggests that the standard is to use `http` regardless
of `https` or `http` proxy
Updates #4395, #2605
Signed-off-by: Maisem Ali <maisem@tailscale.com>
The connections returned from SystemDial are automatically closed when
there is a major link change.
Also plumb through the dialer to the noise client so that connections
are auto-reset when moving from cellular to WiFi etc.
Updates #3363
Signed-off-by: Maisem Ali <maisem@tailscale.com>
Updates #2067
This should help us determine if more robust control of edns parameters
+ implementing answer truncation is warranted, given its likely complexity.
Signed-off-by: Tom DNetto <tom@tailscale.com>
This populates DNS suffixes ("ts.net", etc) in /etc/resolver/* files
to point to 100.100.100.100 so MagicDNS works.
It also sets search domains.
Updates #4276
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
$ tailscale debug via 0xb 10.2.0.0/16
fd7a:115c:a1e0:b1a:0🅱️a02:0/112
$ tailscale debug via fd7a:115c:a1e0:b1a:0🅱️a02:0/112
site 11 (0xb), 10.2.0.0/16
Previously: 3ae701f0eb
This adds a little debug tool to do CIDR math to make converting between
those ranges easier for now.
Updates #3616
Change-Id: I98302e95d17765bfaced3ecbb71cbd43e84bff46
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
In cases where tailscale is operating behind a MITM proxy, we need to consider
that a lot more of the internals of our HTTP requests are visible and may be
used as part of authorization checks. As such, we need to 'behave' as closely
as possible to ideal.
- Some proxies do authorization or consistency checks based the on Host header
or HTTP URI, instead of just the IP/hostname/SNI. As such, we need to
construct a `*http.Request` with a valid URI everytime HTTP is going to be
used on the wire, even if its over TLS.
Aside from the singular instance in net/netcheck, I couldn't find anywhere
else a http.Request was constructed incorrectly.
- Some proxies may deny requests, typically by returning a 403 status code. We
should not consider these requests as a valid latency check, so netcheck
semantics have been updated to consider >299 status codes as a failed probe.
Signed-off-by: Tom DNetto <tom@tailscale.com>
Two changes in one:
* make DoH upgrades an explicitly scheduled send earlier, when we come
up with the resolvers-and-delay send plan. Previously we were
getting e.g. four Google DNS IPs and then spreading them out in
time (for back when we only did UDP) but then later we added DoH
upgrading at the UDP packet layer, which resulted in sometimes
multiple DoH queries to the same provider running (each doing happy
eyeballs dialing to 4x IPs themselves) for each of the 4 source IPs.
Instead, take those 4 Google/Cloudflare IPs and schedule 5 things:
first the DoH query (which can use all 4 IPs), and then each of the
4 IPs as UDP later.
* clean up the dnstype.Resolver.Addr confusion; half the code was
using it as an IP string (as documented) as half was using it as
an IP:port (from some prior type we used), primarily for tests.
Instead, document it was being primarily an IP string but also
accepting an IP:port for tests, then add an accessor method on it
to get the IPPort and use that consistently everywhere.
Change-Id: Ifdd72b9e45433a5b9c029194d50db2b9f9217b53
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
If all N queries failed, we waited until context timeout (in 5
seconds) to return.
This makes (*forwarder).forward fail fast when the network's
unavailable.
Change-Id: Ibbb3efea7ed34acd3f3b29b5fee00ba8c7492569
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Simplify the ability to reason about the DoH dialing code by reusing the
dnscache's dialer we already have.
Also, reduce the scope of the "ip" variable we don't want to close over.
This necessarily adds a new field to dnscache.Resolver:
SingleHostStaticResult, for when the caller already knows the IPs to be
returned.
Change-Id: I9f2aef7926f649137a5a3e63eebad6a3fffa48c0
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>