Commit Graph

104 Commits (a661287c4bc61d4b0a0b26a32498bddb75fe1f74)

Author SHA1 Message Date
Marwan Sulaiman b819f66eb1 tsweb: propagate RequestID via context and entire request
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>
12 months ago
Maisem Ali 5ee349e075 tsweb/varz: fix exporting histograms
Updates tailscale/corp#8641

Signed-off-by: Maisem Ali <maisem@tailscale.com>
1 year ago
Dave Anderson 7b18ed293b
tsweb: check for key-based debug access before XFF check (#9093)
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>
1 year ago
David Anderson 5cfa85e604 tsweb: clean up pprof handler registration, document why it's there
Updates #cleanup

Signed-off-by: David Anderson <danderson@tailscale.com>
1 year ago
Adrian Dewhurst f75a36f9bc tsweb: add request ID for errors
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>
1 year ago
Andrew Lytvynov 7c04846eac
tsweb: relax CSP for debug handlers (#8649)
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>
1 year ago
Maisem Ali 3304819739 metrics: add histogram support
Add initial histogram support.

Updates tailscale/corp#8641

Signed-off-by: Maisem Ali <maisem@tailscale.com>
1 year ago
Andrew Lytvynov 96d7af3469
cmd/derper,tsweb: consistently add HTTP security headers (#8579)
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>
1 year ago
Adrian Dewhurst cd4c71c122 tstest: prepare for Clock API changes
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>
1 year ago
Brad Fitzpatrick 79ee6d6e1e tsweb/varz: use default metrics.LabelMap.Label on serialization
To not break Prometheus if the label is unset.

Updates tailscale/corp#12830

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
Brad Fitzpatrick eefee6f149 all: use cmpx.Or where it made sense
I left a few out where writing it explicitly was better
for various reasons.

Updates #8296

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
1 year ago
James Tucker 5c38f0979e tsweb/promvarz: fix repeated expvar definition in test
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>
2 years ago
Anton Tolchanov 8546ff98fb tsweb: move varz handler(s) into separate modules
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>
2 years ago
Anton Tolchanov c153e6ae2f prober: migrate to Prometheus metric library
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>
2 years ago
Anton Tolchanov 11e6247d2a tsweb: expose native Prometheus metrics in /debug/varz
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>
2 years ago
Maisem Ali 1a30b2d73f all: use tstest.Replace more
Signed-off-by: Maisem Ali <maisem@tailscale.com>
2 years ago
David Anderson 8b2ae47c31 version: unexport all vars, turn Short/Long into funcs
The other formerly exported values aren't used outside the package,
so just unexport them.

Signed-off-by: David Anderson <danderson@tailscale.com>
2 years ago
Brad Fitzpatrick b1248442c3 all: update to Go 1.20, use strings.CutPrefix/Suffix instead of our fork
Updates #7123
Updates #5309

Change-Id: I90bcd87a2fb85a91834a0dd4be6e03db08438672
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Will Norris 10085063fb util/vizerror: add As function to get wrapped Error
Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Will Norris 51e1ab5560 fixup! util/vizerror: add new package for visible errors
Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Will Norris 648aa00a28 fixup! util/vizerror: add new package for visible errors
Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Will Norris 598ec463bc fixup! util/vizerror: add new package for visible errors
Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Will Norris 71029cea2d all: update copyright and license headers
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>
2 years ago
Anton Tolchanov f053f16460 tsweb: export version metrics to Prometheus
This will allow tracking build versions and runtime versions in
Prometheus.

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2 years ago
Mihai Parparita 33520920c3 all: use strs.CutPrefix and strs.CutSuffix more
Updates places where we use HasPrefix + TrimPrefix to use the combined
function.

Updates #5309

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Anton Tolchanov f40bb199f5 tsweb: cache prometheus metric names & types
Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2 years ago
Anton Tolchanov 3c27632ffe tsweb: avoid dashes in Prometheus metric names
Ideally we should strip other invalid characters too, but that would
call for a regexp replacement which increases the number of allocations
and makes `TestVarzHandlerSorting` fail.

Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2 years ago
Brad Fitzpatrick 614a24763b tsweb: sort top-level expvars after removing type prefixes
Fixes #5778

Change-Id: I56c367338fa5686da288cc6545209ef4d6b88549
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 718914b697 tsweb: remove allocs introduced by earlier change
This removes the ~9 allocs added by #5869, while still keeping struct
fields sorted (the previous commit's tests still pass). And add a test
to lock it in that this shouldn't allocate.

Updates #5778

Change-Id: I4c12b9e2a1334adc1ea5aba1777681cb9fc18fbf
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Hasnain Lakhani 8fe04b035c tsweb: sort varz by name after stripping prefix (#5778)
This makes it easier to view prometheus metrics.

Added a test case which demonstrates the new behavior - the test
initially failed as the output was ordered in the same order
as the fields were declared in the struct (i.e. foo_a, bar_a, foo_b,
bar_b). For that reason, I also had to change an existing test case
to sort the fields in the new expected order.

Signed-off-by: Hasnain Lakhani <m.hasnain.lakhani@gmail.com>
2 years ago
Will Norris 62bc1052a2 tsweb: allow HTTPError to unwrap errors
Signed-off-by: Will Norris <will@tailscale.com>
2 years ago
Josh Soref d4811f11a0 all: fix spelling mistakes
Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
2 years ago
Mihai Parparita c66e15772f tsweb: consider 304s as successful for quiet logging
Static resource handlers will generate lots of 304s, which are
effectively successful responses.

Signed-off-by: Mihai Parparita <mihai@tailscale.com>
2 years ago
Brad Fitzpatrick aa5e494aba tsweb: export go_version in standard expvar vars
For monitoring.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Eng Zer Jun f0347e841f refactor: move from io/ioutil to io and os packages
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>
2 years ago
Brad Fitzpatrick 116f55ff66 all: gofmt for Go 1.19
Updates #5210

Change-Id: Ib02cd5e43d0a8db60c1f09755a8ac7b140b670be
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Joe Tsai 57275a4912
tsweb: add HTTPError.Header (#5251)
The Header field allows the server to specify specific headers to set.
Example use case: server returns 429 with the "Retry-After" header set.

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2 years ago
Joe Tsai a794963e2f
tsweb: mark AccessLogRecord fields as omitempty (#5250)
If the field is the zero value, then avoid serializing the field.
This reduces verbosity in server logs.

Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2 years ago
Brad Fitzpatrick 6a396731eb all: use various net/netip parse funcs directly
Mechanical change with perl+goimports.

Changed {Must,}Parse{IP,IPPrefix,IPPort} to their netip variants, then
goimports -d .

Finally, removed the net/netaddr wrappers, to prevent future use.

Updates #5162

Change-Id: I59c0e38b5fbca5a935d701645789cddf3d7863ad
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Brad Fitzpatrick 7eaf5e509f net/netaddr: start migrating to net/netip via new netaddr adapter package
Updates #5162

Change-Id: Id7bdec303b25471f69d542f8ce43805328d56c12
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
Denton Gentry 755396d6fe tsweb: add Float expvar support in varz
We make assertions about stringification of 0.5. IEEE floating point and
all reasonable proprietary floating point can exactly represent 0.5.
We don't make assertions about other floating point values, too brittle
in tests.

Signed-off-by: Denton Gentry <dgentry@tailscale.com>
2 years ago
Tom DNetto 32c6823cf5 tsweb: implement interceptor for error page presentation
Updates https://github.com/tailscale/corp/issues/5605

Signed-off-by: Tom DNetto <tom@tailscale.com>
2 years ago
Brad Fitzpatrick 0df3b76c25 tsweb: fix Port80Handler redirect to https with FQDN unset
Fixes the current http://pkgs.tailscale.com/ redirect to https:///
as that server doesn't configure the Port80Handler.FQDN field.

Change-Id: Iff56e6127a46c306ca97738d91b217bcab32a582
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2 years ago
David Anderson e1c1d47991 tsweb: memoize the string forms of HTTP response codes.
Saves 1-2 allocs per HTTP request after warmup, thanks to
avoiding strconv and fmt.

Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
David Anderson c48513b2be tsweb: support recording unabridged HTTP status codes as well.
Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
Brad Fitzpatrick 2d1849a7b9 tsweb: remove JSONHandlerFunc
It's unused and we've decided it's not what we want.

Change-Id: I425a0104e8869630b498a0adfd0f455876d6f92b
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago
David Anderson 7b4960316b tsweb: add PrometheusVar, for vars that want to output varz themselves.
This enables the infrequent use of more complex Prometheus types, such as
timeseries with high/irregular label cardinality, without needing to
discover and implement generic abstracted type like LabelMap for each one.

Signed-off-by: David Anderson <danderson@tailscale.com>
3 years ago
Maisem Ali 309c0a13a5 tsweb: add FQDN to Port80Handler to allow HTTPS redirects
When the request comes in say over http://mon, the current
implementation would rewrite it https://mon which causes the cert
validation to fail. This PR keeps the existing behavior intact but also
allows passing in a FQDN to the handler to reroute to the correct
hostname.

Related to https://github.com/tailscale/tailscale/pull/4208#pullrequestreview-913832340

Signed-off-by: Maisem Ali <maisem@tailscale.com>
3 years ago
Josh Bleecher Snyder 0868329936 all: use any instead of interface{}
My favorite part of generics.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
3 years ago
Brad Fitzpatrick 61ee72940c all: use Go 1.18's strings.Cut
More remain.

Change-Id: I6ec562cc1f687600758deae1c9d7dbd0d04004cb
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
3 years ago