tinyrelaycommit

Commit 249961ba1458

browse files at this commit | history

1diff --git a/internal/daemon/http.go b/internal/daemon/http.go
2index 0d4f7cb..7b6422d 100644
3--- a/internal/daemon/http.go
4+++ b/internal/daemon/http.go
5@@ -32,6 +32,13 @@ func (t *Tenant) ServeHTTP(w http.ResponseWriter, r *http.Request) {
6 t.healthHTTP(w, r)
7 return
8 }
9+ if t.unclaimedSiteHost(r.Host) {
10+ // A host under the site domain that no site claims must not fall
11+ // through to the relay: signed requests would otherwise verify
12+ // against a URL the relay does not own.
13+ http.NotFound(w, r)
14+ return
15+ }
16 if strings.EqualFold(r.Header.Get("Upgrade"), "websocket") {
17 t.router.HandleHTTP(w, r)
18 return
19@@ -553,3 +560,22 @@ func containsString(values []string, wanted string) bool {
20 }
21 return false
22 }
23+
24+// unclaimedSiteHost reports whether host is a subdomain of the site domain
25+// that neither a hosted site nor a custom host claims.
26+func (t *Tenant) unclaimedSiteHost(host string) bool {
27+ host = strings.ToLower(strings.Split(host, ":")[0])
28+ domain := strings.ToLower(t.siteDomain())
29+ if domain == "" || host == domain || !strings.HasSuffix(host, "."+domain) {
30+ return false
31+ }
32+ if t.sites != nil && t.sites.MatchesHost(host) {
33+ return false
34+ }
35+ for _, custom := range t.Policy().CustomHosts {
36+ if strings.EqualFold(custom.Host, host) {
37+ return false
38+ }
39+ }
40+ return true
41+}
42diff --git a/internal/daemon/site_host_test.go b/internal/daemon/site_host_test.go
43new file mode 100644
44index 0000000..68d5fcd
45--- /dev/null
46+++ b/internal/daemon/site_host_test.go
47@@ -0,0 +1,35 @@
48+package daemon
49+
50+import (
51+ "context"
52+ "net/http"
53+ "net/http/httptest"
54+ "strings"
55+ "testing"
56+)
57+
58+func TestUnclaimedSubdomainsOfTheSiteDomainAreNotFound(t *testing.T) {
59+ ctx := context.Background()
60+ app, err := New(ctx, Config{DataDir: t.TempDir(), DefaultTenant: "main", PublicURL: "https://relay.test"})
61+ if err != nil {
62+ t.Fatal(err)
63+ }
64+ defer app.Close(ctx)
65+ meta, err := app.Create(ctx, CreateOptions{Name: "main", Owner: strings.Repeat("a", 64), Template: "default"})
66+ if err != nil {
67+ t.Fatal(err)
68+ }
69+ tenant, err := app.tenant(ctx, meta, "https://relay.test")
70+ if err != nil {
71+ t.Fatal(err)
72+ }
73+ for host, want := range map[string]int{"relay.test": http.StatusOK, "bauhaus.relay.test": http.StatusNotFound, "tiny.tailnet.example": http.StatusOK, "127.0.0.1:7447": http.StatusOK} {
74+ req := httptest.NewRequest(http.MethodGet, "http://"+host+"/", nil)
75+ req.Host = host
76+ res := httptest.NewRecorder()
77+ tenant.ServeHTTP(res, req)
78+ if res.Code != want {
79+ t.Errorf("host %s: status %d, want %d", host, res.Code, want)
80+ }
81+ }
82+}

About

ownerc01503e8035f
visibilitypublic
head249961ba1458

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs