From da2112e88e3144c2934f611774ccd76f4b9eefe9 Mon Sep 17 00:00:00 2001 From: Colin Adler Date: Thu, 16 Nov 2023 19:45:24 +0000 Subject: [PATCH] fix: ignore https redirect for DERP meshing --- cli/cliutil/sink_test.go | 4 ++-- cli/server.go | 11 +++++++++-- coderd/coderd.go | 7 ++++--- enterprise/cli/server.go | 3 +++ enterprise/coderd/coderd.go | 5 ++--- enterprise/replicasync/replicasync.go | 5 +++-- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/cli/cliutil/sink_test.go b/cli/cliutil/sink_test.go index 49b8b5cbe9636..ab916dcb4580f 100644 --- a/cli/cliutil/sink_test.go +++ b/cli/cliutil/sink_test.go @@ -1,17 +1,17 @@ package cliutil_test import ( - "errors" "testing" "github.com/stretchr/testify/require" + "golang.org/x/xerrors" "github.com/coder/coder/v2/cli/cliutil" ) func TestDiscardAfterClose(t *testing.T) { t.Parallel() - exErr := errors.New("test") + exErr := xerrors.New("test") fwc := &fakeWriteCloser{err: exErr} uut := cliutil.DiscardAfterClose(fwc) diff --git a/cli/server.go b/cli/server.go index ab2f7bb01e892..4288fc6b18fbb 100644 --- a/cli/server.go +++ b/cli/server.go @@ -897,7 +897,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd. // the request is not to a local IP. var handler http.Handler = coderAPI.RootHandler if vals.RedirectToAccessURL { - handler = redirectToAccessURL(handler, vals.AccessURL.Value(), tunnel != nil, appHostnameRegex) + handler = redirectToAccessURL(handler, vals.AccessURL.Value(), tunnel != nil, appHostnameRegex, options.IgnoreRedirectHostnames...) } // ReadHeaderTimeout is purposefully not enabled. It caused some @@ -1916,7 +1916,7 @@ func ConfigureHTTPClient(ctx context.Context, clientCertFile, clientKeyFile stri } // nolint:revive -func redirectToAccessURL(handler http.Handler, accessURL *url.URL, tunnel bool, appHostnameRegex *regexp.Regexp) http.Handler { +func redirectToAccessURL(handler http.Handler, accessURL *url.URL, tunnel bool, appHostnameRegex *regexp.Regexp, ignoreHosts ...string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { redirect := func() { http.Redirect(w, r, accessURL.String(), http.StatusTemporaryRedirect) @@ -1945,6 +1945,13 @@ func redirectToAccessURL(handler http.Handler, accessURL *url.URL, tunnel bool, return } + for _, ignore := range ignoreHosts { + if r.Host == ignore { + handler.ServeHTTP(w, r) + return + } + } + redirect() }) } diff --git a/coderd/coderd.go b/coderd/coderd.go index 8b54b708cc85d..421f0532f8c80 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -120,9 +120,10 @@ type Options struct { RealIPConfig *httpmw.RealIPConfig TrialGenerator func(ctx context.Context, email string) error // TLSCertificates is used to mesh DERP servers securely. - TLSCertificates []tls.Certificate - TailnetCoordinator tailnet.Coordinator - DERPServer *derp.Server + TLSCertificates []tls.Certificate + TailnetCoordinator tailnet.Coordinator + IgnoreRedirectHostnames []string + DERPServer *derp.Server // BaseDERPMap is used as the base DERP map for all clients and agents. // Proxies are added to this list. BaseDERPMap *tailcfg.DERPMap diff --git a/enterprise/cli/server.go b/enterprise/cli/server.go index 7fb1526c50197..3da61e3d61ca2 100644 --- a/enterprise/cli/server.go +++ b/enterprise/cli/server.go @@ -75,6 +75,9 @@ func (r *RootCmd) Server(_ func()) *clibase.Cmd { CheckInactiveUsersCancelFunc: dormancy.CheckInactiveUsers(ctx, options.Logger, options.Database), } + if o.DERPServerRelayAddress != "" { + o.Options.IgnoreRedirectHostnames = append(o.Options.IgnoreRedirectHostnames, o.DERPServerRelayAddress) + } if encKeys := options.DeploymentValues.ExternalTokenEncryptionKeys.Value(); len(encKeys) != 0 { keys := make([][]byte, 0, len(encKeys)) diff --git a/enterprise/coderd/coderd.go b/enterprise/coderd/coderd.go index 55defaf9b964d..f0729c726f8e9 100644 --- a/enterprise/coderd/coderd.go +++ b/enterprise/coderd/coderd.go @@ -14,12 +14,11 @@ import ( "sync" "time" - "golang.org/x/xerrors" - "tailscale.com/tailcfg" - "github.com/cenkalti/backoff/v4" "github.com/go-chi/chi/v5" "github.com/prometheus/client_golang/prometheus" + "golang.org/x/xerrors" + "tailscale.com/tailcfg" "cdr.dev/slog" "github.com/coder/coder/v2/coderd" diff --git a/enterprise/replicasync/replicasync.go b/enterprise/replicasync/replicasync.go index 1d6cd349b376d..77fadaee1f58e 100644 --- a/enterprise/replicasync/replicasync.go +++ b/enterprise/replicasync/replicasync.go @@ -36,8 +36,9 @@ type Options struct { TLSConfig *tls.Config } -// New registers the replica with the database and periodically updates to ensure -// it's healthy. It contacts all other alive replicas to ensure they are reachable. +// New registers the replica with the database and periodically updates to +// ensure it's healthy. It contacts all other alive replicas to ensure they are +// reachable. func New(ctx context.Context, logger slog.Logger, db database.Store, ps pubsub.Pubsub, options *Options) (*Manager, error) { if options == nil { options = &Options{}